MyBatis代码生成器

写作前面

关于MyBatis代码生成器,笔者接触过的有三个:MyBatis-Generator、通用Mapper、MyBatis-Plus。这三个插件或多或少都能简化基于MyBatis的开发过程。下面通过一个小案例演示一下这三款插件的基本使用。

环境
maven依赖

    org.springframework.boot
    spring-boot-starter-parent
    2.0.5.RELEASE
     


    
        org.springframework.boot
        spring-boot-starter-web
    
    
        org.mybatis.spring.boot
        mybatis-spring-boot-starter
        1.3.2
    
    
        mysql
        mysql-connector-java
        8.0.11
    

配置文件application.yml:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/generator?useSSL=false&serverTimezone=CST
    username: root
    password: root
MySQL
DROP TABLE IF EXISTS user;
CREATE TABLE user
(
	id BIGINT(20) NOT NULL COMMENT '主键ID',
	name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
	age INT(11) NULL DEFAULT NULL COMMENT '年龄',
	email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
	PRIMARY KEY (id)
);


DELETE FROM user;
INSERT INTO user (id, name, age, email) VALUES
(1, 'test1', 18, '[email protected]'),
(2, 'test2', 19, '[email protected]'),
(3, 'test3', 20, '[email protected]'),
(4, 'test4', 21, '[email protected]');
MyBatis-Generator

MyBatis-Generator可以将数据库的表映射到Java的类中,同时自动生成DataObject、Mapper、XML(包括一些简单的SQL语句)文件。

在使用Mybatis-Generator前需要进行一些配置,在前面maven依赖的基础上加入如下配置,添加Mybatis-generator插件:


    
      
        org.mybatis.generator
        mybatis-generator-maven-plugin
        1.3.5
        
          
            org.mybatis.generator
            mybatis-generator-core
            1.3.5
          
          
            mysql
            mysql-connector-java
            8.0.11
          
        
        
          
            mybatis generator
            package
            
              generate
            
          
        
        
          
          true
          
          true

          
          
              src/main/resources/mybatis-generator.xml
          
        
      
    

添加以上配置之后在maven插件下就会有mybatis-generator插件。

MyBatis代码生成器_第1张图片

在resources目录下创建mybatis-generator.xml和jdbcConfig.properties



<generatorConfiguration>
    
    <properties resource="jdbcConfig.properties">properties>
    <context id="DB2Tables" targetRuntime="MyBatis3">

        
        <commentGenerator>
            
            <property name="suppressDate" value="true"/>
            
            <property name="suppressAllComments" value="true" />
        commentGenerator>

        
        <jdbcConnection
                driverClass="${jdbc.driverClassName}"
                connectionURL="${jdbc.url}"
                userId="${jdbc.username}"
                password="${jdbc.password}">
             
            <property name="nullCatalogMeansCurrent" value="true"/>
        jdbcConnection>


        
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        javaTypeResolver>

        
        <javaModelGenerator targetPackage="cn.charviki.dataobject" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        javaModelGenerator>

        
        <sqlMapGenerator targetPackage="mapping" targetProject="src/main/resources">
            <property name="enableSubPackages" value="true"/>
        sqlMapGenerator>

        
        
        <javaClientGenerator type="XMLMAPPER" targetPackage="cn.charviki.dao" targetProject="src/main/java">
            <property name="enableSubPackages" value="true" />
        javaClientGenerator>

        
        <table tableName="user" domainObjectName="UserDO" enableCountByExample="false"
               enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false" >table>
    context>
generatorConfiguration>

jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/generator?useSSL=false&serverTimezone=CST
jdbc.username=root
jdbc.password=root

根据mybatis-generator.xml中的配置的生成文件的路径创建相应的包或目录,比如我这里配置的在cn.charviki.dataobject包下存放生成的dataobject对象。

完成以上配置之后,运行mybatis-generator插件,执行完毕后目录结构如下:

MyBatis代码生成器_第2张图片

以上就是使用mybatis-generator完成数据库表到Java类的映射和自动生成代码的过程。至于mybatis-generator一些更高级的配置和说明可参考官方文档MyBatis-Generator。

通用Mapper

mybatis-generator有一个缺点就是当数据库字段变化频繁时,使用MBG(mybatis-generator)会带来大量的重构工作,对此,通用Mapper给出的解决办法是:给予开发者一个具备丰富的单表方法并且容易扩展的通用的Mapper。 可以认为通用mapper就是MBG的升级版本,通过MBG自动生成代码,并且封装了许多单表操作的方法供使用者调用。

在前面依赖的基础上添加mapper依赖:


    tk.mybatis
    mapper
    4.0.0

添加mybatis-generator的maven插件:


  
    maven-compiler-plugin
    
      1.8
      1.8
    
  
  
    org.mybatis.generator
    mybatis-generator-maven-plugin
    1.3.6
    
      
        ${basedir}/src/main/resources/generatorConfig.xml
      
      true
      true
    
    
      
        mysql
        mysql-connector-java
        8.0.11
      
      
        tk.mybatis
        mapper
        4.0.0
      
    
  

