Mybatis generator


Mybatis generator

目录:

  1. 简介

  2. 主要流程

    2.1 添加依赖

    2.2 配置文件

    2.3 自定义规则

    2.4 运行主类

  3. mapper接口

  4. Example类

参考/来源:

简介

​ 其主要的功能就是方便,快捷的创建好Dao,entry,xml 加快了开发速度,使用方面根据其提供的规则配置好就OK

​ 这里还有一个重要的开发场景,开发过程中,对数据库的操作肯定很多,比如新增字段什么的,你只要将原先自动生成的一套代码删除,重新再生成一份,这就完美解决了,但是这样做的前提是,你必须对生成后的代码不改动,只是使用。不需要像手动开发写代码那样到处改代码,还担心改漏地方。

​ 其实这个的实现方式也是五花八门的,写一种比较常见的

主要流程

添加依赖

主要是jdbc和generator

<!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
<dependency>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-core</artifactId>
    <version>1.3.6</version>
</dependency>

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.38</version>
</dependency>

配置文件

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>
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <!-- 生成mysql带有分页的sql的插件  这个可以自己写,-->
        <plugin type="generator.MysqlPaginationPlugin" />
      
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
				<!--生成mapper.xml时覆盖原文件-->
        <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />
      
        <!-- 自定义的注释规则,继承 DefaultCommentGenerator 重写 一些方法 -->
        <commentGenerator type="generator.NewbatisGenerator">
            <!-- 是否去除自动生成日期的注释 true:是 : false:否 -->
            <property name="suppressDate" value="true"/>
            <!-- 是否去除所有自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://数据库地址"
                        userId="username"
                        password="password">
          	<!--解决mysql驱动升级到8.0后不生成指定数据库代码的问题-->
            <property name="nullCatalogMeansCurrent" value="true" />
        </jdbcConnection>
      
        <!--生成entity类存放位置-->
        <javaModelGenerator targetPackage="包名(com.generator.test.entity)" targetProject="项目地址到\java (D:\workspace\src\main\java)">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
      
        <!--生成映射文件存放位置-->
        <sqlMapGenerator targetPackage="包名(com.generator.test.mapper)" targetProject="项目地址到\java (D:\workspace\src\main\java)">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
      
        <!--生成Dao类存放位置-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="包名(com.generator.test.dao)"
                             targetProject="项目地址到\java (D:\workspace\src\main\java)">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
      
        <!--生成全部表tableName设为%-->
        <table tableName="表名" domainObjectName="生成实体的类名">
        </table>
    </context>
</generatorConfiguration>

这里给一个实际的例子,有很多细节和注意的点,可以参考

<?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>
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <!-- 生成mysql带有分页的sql的插件  这个可以自己写,-->
        <plugin type="com.jason.generator.config.MysqlPaginationPlugin" />
        
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
        <!--生成mapper.xml时覆盖原文件
        <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />
        -->
        
        <!-- 自定义的注释规则,继承 DefaultCommentGenerator 重写 一些方法 -->
        <commentGenerator type="com.jason.generator.config.NewbatisGenerator">
            <!-- 是否去除自动生成日期的注释 true:是 : false:否 -->
            <property name="suppressDate" value="true"/>
            <!-- 是否去除所有自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        
        <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/test"
                        userId="root"
                        password="qianhao123">
            <!--解决mysql驱动升级到8.0后不生成指定数据库代码的问题-->
            <property name="nullCatalogMeansCurrent" value="true" />
        </jdbcConnection>
        <!--生成entity类存放位置-->
        <javaModelGenerator targetPackage="com.jason.entity" targetProject="src/main/java"/>

        <!--生成映射文件存放位置-->
        <sqlMapGenerator targetPackage="com.jason.mybatisxml" targetProject="src/main/resources"/>
        
        <!--生成Dao类存放位置-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.jason.mapper" targetProject="src/main/java"/>

		 <!--生成全部表tableName设为%-->
		 <table tableName="%">
            <generatedKey column="id" sqlStatement="MySql" identity="true"/>
        </table>
    </context>
</generatorConfiguration>

自定义规则

主要看你个人的需求,对注释,分页啥的有啥要求不,可以重写几个方法对其进行改造。

自定义注释规则

public class NewbatisGenerator extends DefaultCommentGenerator {
    private Properties properties;
    private Properties systemPro;
    private boolean suppressDate;
    private boolean suppressAllComments;
    private String currentDateStr;

