浪子逍遥遥
2017-06-12 15:21:35
maven+mybatis+generator整合生成java自定义model实体类,dao接口和mapper映射文件
通过继承PluginAdapter类,开发自定义插件,生成自定义的中文注解的java实体类,dao接口和mapper映射文件.
1.pom.xml添加依赖的jar包:
<dependencies> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.30</version> </dependency> <!--Mybatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.3.1</version> </dependency> <!-- Mybatis Generator --> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.3.5</version> </dependency> </dependencies>
2.配置generatorConfig.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <!-- 引入配置文件 --> <properties resource="jdbc.properties" /> <context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat"> <property name="beginningDelimiter" value="`" /> <property name="endingDelimiter" value="`" /> <!-- 生成的文件编码 --> <property name="javaFileEncoding" value="utf-8"/> <!-- 通过自定义插件类生成自定义注解和接口 --> <plugin type="com.xe.demo.common.generator.GenPlugin"> <property name="mappers" value="com.xe.demo.mapper.BaseMapper" /> </plugin> <commentGenerator> <!-- 取消生成注释 --> <property name="suppressAllComments" value="true"/> </commentGenerator> <!-- 数据库连接属性 --> <jdbcConnection driverClass="${jdbc.driver}" connectionURL="${jdbc.url}" userId="${jdbc.username}" password="${jdbc.password}" /> <!-- 生成实体类配置 --> <javaModelGenerator targetPackage="com.xe.demo.model" targetProject="src/main/java" /> <!-- 生成映射文件配置 --> <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources" /> <!-- 生成映射接口配置 --> <javaClientGenerator targetPackage="com.xe.demo.mapper" targetProject="src/main/java" type="XMLMAPPER" /> <table tableName="%"> <!--mysql 配置 --> <generatedKey column="id" sqlStatement="Mysql" identity="true" /> </table> </context> </generatorConfiguration>
以上配置完成,其实就通过generator可以生成默认的代码了,但是我们想生成我们自定义的代码,就需要继承PluginAdapter开发自定义插件来实现:
3.创建GenPlugin.java继承PluginAdapter:
1).把数据库字段的注释作为生成的实体类字段注释,创建GenCommentGenerator.java类,实现CommentGenerator.java,具体实现如下:
/** * 给字段添加数据库备注 * @param field * @param introspectedTable * @param introspectedColumn */ @Override public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) { if (StringUtility.stringHasValue(introspectedColumn.getRemarks())) { field.addJavaDocLine("//" + introspectedColumn.getRemarks()); } }
/** * getter方法注释 * @param method * @param introspectedTable * @param introspectedColumn */ @Override public void addGetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) { StringBuilder sb = new StringBuilder(); method.addJavaDocLine("/**"); if (StringUtility.stringHasValue(introspectedColumn.getRemarks())) { sb.append(" * 获取"); sb.append(introspectedColumn.getRemarks()); method.addJavaDocLine(sb.toString()); method.addJavaDocLine(" *"); } sb.setLength(0); sb.append(" * @return "); sb.append(introspectedColumn.getActualColumnName()); if (StringUtility.stringHasValue(introspectedColumn.getRemarks())) { sb.append(" - "); sb.append(introspectedColumn.getRemarks()); } method.addJavaDocLine(sb.toString()); method.addJavaDocLine(" */"); }
/** * setter方法注释 * @param method * @param introspectedTable * @param introspectedColumn */ @Override public void addSetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) { StringBuilder sb = new StringBuilder(); method.addJavaDocLine("/**"); if (StringUtility.stringHasValue(introspectedColumn.getRemarks())) { sb.append(" * 设置"); sb.append(introspectedColumn.getRemarks()); method.addJavaDocLine(sb.toString()); method.addJavaDocLine(" *"); } Parameter parm = method.getParameters().get(0); sb.setLength(0); sb.append(" * @param "); sb.append(parm.getName()); if (StringUtility.stringHasValue(introspectedColumn.getRemarks())) { sb.append(" "); sb.append(introspectedColumn.getRemarks()); } method.addJavaDocLine(sb.toString()); method.addJavaDocLine(" */"); }
在GenPlugin.java重写方法setContext:
// 注释生成器 private CommentGeneratorConfiguration commentCfg; @Override public void setContext(Context context) { super.setContext(context); // 设置默认的注释生成器 commentCfg = new CommentGeneratorConfiguration(); commentCfg.setConfigurationType(GenCommentGenerator.class.getCanonicalName()); context.setCommentGeneratorConfiguration(commentCfg); // 支持oracle获取注释#114 context.getJdbcConnectionConfiguration().addProperty("remarksReporting", "true"); }
2).创建基础mapper接口BaseMapper.java,重写clientGenerated方法,让generator自动生成的接口继承BaseMapper.java:
package com.xe.demo.mapper; import java.io.Serializable; import java.util.List; import org.apache.ibatis.annotations.Param; import com.xe.demo.common.pojo.PageModel; /** * Mybatis基础DAO * @author 蔡泽华 */ public interface BaseMapper<T> { /** * 通过ID查询 * @param id * @return */ Object selectById(Serializable id); /** * 查询单条记录 * @param entity * @return */ Object selectOne(@Param("item")Object obj); /** * 查询记录集合 * @param entity * @return */ List<?> selectList(@Param("item")Object obj); /** * 分页查询 * @param t * @param page * @return */ List<T> selectPage(@Param("item")Object obj, @Param("page")PageModel page); /** * 通用的保存方法 * @param <T> * @param entity */ void save(@Param("item")Object obj); /** * 批量保存 * @param list */ int batchSave(List<?> list); /** * 通用的修改方法 * @param <T> * @param entity */ int update(@Param("item")Object obj); /** * 批量更新 * @param list * @return */ int batchUpdate(List<?> list); /** * 删除方法 * @param id */ int delById(Serializable id); /** * 批量删除 * @param list * @return */ int delList(List<?> list); /** * 批量删除方法 * @param ids */ int delArray(int[] ids); /** * 统计查询 * @param <T> * @param params 查询参数 * @return 总记录条数 */ int count(Object obj); }
private Set<String> mappers = new HashSet<String>(); @Override public void setProperties(Properties properties) { super.setProperties(properties); String mappers = this.properties.getProperty("mappers"); for (String mapper : mappers.split(",")) { this.mappers.add(mapper); } } /** * 生成的Mapper接口 * @param interfaze * @param topLevelClass * @param introspectedTable * @return */ @Override public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { // 获取实体类 FullyQualifiedJavaType entityType = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType()); // import接口 for (String mapper : mappers) { interfaze.addImportedType(new FullyQualifiedJavaType(mapper)); interfaze.addSuperInterface(new FullyQualifiedJavaType(mapper + "<" + entityType.getShortName() + ">")); } // import实体类 interfaze.addImportedType(entityType); return true; }
3).重写sqlMapDocumentGenerated方法,让生成BaseMapper.java接口对应的映射文件:
/** * 拼装SQL语句生成Mapper接口映射文件 */ @Override public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) { XmlElement rootElement = document.getRootElement(); // 数据库表名 String tableName = introspectedTable.getFullyQualifiedTableNameAtRuntime(); // 主键 IntrospectedColumn pkColumn = introspectedTable.getPrimaryKeyColumns().get(0); // 公共字段 StringBuilder columnSQL = new StringBuilder(); // IF判断语句 StringBuilder ifSQL = new StringBuilder(); // 要插入的字段(排除自增主键) StringBuilder saveColumn = new StringBuilder("insert into ").append(tableName).append("(\n"); // 要保存的值 StringBuilder saveValue = new StringBuilder("(\n"); // 拼装更新字段 StringBuilder updateSQL = new StringBuilder("update ").append(tableName).append(" set ").append(pkColumn.getActualColumnName()) .append(" = #{item.").append(pkColumn.getJavaProperty()).append("}\n"); // 数据库字段名 String columnName = null; // java字段名 String javaProperty = null; for (IntrospectedColumn introspectedColumn : introspectedTable.getAllColumns()) { columnName = MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn); javaProperty = introspectedColumn.getJavaProperty(); // 拼接字段 columnSQL.append(columnName).append(","); // 拼接IF语句 ifSQL.append(" <if test=\"null != item.").append(javaProperty).append(" and '' != item.").append(javaProperty).append("\">"); ifSQL.append("and ").append(columnName).append(" = #{item.").append(javaProperty).append("}</if>\n"); // 拼接SQL if (!introspectedColumn.isAutoIncrement()) { saveColumn.append("\t <if test=\"null != item.").append(javaProperty).append("\">, ").append(columnName).append("</if>\n"); saveValue.append("\t <if test=\"null != item.").append(javaProperty).append("\">, ").append("#{item.").append(javaProperty) .append("}</if>\n"); updateSQL.append(" <if test=\"null != item.").append(javaProperty).append("\">"); updateSQL.append(", ").append(columnName).append(" = #{item.").append(javaProperty).append("}</if>\n"); } } String columns = columnSQL.substring(0, columnSQL.length() - 1); rootElement.addElement(createSql("sql_columns", columns)); String whereSQL = MessageFormat.format("<where>\n{0}\t</where>", ifSQL.toString()); rootElement.addElement(createSql("sql_where", whereSQL)); rootElement.addElement(createSelect("selectById", tableName, pkColumn)); rootElement.addElement(createSelect("selectOne", tableName, null)); rootElement.addElement(createSelect("selectList", tableName, null)); rootElement.addElement(createSelect("selectPage", tableName, null)); rootElement.addElement(createSql("sql_save_columns", saveColumn.append("\t) values").toString().replaceFirst(",", ""))); rootElement.addElement(createSql("sql_save_values", saveValue.append("\t)").toString().replaceFirst(",", ""))); rootElement.addElement(createSave("save", pkColumn)); rootElement.addElement(createSave("batchSave", null)); updateSQL.append("\twhere ").append(pkColumn.getActualColumnName()).append(" = #{item.").append(pkColumn.getJavaProperty()).append("}"); rootElement.addElement(createSql("sql_update", updateSQL.toString())); rootElement.addElement(createUpdate("update")); rootElement.addElement(createUpdate("batchUpdate")); rootElement.addElement(createDels(tableName, pkColumn, "delArray", "array")); rootElement.addElement(createDels(tableName, pkColumn, "delList", "list")); return super.sqlMapDocumentGenerated(document, introspectedTable); } /** * 公共SQL * @param id * @param sqlStr * @return */ private XmlElement createSql(String id, String sqlStr) { XmlElement sql = new XmlElement("sql"); sql.addAttribute(new Attribute("id", id)); sql.addElement(new TextElement(sqlStr)); return sql; } /** * 查询 * @param id * @param tableName * @param pkColumn * @return */ private XmlElement createSelect(String id, String tableName, IntrospectedColumn pkColumn) { XmlElement select = new XmlElement("select"); select.addAttribute(new Attribute("id", id)); select.addAttribute(new Attribute("resultMap", "BaseResultMap")); StringBuilder selectStr = new StringBuilder("select <include refid=\"sql_columns\" /> from ").append(tableName); if (null != pkColumn) { selectStr.append(" where ").append(pkColumn.getActualColumnName()).append(" = #{").append(pkColumn.getJavaProperty()).append("}"); } else { selectStr.append(" <include refid=\"sql_where\" />"); } if ("selectPage".equals(id)) { selectStr.append(" limit #{page.startRow}, #{page.pageSize}"); } select.addElement(new TextElement(selectStr.toString())); return select; } /** * 保存 * @param id * @param pkColumn * @return */ private XmlElement createSave(String id, IntrospectedColumn pkColumn) { XmlElement save = new XmlElement("insert"); save.addAttribute(new Attribute("id", id)); if (null != pkColumn) { save.addAttribute(new Attribute("keyProperty", "item." + pkColumn.getJavaProperty())); save.addAttribute(new Attribute("useGeneratedKeys", "true")); save.addElement(new TextElement("<include refid=\"sql_save_columns\" /><include refid=\"sql_save_values\" />")); } else { StringBuilder saveStr = new StringBuilder( "<foreach collection=\"list\" index=\"index\" item=\"item\" open=\"\" separator=\";\" close=\"\">\n\t ") .append("<include refid=\"sql_save_columns\" /><include refid=\"sql_save_values\" />\n\t</foreach>"); save.addElement(new TextElement(saveStr.toString())); } return save; } /** * 更新 * @param id * @return */ private XmlElement createUpdate(String id) { XmlElement update = new XmlElement("update"); update.addAttribute(new Attribute("id", id)); if ("update".equals(id)) { update.addElement(new TextElement("<include refid=\"sql_update\" />")); } else { update.addElement(new TextElement( "<foreach collection=\"list\" index=\"index\" item=\"item\" open=\"\" separator=\";\" close=\"\">\n\t <include refid=\"sql_update\" />\n\t</foreach>")); } return update; } /** * 删除 * @param tableName * @param pkColumn * @param method * @param type * @return */ private XmlElement createDels(String tableName, IntrospectedColumn pkColumn, String method, String type) { XmlElement delete = new XmlElement("delete"); delete.addAttribute(new Attribute("id", method)); StringBuilder deleteStr = new StringBuilder("delete from ").append(tableName).append(" where ").append(pkColumn.getActualColumnName()) .append(" in\n\t") .append("<foreach collection=\"").append(type) .append("\" index=\"index\" item=\"item\" open=\"(\" separator=\",\" close=\")\">#{item}</foreach>"); delete.addElement(new TextElement(deleteStr.toString())); return delete; }
4.执行GenMain.java方法:
package com.xe.demo; import java.io.File; import java.util.ArrayList; import java.util.List; import org.mybatis.generator.api.MyBatisGenerator; import org.mybatis.generator.config.Configuration; import org.mybatis.generator.config.xml.ConfigurationParser; import org.mybatis.generator.internal.DefaultShellCallback; public class GenMain { public static void main(String[] args) { //读取文件 File configFile = new File(GenMain.class.getResource("/generatorConfig.xml").getFile()); List<String> warnings = new ArrayList<String>(); ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = null; //true:覆盖生成 DefaultShellCallback callback = new DefaultShellCallback(true); MyBatisGenerator myBatisGenerator = null; try { config = cp.parseConfiguration(configFile); myBatisGenerator = new MyBatisGenerator(config, callback, warnings); myBatisGenerator.generate(null); System.err.println("代码成功生成!"); } catch (Exception e) { e.printStackTrace(); } } }
执行完刷新项目,项目结构前后对比:
下面是自动生成的代码:
package com.xe.demo.model; import java.math.BigDecimal; public class IMemberOrders { private Long oid; //订单号 private String ordercode; //昵称 private String nickname; //商品名 private String shopname; //购买数量 private Short buycount; //当次花费 private BigDecimal paycount; //购买时间 private String buytime; /** * @return oid */ public Long getOid() { return oid; } /** * @param oid */ public void setOid(Long oid) { this.oid = oid; } /** * 获取订单号 * * @return ordercode - 订单号 */ public String getOrdercode() { return ordercode; } /** * 设置订单号 * * @param ordercode 订单号 */ public void setOrdercode(String ordercode) { this.ordercode = ordercode; } /** * 获取昵称 * * @return nickname - 昵称 */ public String getNickname() { return nickname; } /** * 设置昵称 * * @param nickname 昵称 */ public void setNickname(String nickname) { this.nickname = nickname; } /** * 获取商品名 * * @return shopname - 商品名 */ public String getShopname() { return shopname; } /** * 设置商品名 * * @param shopname 商品名 */ public void setShopname(String shopname) { this.shopname = shopname; } /** * 获取购买数量 * * @return buycount - 购买数量 */ public Short getBuycount() { return buycount; } /** * 设置购买数量 * * @param buycount 购买数量 */ public void setBuycount(Short buycount) { this.buycount = buycount; } /** * 获取当次花费 * * @return paycount - 当次花费 */ public BigDecimal getPaycount() { return paycount; } /** * 设置当次花费 * * @param paycount 当次花费 */ public void setPaycount(BigDecimal paycount) { this.paycount = paycount; } /** * 获取购买时间 * * @return buytime - 购买时间 */ public String getBuytime() { return buytime; } /** * 设置购买时间 * * @param buytime 购买时间 */ public void setBuytime(String buytime) { this.buytime = buytime; } }
package com.xe.demo.mapper; import com.xe.demo.model.IMemberOrders; public interface IMemberOrdersMapper extends BaseMapper<IMemberOrders> { }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.xe.demo.mapper.IMemberOrdersMapper"> <resultMap id="BaseResultMap" type="com.xe.demo.model.IMemberOrders"> <id column="oid" jdbcType="BIGINT" property="oid" /> <result column="ordercode" jdbcType="VARCHAR" property="ordercode" /> <result column="nickname" jdbcType="VARCHAR" property="nickname" /> <result column="shopname" jdbcType="VARCHAR" property="shopname" /> <result column="buycount" jdbcType="SMALLINT" property="buycount" /> <result column="paycount" jdbcType="DECIMAL" property="paycount" /> <result column="buytime" jdbcType="VARCHAR" property="buytime" /> </resultMap> <sql id="sql_columns"> oid,ordercode,nickname,shopname,buycount,paycount,buytime </sql> <sql id="sql_where"> <where> <if test="null != item.oid and '' != item.oid">and oid = #{item.oid}</if> <if test="null != item.ordercode and '' != item.ordercode">and ordercode = #{item.ordercode}</if> <if test="null != item.nickname and '' != item.nickname">and nickname = #{item.nickname}</if> <if test="null != item.shopname and '' != item.shopname">and shopname = #{item.shopname}</if> <if test="null != item.buycount and '' != item.buycount">and buycount = #{item.buycount}</if> <if test="null != item.paycount and '' != item.paycount">and paycount = #{item.paycount}</if> <if test="null != item.buytime and '' != item.buytime">and buytime = #{item.buytime}</if> </where> </sql> <select id="selectById" resultMap="BaseResultMap"> select <include refid="sql_columns" /> from i_member_orders where oid = #{oid} </select> <select id="selectOne" resultMap="BaseResultMap"> select <include refid="sql_columns" /> from i_member_orders <include refid="sql_where" /> </select> <select id="selectList" resultMap="BaseResultMap"> select <include refid="sql_columns" /> from i_member_orders <include refid="sql_where" /> </select> <select id="selectPage" resultMap="BaseResultMap"> select <include refid="sql_columns" /> from i_member_orders <include refid="sql_where" /> limit #{page.startRow}, #{page.pageSize} </select> <sql id="sql_save_columns"> insert into i_member_orders( <if test="null != item.ordercode"> ordercode</if> <if test="null != item.nickname">, nickname</if> <if test="null != item.shopname">, shopname</if> <if test="null != item.buycount">, buycount</if> <if test="null != item.paycount">, paycount</if> <if test="null != item.buytime">, buytime</if> ) values </sql> <sql id="sql_save_values"> ( <if test="null != item.ordercode"> #{item.ordercode}</if> <if test="null != item.nickname">, #{item.nickname}</if> <if test="null != item.shopname">, #{item.shopname}</if> <if test="null != item.buycount">, #{item.buycount}</if> <if test="null != item.paycount">, #{item.paycount}</if> <if test="null != item.buytime">, #{item.buytime}</if> ) </sql> <insert id="save" keyProperty="item.oid" useGeneratedKeys="true"> <include refid="sql_save_columns" /><include refid="sql_save_values" /> </insert> <insert id="batchSave"> <foreach collection="list" index="index" item="item" open="" separator=";" close=""> <include refid="sql_save_columns" /><include refid="sql_save_values" /> </foreach> </insert> <sql id="sql_update"> update i_member_orders set oid = #{item.oid} <if test="null != item.ordercode">, ordercode = #{item.ordercode}</if> <if test="null != item.nickname">, nickname = #{item.nickname}</if> <if test="null != item.shopname">, shopname = #{item.shopname}</if> <if test="null != item.buycount">, buycount = #{item.buycount}</if> <if test="null != item.paycount">, paycount = #{item.paycount}</if> <if test="null != item.buytime">, buytime = #{item.buytime}</if> where oid = #{item.oid} </sql> <update id="update"> <include refid="sql_update" /> </update> <update id="batchUpdate"> <foreach collection="list" index="index" item="item" open="" separator=";" close=""> <include refid="sql_update" /> </foreach> </update> <delete id="delArray"> delete from i_member_orders where oid in <foreach collection="array" index="index" item="item" open="(" separator="," close=")">#{item}</foreach> </delete> <delete id="delList"> delete from i_member_orders where oid in <foreach collection="list" index="index" item="item" open="(" separator="," close=")">#{item}</foreach> </delete> </mapper>
源码下载地址:maven整合mybatis+generator生成java自定义model实体类,dao接口和mapper映射文件
评论