在resources目录下增加配置文件 generatorConfig.xml:



<generatorConfiguration>
    <properties resource="jdbcConfig.properties"/>

    <context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>

        <plugin type="tk.mybatis.mapper.generator.MapperPlugin">
            <property name="mappers" value="tk.mybatis.mapper.common.Mapper"/>
            <property name="caseSensitive" value="true"/>
        plugin>

        <jdbcConnection driverClass="${jdbc.driverClassName}"
                        connectionURL="${jdbc.url}"
                        userId="${jdbc.username}"
                        password="${jdbc.password}">
            
            <property name="nullCatalogMeansCurrent" value="true"/>
        jdbcConnection>

        <javaModelGenerator targetPackage="cn.charviki.model"
                            targetProject="src/main/java"/>

        <sqlMapGenerator targetPackage="mapper"
                         targetProject="src/main/resources"/>

        <javaClientGenerator targetPackage="cn.charviki.mapper"
                             targetProject="src/main/java"
                             type="XMLMAPPER"/>

        <table tableName="user">
            <generatedKey column="id" sqlStatement="JDBC"/>
        table>
    context>
generatorConfiguration>

运行mybatis-generator插件后生成目录结构如下:

MyBatis代码生成器_第3张图片

自动生成的Mapper、Entity、XML代码如下:

public interface UserMapper extends Mapper<User> {
}
@Table(name = "user")
public class User {
    /**
     * 主键ID
     */
    @Id
    @GeneratedValue(generator = "JDBC")
    private Long id;

    /**
     * 姓名
     */
    private String name;

    /**
     * 年龄
     */
    private Integer age;

    /**
     * 邮箱
     */
    private String email;

    /**
     * 获取主键ID
     *
     * @return id - 主键ID
     */
    public Long getId() {
        return id;
    }

    /**
     * 设置主键ID
     *
     * @param id 主键ID
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * 获取姓名
     *
     * @return name - 姓名
     */
    public String getName() {
        return name;
    }

    /**
     * 设置姓名
     *
     * @param name 姓名
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取年龄
     *
     * @return age - 年龄
     */
    public Integer getAge() {
        return age;
    }

    /**
     * 设置年龄
     *
     * @param age 年龄
     */
    public void setAge(Integer age) {
        this.age = age;
    }

    /**
     * 获取邮箱
     *
     * @return email - 邮箱
     */
    public String getEmail() {
        return email;
    }

    /**
     * 设置邮箱
     *
     * @param email 邮箱
     */
    public void setEmail(String email) {
        this.email = email;
    }
}


<mapper namespace="cn.charviki.mapper.UserMapper">
  <resultMap id="BaseResultMap" type="cn.charviki.model.User">
    
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="age" jdbcType="INTEGER" property="age" />
    <result column="email" jdbcType="VARCHAR" property="email" />
  resultMap>
mapper>

通用Mapper在MBG的基础上对生成代码注释进行了改进,根据数据库的注释生成相应的Java注释。在生成的XML中只有数据库数据类型和Java数据类型的映射关系,至于其他针对数据库单表操作的SQL已经封装在了相应的Mapper中。

接下来将SpringBoot中的启动类加入通用Mapper的注解@MapperScan配置Mapper扫描包。

@SpringBootApplication
@MapperScan("cn.charviki.mapper")
public class App {
    public static void main( String[] args ) {
        SpringApplication.run(App.class);
    }
}

编写测试类:

@SpringBootTest
@RunWith(SpringRunner.class)
public class AppTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void mapperTest(){
        List<User> users = userMapper.selectAll();
        for (User user : users) {
            System.out.println(user);
        }
    }
}

为方便查看,在生成的User类中重写toString方法。运行测试类,控制台输出:

MyBatis代码生成器_第4张图片

自此,SpringBoot成功整合和通用Mapper,如果需要扩展一下复杂的SQL语句,直接在Mapper中使用注解,并在注解内直接写SQL语句即可,省去了使用配置文件。

通过IDEA查看一下UserDOMapper对数据表操作方法:

MyBatis代码生成器_第5张图片

这些方法能实现大部分的单表操作。

通过查看通用Mapper的包结构,可以发现通用Mapper还提供了单表数据的批量操作,只需要继承相应的Mapper接口即可。

MyBatis代码生成器_第6张图片

小结一下,通用Mapper是相当与MBG的改进,比起MBG更加简洁和方便。我个人比较喜欢将通用Mapper和lombok结合使用,近乎纯注解的配置,看起来十分简洁。

如果想要近一步了解通用Mapper,可参考官方文档 Mapper。

MyBatis-Plus

笔者也是最近才开始接触MyBatis-Plus这款插件,这款插件十分强大。官方介绍:MyBatis-Plus是在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 也就是说,如果你以前使用的是原生的MyBatis开发,现在你可以直接使用MyBatis-Plus替换掉MyBatis的依赖,代码上不做任何改动仍能正常运行,同时你还可以使用许多增强功能。比如通用Mapper、通用Service、内置分页插件等。