    public NewbatisGenerator() {
        super();
        properties = new Properties();
        systemPro = System.getProperties();
        suppressDate = false;
        suppressAllComments = false;
        currentDateStr = (new SimpleDateFormat("yyyy-MM-dd")).format(new Date());
    }

    /**
     * 对类的注解
     * @param topLevelClass
     * @param introspectedTable
     */
    @Override
    public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        topLevelClass.addJavaDocLine("/**");
        topLevelClass.addJavaDocLine(" * 这是MyBatis Generator自动生成的Model Class.");

        StringBuilder sb = new StringBuilder();
        sb.append(" * 对应的数据表是 : ");
        sb.append(introspectedTable.getFullyQualifiedTable());
        topLevelClass.addJavaDocLine(sb.toString());

        String tableRemarks = introspectedTable.getRemarks();
        if (!StringUtils.isEmpty(tableRemarks)) {
            sb.setLength(0);
            sb.append(" * 数据表注释 : ");
            sb.append(tableRemarks);
            topLevelClass.addJavaDocLine(sb.toString());
        }

        sb.setLength(0);
        sb.append(" * @author ");
        sb.append(systemPro.getProperty("user.name"));
        topLevelClass.addJavaDocLine(sb.toString());

        String curDateString = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date());
        sb.setLength(0);
        sb.append(" * @date ");
        sb.append(curDateString);
        topLevelClass.addJavaDocLine(sb.toString());

        topLevelClass.addJavaDocLine(" */");
    }

    /**
     * 生成的实体增加字段的中文注释
     */
    public void addFieldComment(Field field, IntrospectedTable introspectedTable,
                                IntrospectedColumn introspectedColumn) {
        if (suppressAllComments) {
            return;
        }
        StringBuilder sb = new StringBuilder();
        field.addJavaDocLine("/**");
        sb.append(" * ");
        sb.append(introspectedColumn.getRemarks());
        field.addJavaDocLine(sb.toString().replace("\n", " "));
        field.addJavaDocLine(" */");
    }

}

自定义分页规则

public class MysqlPaginationPlugin extends PluginAdapter {
    public MysqlPaginationPlugin() {}

    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass,
            IntrospectedTable introspectedTable) {
        this.addLimit(topLevelClass, introspectedTable, "limitStart");
        this.addLimit(topLevelClass, introspectedTable, "limitSize");
        return super.modelExampleClassGenerated(topLevelClass, introspectedTable);
    }

    public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element,
            IntrospectedTable introspectedTable) {
        XmlElement isNotNullElement = new XmlElement("if");
        isNotNullElement
                .addAttribute(new Attribute("test", "limitStart != null and limitSize >= 0"));
        isNotNullElement.addElement(new TextElement("limit #{limitStart} , #{limitSize}"));
        element.addElement(isNotNullElement);
        return super.sqlMapSelectByExampleWithoutBLOBsElementGenerated(element, introspectedTable);
    }

    public boolean sqlMapSelectByExampleWithBLOBsElementGenerated(XmlElement element,
            IntrospectedTable introspectedTable) {
        XmlElement isNotNullElement = new XmlElement("if");
        isNotNullElement
                .addAttribute(new Attribute("test", "limitStart != null and limitSize >= 0"));
        isNotNullElement.addElement(new TextElement("limit #{limitStart} , #{limitSize}"));
        element.addElement(isNotNullElement);
        return super.sqlMapSelectByExampleWithBLOBsElementGenerated(element, introspectedTable);
    }

    private void addLimit(TopLevelClass topLevelClass, IntrospectedTable introspectedTable,
            String name) {
        CommentGenerator commentGenerator = this.context.getCommentGenerator();
        Field field = new Field();
        field.setVisibility(JavaVisibility.PROTECTED);
        field.setType(PrimitiveTypeWrapper.getIntegerInstance());
        field.setName(name);
        commentGenerator.addFieldComment(field, introspectedTable);
        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(PrimitiveTypeWrapper.getIntegerInstance(), name));
        StringBuilder sb = new StringBuilder();
        sb.append("this.");
        sb.append(name);
        sb.append(" = ");
        sb.append(name);
        sb.append(";");
        method.addBodyLine(sb.toString());
        commentGenerator.addGeneralMethodComment(method, introspectedTable);
        topLevelClass.addMethod(method);
        Method getterMethod = AbstractJavaGenerator.getGetter(field);
        commentGenerator.addGeneralMethodComment(getterMethod, introspectedTable);
        topLevelClass.addMethod(getterMethod);
    }

    public boolean validate(List<String> warnings) {
        return true;
    }



    /**
     * 生成mapper.xml,文件内容会被清空再写入
     * */
    @Override
    public boolean sqlMapGenerated(GeneratedXmlFile sqlMap, IntrospectedTable introspectedTable) {
        sqlMap.setMergeable(false);
        return super.sqlMapGenerated(sqlMap, introspectedTable);
    }

}

