maven+mybatis+mybatis-generator+sql server 2005自动生成代码,加上自定义分页插件和批量插入更新插件
来源:互联网 发布:win10怎么安装php 编辑:程序博客网 时间:2024/05/16 07:03
第一步:准备需要的jar包。由于maven只要配置pom.xml就可以从仓库下载jar包。因此我们首先配置pom.xml。
注意com.microsoft.sqlserver需要自己加入maven仓库的。
<dependencies>......<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.2.3</version></dependency><dependency><groupId>com.microsoft.sqlserver</groupId><artifactId>sqljdbc4</artifactId><version>4.0</version></dependency><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.3.2</version></dependency>......</dependencies><build>......<plugins> ...... <!-- generator插件 --><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.2</version><configuration> <overwrite>true</overwrite> <verbose>true</verbose></configuration><dependencies><dependency><groupId>com.microsoft.sqlserver</groupId><artifactId>sqljdbc4</artifactId><version>4.0</version></dependency><dependency> <groupId>com.montnets.edusun</groupId><artifactId>mybatis-user-defined-plugin</artifactId><version>0.1</version></dependency></dependencies></plugin></plugins></build>
第二步:配置generatorConfig.xml文件。在src/main/resources文件夹下新建generatorConfig.xml文件,配置文件如下代码所示。
<generatorConfiguration><properties resource="datasource.properties" /> <!-- 数据库驱动包位置 配置在pom.xml文件中 --> <context id="MSSQLTables" targetRuntime="MyBatis3"> <plugin type="org.mybatis.generator.plugins.SerializablePlugin"></plugin><!-- <plugin type="org.mybatis.generator.plugins.ToStringPlugin"></plugin> --> <plugin type="com.montnets.mybatis.generator.plugins.InsertAndUpdateBatch"></plugin> <!-- Pagination --> <plugin type="com.montnets.mybatis.generator.plugins.PaginationPlugin"> <property name="pageQualifiedName" value="com.montnets.edusun.common.Page" /><property name="fromIndex" value="fromIndex" /><property name="toIndex" value="toIndex" /><property name="myBatisRepository" value="com.montnets.edusun.common.MyBatisRepository" /> </plugin> <commentGenerator> <!-- 是否去除自动生成的注释 true:是 : false:否 --> <property name="suppressAllComments" value="true" /> </commentGenerator> <!-- 数据库链接URL、用户名、密码 --> <jdbcConnection driverClass="${jdbc.driver}" connectionURL="${jdbc.url}" userId="${jdbc.username}" password="${jdbc.password}"> </jdbcConnection> <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer true,把JDBC DECIMAL 和 NUMERIC 类型解析为java.math.BigDecimal --> <javaTypeResolver> <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!-- 生成模型的包名和位置 --> <javaModelGenerator targetPackage="com.montnets.edusun.entity.test" targetProject="./src/main/java"> <property name="enableSubPackages" value="true" /> <!-- 从数据库返回的值被清理前后的空格 --> <property name="trimStrings" value="true" /> </javaModelGenerator> <!-- 生成的映射文件包名和位置 --> <sqlMapGenerator targetPackage="sqlmaps.test" targetProject="./src/main/resources"> <property name="enableSubPackages" value="true" /> </sqlMapGenerator> <!-- 生成DAO的包名和位置 --> <javaClientGenerator type="XMLMAPPER" targetPackage="com.montnets.edusun.dao.test" targetProject="./src/main/java"> <property name="enableSubPackages" value="true" /> </javaClientGenerator> <!-- 要生成那些表(更改tableName和domainObjectName就可以) --> <table tableName="Edu_Notice" domainObjectName="EduNotice"> <generatedKey column="id" sqlStatement="JDBC" identity="true"/> </table> </context></generatorConfiguration>
对应的datasource.properties如下所示
#sql server database settingsjdbc.driver=com.microsoft.sqlserver.jdbc.SQLServerDriverjdbc.url=jdbc:sqlserver://127.0.0.1:1433;DatabaseName=testjdbc.username=sajdbc.password=******
第三步:运行mybatis-generator。命令:mybatis-generator:generate
详细介绍请参照:点击打开官网链接
-----------------------------------------------------------------------------------------------------------------------
下面介绍一下自定义的两个插件:InsertAndUpdateBatch和PaginationPlugin。这两个插件都被封装在mybatis-user-defined-plugin.jar包中。需要在maven的仓库中注册该jar包,pom.xml和generatorConfig.xml里的配置方式已经在前面有了。
InsertAndUpdateBatch: 配置后在生成代码时,会在接口和sqlmap文件中生成updateBySelectiveBatch、updateBatch、insertBatch三个方法和对应的sql语句。
PaginationPlugin:配置后在生成代码时,会在接口和sqlmap文件中生成countTotalData、pageQuery两个方法和对应的sql语句。需要注意的是该插件的四个参数,前三个参数为必需的,后一个参数为非必需的。
pageQualifiedName——分页类的全路径
fromIndex——分页查询中需要用到的起始索引名称
toIndex——分页查询中需要用到的结束索引名称
myBatisRepository——接口为mybatis提供的扫描注解类的全名。
源代码如下:
import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;import static org.mybatis.generator.internal.util.messages.Messages.getString;import java.util.List;import org.mybatis.generator.api.IntrospectedTable;import org.mybatis.generator.api.PluginAdapter;import org.mybatis.generator.api.dom.java.Field;import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;import org.mybatis.generator.api.dom.java.Interface;import org.mybatis.generator.api.dom.java.JavaVisibility;import org.mybatis.generator.api.dom.java.Method;import org.mybatis.generator.api.dom.java.Parameter;import org.mybatis.generator.api.dom.java.TopLevelClass;import org.mybatis.generator.api.dom.xml.Attribute;import org.mybatis.generator.api.dom.xml.Document;import org.mybatis.generator.api.dom.xml.TextElement;import org.mybatis.generator.api.dom.xml.XmlElement;/** * @author 罗勇 * @date 2013年11月6日 下午2:45:26 */public class PaginationPlugin extends PluginAdapter {private String pageQualifiedName;//分页类的全名private String fromIndex;//Page对象中,查询起始位置的属性名称private String toIndex;//Page对象中,查询结束位置的属性名称private String myBatisRepository;//接口注解全名/** * 验证插件的配置是否正确 */public boolean validate(List<String> warnings) {pageQualifiedName = properties.getProperty("pageQualifiedName");fromIndex = properties.getProperty("fromIndex");toIndex = properties.getProperty("toIndex");myBatisRepository = properties.getProperty("myBatisRepository");if (!stringHasValue(pageQualifiedName)) {warnings.add(getString("ValidationError.18", "PaginationPlugin", "pageQualifiedName"));return false;}if (!stringHasValue(fromIndex)) {warnings.add(getString("ValidationError.18", "PaginationPlugin", "fromIndex"));return false;}if (!stringHasValue(toIndex)) {warnings.add(getString("ValidationError.18", "PaginationPlugin", "toIndex"));return false;}return true;}/** * 在接口中添加方法 */@Overridepublic boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {String objectName = introspectedTable.getTableConfiguration().getDomainObjectName();//对象名称interfaze.addImportedType(new FullyQualifiedJavaType("java.util.List"));interfaze.addImportedType(new FullyQualifiedJavaType(pageQualifiedName));if (stringHasValue(myBatisRepository) && myBatisRepository.contains(".")) {int index = myBatisRepository.lastIndexOf('.');interfaze.addImportedType(new FullyQualifiedJavaType(myBatisRepository));interfaze.addAnnotation("@" + myBatisRepository.substring(index + 1));//接口添加注解}Method method = new Method();//统计记录总条数方法method.setName("countTotalData");method.setReturnType(new FullyQualifiedJavaType("int"));interfaze.addMethod(method);method = new Method();//分页查询方法method.setName("pageQuery");method.addParameter(new Parameter(new FullyQualifiedJavaType(pageQualifiedName), "page"));method.setReturnType(new FullyQualifiedJavaType("java.util.List<" + objectName + ">"));interfaze.addMethod(method);return super.clientGenerated(interfaze, topLevelClass, introspectedTable);}/** * 在xml文件中添加需要的元素 */@Overridepublic boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {XmlElement parentElement = document.getRootElement();String tableName = introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime();//数据库表名// 产生统计记录数查询XmlElement countTotalDataElement = new XmlElement("select");countTotalDataElement.addAttribute(new Attribute("id", "countTotalData"));countTotalDataElement.addAttribute(new Attribute("resultType", "java.lang.Integer"));countTotalDataElement.addElement(new TextElement("select count(1) from " + tableName));parentElement.addElement(countTotalDataElement);// 产生分页查询语句XmlElement pageQueryElement = new XmlElement("select");pageQueryElement.addAttribute(new Attribute("id", "pageQuery"));pageQueryElement.addAttribute(new Attribute("resultMap", "BaseResultMap"));pageQueryElement.addAttribute(new Attribute("parameterType", pageQualifiedName));XmlElement queryStart = new XmlElement("include");queryStart.addAttribute(new Attribute("refid", "PageQueryPrefix"));pageQueryElement.addElement(queryStart);pageQueryElement.addElement(new TextElement("select "));XmlElement query = new XmlElement("include");query.addAttribute(new Attribute("refid", "Base_Column_List"));pageQueryElement.addElement(query);pageQueryElement.addElement(new TextElement("from " + tableName));XmlElement queryEnd = new XmlElement("include");queryEnd.addAttribute(new Attribute("refid", "PageQuerySuffix"));pageQueryElement.addElement(queryEnd);parentElement.addElement(pageQueryElement);// 产生分页语句前半部分XmlElement paginationPrefixElement = new XmlElement("sql");paginationPrefixElement.addAttribute(new Attribute("id", "PageQueryPrefix"));XmlElement pageStart = new XmlElement("if");pageStart.addAttribute(new Attribute("test", "fromIndex != null and toIndex != null"));pageStart.addElement(new TextElement("select * from (select row_number() over (order by id desc) as rownum,* from( "));paginationPrefixElement.addElement(pageStart);parentElement.addElement(paginationPrefixElement);// 产生分页语句后半部分XmlElement paginationSuffixElement = new XmlElement("sql");paginationSuffixElement.addAttribute(new Attribute("id", "PageQuerySuffix"));XmlElement pageEnd = new XmlElement("if");pageEnd.addAttribute(new Attribute("test", "fromIndex != null and toIndex != null"));pageEnd.addElement(new TextElement("<![CDATA[ ) as t1 ) as t2 where rownum <= #{" + toIndex + "} and rownum >= #{" + fromIndex + "} ]]>"));paginationSuffixElement.addElement(pageEnd);parentElement.addElement(paginationSuffixElement);return super.sqlMapDocumentGenerated(document, introspectedTable);}/** * 在Example配置为true时,在Example对象中添加get/set方法 */@Overridepublic boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {String name = "page";topLevelClass.addImportedType(new FullyQualifiedJavaType(pageQualifiedName));Field field = new Field();field.setVisibility(JavaVisibility.PROTECTED);field.setType(new FullyQualifiedJavaType(pageQualifiedName));field.setName(name);topLevelClass.addField(field);char c = name.charAt(0);String camel = Character.toUpperCase(c) + name.substring(1);Method method = new Method();method.setVisibility(JavaVisibility.PUBLIC);method.setName("set" + camel);method.addParameter(new Parameter(new FullyQualifiedJavaType(pageQualifiedName), name));method.addBodyLine("this." + name + "=" + name + ";");topLevelClass.addMethod(method);method = new Method();method.setVisibility(JavaVisibility.PUBLIC);method.setReturnType(new FullyQualifiedJavaType(pageQualifiedName));method.setName("get" + camel);method.addBodyLine("return " + name + ";");topLevelClass.addMethod(method);return super.modelExampleClassGenerated(topLevelClass, introspectedTable);}/** * 在Example配置为true时,对生成的排除了大字段Example查询语句添加分页语句 */@Overridepublic boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {XmlElement pageStart = new XmlElement("include"); pageStart.addAttribute(new Attribute("refid", "PageQueryPrefix"));element.getElements().add(0, pageStart);XmlElement isNotNullElement = new XmlElement("include"); isNotNullElement.addAttribute(new Attribute("refid", "PageQuerySuffix"));element.getElements().add(isNotNullElement);return super.sqlMapUpdateByExampleWithoutBLOBsElementGenerated(element, introspectedTable);}
import java.util.ArrayList;import java.util.Iterator;import java.util.List;import org.mybatis.generator.api.IntrospectedColumn;import org.mybatis.generator.api.IntrospectedTable;import org.mybatis.generator.api.PluginAdapter;import org.mybatis.generator.api.dom.OutputUtilities;import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;import org.mybatis.generator.api.dom.java.Interface;import org.mybatis.generator.api.dom.java.Method;import org.mybatis.generator.api.dom.java.Parameter;import org.mybatis.generator.api.dom.java.TopLevelClass;import org.mybatis.generator.api.dom.xml.Attribute;import org.mybatis.generator.api.dom.xml.Document;import org.mybatis.generator.api.dom.xml.TextElement;import org.mybatis.generator.api.dom.xml.XmlElement;import org.mybatis.generator.codegen.mybatis3.MyBatis3FormattingUtilities;/** * * @author 罗勇 * @date 2013年11月19日 下午3:47:25 */public class InsertAndUpdateBatch extends PluginAdapter {private String item = "item";/** * 验证插件的配置是否正确 */public boolean validate(List<String> warnings) {return true;}/** * 在接口中添加方法 */@Overridepublic boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {String objectName = introspectedTable.getTableConfiguration().getDomainObjectName();//对象名称interfaze.addImportedType(new FullyQualifiedJavaType("java.util.List"));Method method = new Method();//method.addJavaDocLine("/**");method.addJavaDocLine(" * Batch update or insert. Parameters can not be more than 2100");method.addJavaDocLine(" * list of size not greater than 1000");method.addJavaDocLine(" */");method.setName("updateBySelectiveBatch");method.addParameter(new Parameter(new FullyQualifiedJavaType("java.util.List<" + objectName + ">"), "list"));method.setReturnType(new FullyQualifiedJavaType("void"));/*该行代码的作用:当commentGenerator配置为false时,接口可以生成注释代码。 没有意义,所以注释,其他新加的方法已经删除*///context.getCommentGenerator().addGeneralMethodComment(method, introspectedTable);interfaze.addMethod(method);method = new Method();//method.setName("updateBatch");method.addParameter(new Parameter(new FullyQualifiedJavaType("java.util.List<" + objectName + ">"), "list"));method.setReturnType(new FullyQualifiedJavaType("void"));interfaze.addMethod(method);method = new Method();//method.setName("insertBatch");method.addParameter(new Parameter(new FullyQualifiedJavaType("java.util.List<" + objectName + ">"), "list"));method.setReturnType(new FullyQualifiedJavaType("void"));interfaze.addMethod(method);return super.clientGenerated(interfaze, topLevelClass, introspectedTable);}/** * 在xml文件中添加需要的元素 */@Overridepublic boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {XmlElement parentElement = document.getRootElement();String tableName = introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime();//数据库表名parentElement.addElement(getUpdateBatchBySelectiveElement(introspectedTable, tableName));parentElement.addElement(getUpdateBatchElement(introspectedTable, tableName));//批量更新parentElement.addElement(getInsertBatchElement(introspectedTable, tableName));//批量插入return super.sqlMapDocumentGenerated(document, introspectedTable);}/** * 批量修改BySelective * @param introspectedTable * @param tableName * @return */public XmlElement getUpdateBatchBySelectiveElement(IntrospectedTable introspectedTable, String tableName) { XmlElement updateBatchElement = new XmlElement("update"); updateBatchElement.addAttribute(new Attribute("id", "updateBySelectiveBatch")); XmlElement foreachElement = NewForeachElement();XmlElement ifElement = NewIfElement(introspectedTable.getPrimaryKeyColumns());/*该行代码的作用:当commentGenerator配置为false时,sql可以生成注释代码。 没有意义,所以注释,其他新加的方法已经删除*///context.getCommentGenerator().addComment(updateBatchElement); StringBuilder sb = new StringBuilder(); sb.append("update ").append(tableName); ifElement.addElement(new TextElement(sb.toString())); XmlElement dynamicElement = new XmlElement("set"); ifElement.addElement(dynamicElement); for (IntrospectedColumn introspectedColumn : introspectedTable.getNonPrimaryKeyColumns()) { XmlElement isNotNullElement = new XmlElement("if"); isNotNullElement.addAttribute(new Attribute("test", introspectedColumn.getJavaProperty(item + ".") + " != null")); dynamicElement.addElement(isNotNullElement); sb.setLength(0); sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn)); sb.append(" = "); sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, item + ".")); sb.append(','); isNotNullElement.addElement(new TextElement(sb.toString())); } boolean and = false; for (IntrospectedColumn introspectedColumn : introspectedTable.getPrimaryKeyColumns()) { sb.setLength(0); if (and) { sb.append(" and "); } else { sb.append("where "); and = true; } sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn)); sb.append(" = "); sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, item + ".")); ifElement.addElement(new TextElement(sb.toString())); } foreachElement.addElement(ifElement); updateBatchElement.addElement(foreachElement); return updateBatchElement; }/** * 批量修改 * @param introspectedTable * @param tableName * @return */public XmlElement getUpdateBatchElement(IntrospectedTable introspectedTable, String tableName) {XmlElement updateBatchElement = new XmlElement("update"); updateBatchElement.addAttribute(new Attribute("id", "updateBatch")); XmlElement foreachElement = NewForeachElement();XmlElement ifElement = NewIfElement(introspectedTable.getPrimaryKeyColumns()); StringBuilder sb = new StringBuilder(); sb.append("update ").append(tableName); ifElement.addElement(new TextElement(sb.toString())); // set up for first column sb.setLength(0); sb.append("set "); Iterator<IntrospectedColumn> iter = introspectedTable.getNonPrimaryKeyColumns().iterator(); while (iter.hasNext()) { IntrospectedColumn introspectedColumn = iter.next(); sb.append(MyBatis3FormattingUtilities.getAliasedEscapedColumnName(introspectedColumn)); sb.append(" = "); sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, item + ".")); if (iter.hasNext()) { sb.append(','); } ifElement.addElement(new TextElement(sb.toString())); // set up for the next column if (iter.hasNext()) { sb.setLength(0); OutputUtilities.xmlIndent(sb, 1); } } boolean and = false; for (IntrospectedColumn introspectedColumn : introspectedTable.getPrimaryKeyColumns()) { sb.setLength(0); if (and) { sb.append(" and "); } else { sb.append("where "); and = true; } sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn)); sb.append(" = "); sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, item + ".")); ifElement.addElement(new TextElement(sb.toString())); } foreachElement.addElement(ifElement);updateBatchElement.addElement(foreachElement); return updateBatchElement; }/** * 批量添加 * @param introspectedTable * @param tableName * @return */public XmlElement getInsertBatchElement(IntrospectedTable introspectedTable, String tableName) { XmlElement insertBatchElement = new XmlElement("insert"); insertBatchElement.addAttribute(new Attribute("id", "insertBatch")); XmlElement foreachElement = NewForeachElement(); StringBuilder insertClause = new StringBuilder(); StringBuilder valuesClause = new StringBuilder(); insertClause.append("insert into "); insertClause.append(tableName); insertClause.append(" ("); valuesClause.append("values ("); List<String> valuesClauses = new ArrayList<String>(); Iterator<IntrospectedColumn> iter = introspectedTable.getAllColumns().iterator(); while (iter.hasNext()) { IntrospectedColumn introspectedColumn = iter.next(); if (introspectedColumn.isIdentity()) { // cannot set values on identity fields continue; } insertClause.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn)); valuesClause.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, item + ".")); if (iter.hasNext()) { insertClause.append(", "); valuesClause.append(", "); } if (valuesClause.length() > 80) { foreachElement.addElement(new TextElement(insertClause.toString())); insertClause.setLength(0); OutputUtilities.xmlIndent(insertClause, 1); valuesClauses.add(valuesClause.toString()); valuesClause.setLength(0); OutputUtilities.xmlIndent(valuesClause, 1); } } insertClause.append(')'); foreachElement.addElement(new TextElement(insertClause.toString())); valuesClause.append(')'); valuesClauses.add(valuesClause.toString()); for (String clause : valuesClauses) { foreachElement.addElement(new TextElement(clause)); } insertBatchElement.addElement(foreachElement); return insertBatchElement; }/** * @return */public XmlElement NewForeachElement(){XmlElement foreachElement = new XmlElement("foreach");foreachElement.addAttribute(new Attribute("collection", "list"));foreachElement.addAttribute(new Attribute("item", item));foreachElement.addAttribute(new Attribute("index", "index"));foreachElement.addAttribute(new Attribute("separator", ";"));return foreachElement;}/** * @param primaryKeyColumns * @return */public XmlElement NewIfElement(List<IntrospectedColumn> primaryKeyColumns){StringBuilder sb = new StringBuilder();boolean flag = false;for (IntrospectedColumn introspectedColumn : primaryKeyColumns) {if (flag) {sb.append(" and ");sb.append(item).append(".");sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));sb.append(" != null");} else {sb.append(item).append(".");sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));sb.append(" != null");flag = true;}}XmlElement ifElement = new XmlElement("if");ifElement.addAttribute(new Attribute("test", sb.toString()));return ifElement;}}
- maven+mybatis+mybatis-generator+sql server 2005自动生成代码,加上自定义分页插件和批量插入更新插件
- mybatis maven generator 插件自动生成代码
- mybatis-利用mybatis-generator(maven插件)自动生成代码
- maven插件-利用mybatis-generator自动生成代码
- mybatis generator maven插件自动生成代码__个人记录
- maven插件mybatis-generator自动生成
- maven插件mybatis-generator自动生成
- maven插件mybatis-generator生成代码配置
- maven插件mybatis-generator生成代码配置
- maven插件mybatis-generator生成代码配置
- maven插件mybatis-generator生成代码配置
- mybatis-generator插件自动生成代码
- Maven插件之mybatis-generator(mybatis自动生成实体代码的插件)
- Maven插件之mybatis-generator(mybatis自动生成实体代码的插件)
- 使用Maven 插件Mybatis Generator自动生成Mybatis数据映射代码
- Maven插件之mybatis-generator自动生成DAO层代码的插件
- mybatis-generator插件自动生成mybatis文件
- 用maven插件自动生成mybatis代码
- linux下安装mysql
- 深入理解JVM内幕:从基本结构到Java 7新特性
- 证明:含有n个结点的二叉链表中共有n+1个空链域
- URLRewriter最简单入门介绍 URLRewriter相关资源
- DOS或命令行下查看进程,结束进程命令
- maven+mybatis+mybatis-generator+sql server 2005自动生成代码,加上自定义分页插件和批量插入更新插件
- Android系统服务
- C++头文件包含顺序问题(转载)
- 深入JVM的Class文件结构
- JIRA后台索引无法进行的解决方式
- Protel PCB各层含义
- 如何在Windows环境下的VS中安装使用Google Protobuf完成SOCKET通信
- 2013-11-15 singelton的实现及学习的笔记
- Eclipse 常用技巧功能