MyBatis-Plus的使用十分简单,只需要将MyBatis-Plus的依赖替换掉MyBatis的依赖:


    com.baomidou
    mybatis-plus-boot-starter
    3.2.0

如果要使用MyBatis-Plus的代码生成器,需要引入下面的依赖:


    com.baomidou
    mybatis-plus-generator
    3.2.0



    org.freemarker
    freemarker
    2.3.29

下面是官方给的生成代码配置:

// 演示例子,执行 main 方法控制台输入模块表名回车自动生成对应项目目录中
public class CodeGenerator {

    /**
     * 

* 读取控制台内容 *

*/
public static String scanner(String tip) { Scanner scanner = new Scanner(System.in); StringBuilder help = new StringBuilder(); help.append("请输入" + tip + ":"); System.out.println(help.toString()); if (scanner.hasNext()) { String ipt = scanner.next(); if (StringUtils.isNotEmpty(ipt)) { return ipt; } } throw new MybatisPlusException("请输入正确的" + tip + "!"); } public static void main(String[] args) { // 代码生成器 AutoGenerator mpg = new AutoGenerator(); // 全局配置 GlobalConfig gc = new GlobalConfig(); String projectPath = System.getProperty("user.dir"); gc.setOutputDir(projectPath + "/src/main/java"); gc.setAuthor("jobob"); gc.setOpen(false); // gc.setSwagger2(true); 实体属性 Swagger2 注解 mpg.setGlobalConfig(gc); // 数据源配置 DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://localhost:3306/ant?useUnicode=true&useSSL=false&characterEncoding=utf8"); // dsc.setSchemaName("public"); dsc.setDriverName("com.mysql.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("密码"); mpg.setDataSource(dsc); // 包配置 PackageConfig pc = new PackageConfig(); pc.setModuleName(scanner("模块名")); // 包路径 pc.setParent("com.baomidou.ant"); mpg.setPackageInfo(pc); // 自定义配置 InjectionConfig cfg = new InjectionConfig() { @Override public void initMap() { // to do nothing } }; // 如果模板引擎是 freemarker String templatePath = "/templates/mapper.xml.ftl"; // 如果模板引擎是 velocity // String templatePath = "/templates/mapper.xml.vm"; // 自定义输出配置 List<FileOutConfig> focList = new ArrayList<>(); // 自定义配置会被优先输出 focList.add(new FileOutConfig(templatePath) { @Override public String outputFile(TableInfo tableInfo) { // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!! return projectPath + "/src/main/resources/mapper/" + pc.getModuleName() + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; } }); /* cfg.setFileCreate(new IFileCreate() { @Override public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) { // 判断自定义文件夹是否需要创建 checkDir("调用默认方法创建的目录"); return false; } }); */ cfg.setFileOutConfigList(focList); mpg.setCfg(cfg); // 配置模板 TemplateConfig templateConfig = new TemplateConfig(); // 配置自定义输出模板 //指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别 // templateConfig.setEntity("templates/entity2.java"); // templateConfig.setService(); // templateConfig.setController(); templateConfig.setXml(null); mpg.setTemplate(templateConfig); // 策略配置 StrategyConfig strategy = new StrategyConfig(); strategy.setNaming(NamingStrategy.underline_to_camel); strategy.setColumnNaming(NamingStrategy.underline_to_camel); strategy.setSuperEntityClass("com.baomidou.ant.common.BaseEntity"); strategy.setEntityLombokModel(true); strategy.setRestControllerStyle(true); // 公共父类 strategy.setSuperControllerClass("com.baomidou.ant.common.BaseController"); // 写于父类中的公共字段 strategy.setSuperEntityColumns("id"); strategy.setInclude(scanner("表名,多个英文逗号分割").split(",")); strategy.setControllerMappingHyphenStyle(true); strategy.setTablePrefix(pc.getModuleName() + "_"); mpg.setStrategy(strategy); mpg.setTemplateEngine(new FreemarkerTemplateEngine()); mpg.execute(); } }

只需要简单修改数据库连接信息,生成包信息和一些全局配置信息即可运行生成controller、entity、service、mapper等。

具体配置可参考官方文档MyBatis-Plus。

在生成代码后,关于测试查找功能的代码跟通用Mapper基本一样,这里不再过多介绍。

总结

以上就是三款Mybatis代码生成器的入门介绍,如果想要了解各个插件的高级用法,可参考文章给出的官方文档链接。关于三者的选择,笔者推荐是使用通用Mapper或者Mybatis-Plus,相比于这两个,MyBatis-Generator功能显得过于单一。Mybatis-Plus功能会更强大一点,毕竟也实现了通用Mapper的功能,而且支持的数据库类型也较多。笔者之前在使用通用Mapper的时候不是很喜欢使用代码生成器生成Mapper、Entity等(ps:因为生成的代码的注释和格式之类的和笔者的习惯有所不同),所以在接触Mybatis-Plus后感觉两者用法差不多,不过Mybatis-Plus支持自定义模板代码生成,可以尝试一下。

你可能感兴趣的:(SpringBoot,MyBatis,MyBatis)