运行主类

public class Generator {

    public static void main(String[] args) throws Exception{
        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        File configFile = new File("generatorConfig.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);

    }
}

image-20220323133142812

然后需要刷新一下工程,就可以看到生成的代码。

使用生成的代码

一般来说,使用Mybatis generator生成代码的部分,会单独部署在一个工程,供其他工程引用。

配置文件

主要是将生成的xml文件和mapper接口进行关联

mybatis:
  mapper-locations:
    - classpath:com/**/mybatisxml/*.xml

调用Mapper


/**
 * 返回所有用户数据
 * @return
 */
@RequestMapping("/getAll")
public String getAll() {
	try {
		return JSON.toJSONString(userMapper.selectByExample(new UserExample()));
	} catch (Exception e) {
		// TODO: handle exception
		e.printStackTrace();
		return "Failed";
	}
}

/**
 * 更加用户名查找用户信息
 * @param username
 * @return
 */
@RequestMapping("/getUser")
public String getUser(String username) {
	UserExample userExample = new UserExample();
	userExample.createCriteria().andUsernameEqualTo(username);
	try {
		return JSON.toJSONString(userMapper.selectByExample(userExample));
	} catch (Exception e) {
		// TODO: handle exception
		e.printStackTrace();
		return "Failed";
	}
}

主类

记得在主类加上mapper扫包的注解

@SpringBootApplication
@MapperScan(basePackages = "com.jason.mapper")
public class MybatisDemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(MybatisDemoApplication.class, args);
	}
}

mapper接口

方法 功能说明
int countByExample(UserExample example) thorws SQLException 按条件计数
int deleteByPrimaryKey(Integer id) thorws SQLException 按主键删除
int deleteByExample(UserExample example) thorws SQLException 按条件删除
String/Integer insert(User record) thorws SQLException 插入数据(返回值为ID)
User selectByPrimaryKey(Integer id) thorws SQLException 按主键查询
List selectByExample(UserExample example) thorws SQLException 按条件查询
List selectByExampleWithBLOGs(UserExample example) thorws SQLException 按条件查询(包括BLOB字段)。只有当数据表中的字段类型有为二进制的才会产生。
int updateByPrimaryKey(User record) thorws SQLException 按主键更新
int updateByPrimaryKeySelective(User record) thorws SQLException 按主键更新值不为null的字段
int updateByExample(User record, UserExample example) thorws SQLException 按条件更新
int updateByExampleSelective(User record, UserExample example) thorws SQLException 按条件更新值不为null的字段

Example类

mybatis的逆向工程中会生成实例及实例对应的example,example用于添加条件,相当where后面的部分

xxxExample example = new xxxExample();

Criteria criteria = new Example().createCriteria();

方法 说明
example.setOrderByClause(“字段名 ASC”); 添加升序排列条件,DESC为降序
example.setDistinct(false) 去除重复,boolean型,true为选择不重复的记录。
criteria.andXxxIsNull 添加字段xxx为null的条件
criteria.andXxxIsNotNull 添加字段xxx不为null的条件
criteria.andXxxEqualTo(value) 添加xxx字段等于value条件
criteria.andXxxNotEqualTo(value) 添加xxx字段不等于value条件
criteria.andXxxGreaterThan(value) 添加xxx字段大于value条件
criteria.andXxxGreaterThanOrEqualTo(value) 添加xxx字段大于等于value条件
criteria.andXxxLessThan(value) 添加xxx字段小于value条件
criteria.andXxxLessThanOrEqualTo(value) 添加xxx字段小于等于value条件
criteria.andXxxIn(List<?>) 添加xxx字段值在List<?>条件
criteria.andXxxNotIn(List<?>) 添加xxx字段值不在List<?>条件
criteria.andXxxLike(“%”+value+”%”) 添加xxx字段值为value的模糊查询条件
criteria.andXxxNotLike(“%”+value+”%”) 添加xxx字段值不为value的模糊查询条件
criteria.andXxxBetween(value1,value2) 添加xxx字段值在value1和value2之间条件
criteria.andXxxNotBetween(value1,value2) 添加xxx字段值不在value1和value2之间条件

更多示例参考:https://blog.csdn.net/xiaozhenzi66/article/details/81117458


文章作者: 小小千千
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小小千千 !
评论
  目录