springboot 中使用Mybatis Generator

1 为什么要使用Mybatis Generator

虽然MyBatis是一个简单易学的框架,但是配置XML文件也是一件相当繁琐的一个过程,而且会出现很多不容易定位的错误。当在工作中需要生成大量对象的时候,有太多的重复劳动,简直是生无可恋。所以,官方开发了 MyBatis Generator。它只需要很少量的简单配置,就可以完成大量的表到Java对象的生成工作,拥有零出错和速度快的优点,让开发人员解放出来更专注于业务逻辑的开发。

2  说明

  MyBatis Generator 生成的文件包含三类

1 Model实体文件 一个数据库表生成一个model实体

2 Mapper 接口文件, 数据操作方法都在此接口中定义

3 Mapper xml配置文件

3 配置

 1 首先在pom.xml文件中引入mbg的依赖

<dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.3</version>
        </dependency>

2 创建generator.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="generator.properties"/>
    <context id="MySqlContext" targetRuntime="MyBatis3" defaultModelType="flat">
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>
        <property name="javaFileEncoding" value="UTF-8"/>
        <!-- 为模型生成序列化方法-->
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
        <!-- 为生成的Java模型创建一个toString方法 -->
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
        <!--可以自定义生成model的代码注释-->
        <commentGenerator type="com.macro.mall.tiny.mbg.CommentGenerator">
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="true"/>
            <property name="suppressDate" value="true"/>
            <property name="addRemarkComments" value="true"/>
        </commentGenerator>
        <!--配置数据库连接-->
        <jdbcConnection driverClass="${jdbc.driverClass}"
                        connectionURL="${jdbc.connectionURL}"
                        userId="${jdbc.userId}"
                        password="${jdbc.password}">
            <!--解决mysql驱动升级到8.0后不生成指定数据库代码的问题-->
            <property name="nullCatalogMeansCurrent" value="true" />
        </jdbcConnection>
        <!--指定生成model的路径-->
        <javaModelGenerator targetPackage="com.macro.mall.tiny.mbg.model" targetProject="D:\testforgenerator\src\main\java"/>
        <!--指定生成mapper.xml的路径-->
        <sqlMapGenerator targetPackage="com.macro.mall.tiny.mbg.mapper" targetProject="D:\testforgenerator\src\main\resources"/>
        <!--指定生成mapper接口的的路径-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.macro.mall.tiny.mbg.mapper"
                             targetProject="D:\testforgenerator\src\main\java"/>
        <!--生成全部表tableName设为%-->
        <table tableName="pms_brand">
            <generatedKey column="id" sqlStatement="MySql" identity="true"/>
        </table>
        <!--后台用户表-->
        <table tableName="ums_admin">
            <generatedKey column="id" sqlStatement="MySql" identity="true"/>
        </table>
        <!--后台用户角色表-->
        <table tableName="ums_role">
            <generatedKey column="id" sqlStatement="MySql" identity="true"/>
        </table>
        <!--后台用户权限表-->
        <table tableName="ums_permission">
            <generatedKey column="id" sqlStatement="MySql" identity="true"/>
        </table>
        <table tableName="ums_admin_role_relation">
            <generatedKey column="id" sqlStatement="MySql" identity="true"/>
        </table>
        <table tableName="ums_role_permission_relation">
            <generatedKey column="id" sqlStatement="MySql" identity="true"/>
        </table>
        <table tableName="ums_admin_permission_relation">
            <generatedKey column="id" sqlStatement="MySql" identity="true"/>
        </table>
    </context>
</generatorConfiguration>

详细分析:

<?xml version="1.0" encoding="UTF-8"?>

 这里xml版本为 1.0  字符集编码为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="generator.properties"/>   这个表示了使用了资源的路径,就可以直接使用其中的路径
例如这种

   <jdbcConnection driverClass="${jdbc.driverClass}"
                        connectionURL="${jdbc.connectionURL}"
                        userId="${jdbc.userId}"
                        password="${jdbc.password}">
            <!--解决mysql驱动升级到8.0后不生成指定数据库代码的问题-->
            <property name="nullCatalogMeansCurrent" value="true" />
        </jdbcConnection>
		
<!--指定生成model的路径-->
<javaModelGenerator targetPackage="com.macro.mall.tiny.mbg.model" targetPackage="D:\mall-tiny-01\src\main\java"/>
    <!--指定生成mapper.xml的路径-->
        <sqlMapGenerator targetPackage="com.macro.mall.tiny.mbg.mapper" targetProject="D:\mall-tiny-01\src\main\resources"/>

  注意如果在本地环境使用generator.xml文件需要修改对应生成的model mapper.xml 的路径

generatorConfig.xml中 1 targetRuntime属性指定生成的代码运行的环境 有两个选项

Mybatis3和Mybatis3Simple,而Mybatis3Simple不会生成Example相关方法

2 defaultModel 属性定义了如何生成实体类,有三个选项

conditional flat hierarchical

conditional 如果表中得主键只有一个字段,那么将该字段合并到基本实体类中

flat 为每张表生成一个实体类

hierarchical 是如果表中存在主键 就会单独生成一个主键实体类

3 property 标签,该标签是context的子标签,该标签可以配置数据库的分隔符和java文件编码,在该例子中主要使用它的前后分割符属性,因为mysql中分隔符是‘ 所以将其其前后分隔符都设置为'

4 commentGenerator 标签 该标签是context子标签 用来配置如何生成注释信息,最多可以配置一个.该标签有一个可选择的属性type

可以指定用户自己创建的注释生成类。提供了3个可选的属性 supperAllComments supperessData AddReamarkComments 分别用来阻止生成注释 阻止生成的注释包含的是时间戳,注释是否添加数据库表中得备注信息

 

 

5 jdbcConnection 标签 该标签配置了连接的数据库信息

6 javaModelGenerator 标签 该标签用来控制生成的实体类 ,必须配置一个。该标签有两个必选属性 targetPackeage 和 targetProject 前置用来存放实体类的包名,后者用来指定项目路径 (因为可能一个工程下会有许多子项目)

7 sqlMapGenerator 标签 该标签用来配置sql映射生成器(Mapper.xml) 的属性。其两个必选属性与javaModeGenerator 标签的两个必须属性一致

 

8 javaClientGenerator 标签,该标签用于配置Mapper接口的属性,如果不设置该标签,就不会生成Mapper接口。其中两个必选的属性与两个标签一致,还有一个type属性用来设置mapper接口的生成器

9 table标签 该标签很重要 ,用来配置需要通过内省数据库表,只有在该标签中配置,才能生成最终的代码,至少要配置一个,该标签只有一个必选的属性就是tablename要指定生成的表名,可以匹配多个表,如果要生成全部的表的话,可以使用% 进行配置。

 

 

 

 

3 创建 generator.java类

List<String>  warnings =new ArrayList<String>();
    //MBG 执行过程中产生的警告信息
	boolean overwrite =new ArrayList<String>();
	//当生成重复的代码的时候覆盖原来的代码
	InputStream is=Generatorc.class.getResourceAsStream("/generatorComnfig.xml");
	 //读取xml文件中得配置
	 
	 ConfigurationParset cp=new ConfigurationParset(warnings);
	 Configuration config=cp.pareseConfiguration(is);
	 is.close();
	 
	 DefaultShellCallback callback=new DefaultShellCallback(overwrite);
	 MyBatisGenerator mybatisGenerator=new MyBatisGenerator(config,callback,warnings);
	 //执行生成的代码
	 mybatisGenerator.generator(null);
	 //输出警告的信息
	 for(String warnings:warnings)
	 {
	    System.out.println(warnings);
	 }
	

4 生成的效果:

5  生成的 分析

   model下会生成两类文件,一种是xxx(表名) 另一种是xxxexample(查询对象) ,第一种是表名对应的实体类,第二种对应的是查询条件,这个类是专门试用来这张表的查询的类,对该表的curd操作是脱离sql性质的(已经通过逆向工程生成对应的sql) ,直接在service就可以完成对应的操作,包含了一个static 的内部类Criteria ,在Criteria中有许多方法,主要是定义了sql语句中where后的查询条件。
     xxx 就是简单的按照主键的和内容的操作,而xxxexample是更加复杂的where条件形式和整体数据的操作
 
 
 

                                                                                                                                    这里使用User 为表名

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

插入数据(数据从这个

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的字段

                         

mybatis通过逆向工程来生成example类,example用于添加条件,这就相当于where条件后面的

             xxxExample example=new XXXExample();

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

Example.setOrderByClause("字段名 asc")

添加了升序排列条件,Desc为降序

Example.setDistinct(false)

去除重复,其中参数为boolean类型,true为选择不重复的记录

Criteria.andXXXIsnull

添加字段xxx为空的条件

Criteria.andXXXIsnotnull

添加字段为不为空的条件

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<?>中得条件

Creteria.andxxxNotin(List<?>)

添加xxx字段值不在List<?>中得条件

Criteria.andxxxLike("%"+value+"%")

添加xxx字段值为value的模糊查询条件

Criteria.andxxxNotLike("%"+value+"%")

添加xxx字段值不为value的模糊查询

Criteria.andxxxbetween(value,value2)

添加xxx字段值在value与value2之间的条件

Criteria.andxxxNotbetween(value1,value2)

添加字段值不在value1与value2之间的条件

 

 

 

     1 使用实例

       
        查询数据
          
	package com.macro.mall.tiny.mbg.controller;
	
	import com.macro.mall.tiny.mbg.mapper.PmsBrandMapper;
	import com.macro.mall.tiny.mbg.model.PmsBrand;
	import com.macro.mall.tiny.mbg.model.PmsBrandExample;
	import org.junit.Test;
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.stereotype.Controller;
	import org.springframework.web.bind.annotation.RequestBody;
	import org.springframework.web.bind.annotation.RequestMapping;
	import org.springframework.web.bind.annotation.ResponseBody;
	
	import java.util.List;
	
	@Controller
	public class testController {
	    @Autowired
	    private PmsBrandMapper brandMapper;
	
	    @ResponseBody
	    @Test
	    @RequestMapping(value = "findtest")
	    public void  testFind()
	    {
	        //其中example用于复合查询  ,其中example 是处理整体的操作的order distinct,criteria处理对单个字符的操作。比如equalto 等操作
	        PmsBrandExample pmsBrandExample=new PmsBrandExample();
	        //获取Criteria  使用 定义字段的条件
	        PmsBrandExample.Criteria  criteria=pmsBrandExample.createCriteria();
	        //设置id=6的where条件
	        criteria.andIdEqualTo((long) 6);
	        //设置order by id desc
	         pmsBrandExample.setOrderByClause("id desc");
	         //将条件绑定到mapper对象中 执行查询
	        List<?> list = brandMapper.selectByExample(pmsBrandExample);
	        for (int i = 0; i < list.size(); i++) {
	            System.out.println(list.get(i));
	        }
	    }
}

   2 添加数据

	@ResponseBody
	    @Test
	    @RequestMapping("/inserdata")
	    public String insertdata()
	    {
	        PmsBrand pmsBrand=new PmsBrand();
	        pmsBrand.setName("demo");
	       int status= brandMapper.insert(pmsBrand);
	       long id= pmsBrand.getId();
	       return "新增数据的id"+id;
	
	    }

 

3  更新数据 

	更新数据
	//注意这里其他的字段值并没有设置值,导致将数据库中的值更新为空
	@ResponseBody
	    @RequestMapping("/updatedata")
	    public String  updatedata()
	    {
	        //创建一个实体对象
	        PmsBrand pmsBrand=new PmsBrand();
	        pmsBrand.setName("demoupdate");
	        pmsBrand.setId((long)60);
	        pmsBrand.setLogo("asdad");
	        int status= brandMapper.updateByPrimaryKey(pmsBrand);
	        if(status==1)
	        {
	            return "更新成功";
	
	        }
	        else
	        {
	            return "更新失败"+status;
	        }
	    }
	 

注意这里的更新会将整个bean对象的内容更新到数据库,有可能会把数据库中存在的值更新为null

 4     updateByPrimaryKeySelective  这里更新只会更新存在值的

 @Test
	    @ResponseBody
	    @RequestMapping("/updateByPrimaryKeySelective")
	    public String updateByPrimaryKeySelective()
	    {
	
	        //这时候更新数据库中的firstletter并不会被更新为空
	        PmsBrand pmsBrand=new PmsBrand();
	        pmsBrand.setName("demoisnotnull");
	        pmsBrand.setId((long)60);
	        int status=brandMapper.updateByPrimaryKeySelective(pmsBrand);
	        return  "updateByPrimaryKeySelective更新"+(status==1? "成功":"失败");
	
    }

 

 5  updateByExample

@Test
	    @ResponseBody
	    @RequestMapping("updateByExample")
	    public String updateByExample()
	    {
	        /*
	        如果实体类没有设置值的话,会将数据库中对应的字段设置为空
	         */
	        PmsBrand pmsBrand=new PmsBrand();
	        pmsBrand.setName("demoExample");
	        pmsBrand.setId((long)60);
	        pmsBrand.setLogo("wwwwwww");
	        PmsBrandExample pmsBrandExample=new PmsBrandExample();
	
	        PmsBrandExample.Criteria criteria=pmsBrandExample.createCriteria();
	        criteria.andIdEqualTo((long)60);
	        int status=brandMapper.updateByExample(pmsBrand,pmsBrandExample);
	        return  "updateByExample更新"+(status==1? "成功":"失败");
	
	    }

    6 updateByExampleSelective

 @Test
	    @ResponseBody
	    @RequestMapping("updateByExampleSelective")
	    public String updateByExampleSelective()
	    {
	
	        /*
	        这里指挥更新实体类中不为空的字段数据
	         */
	        PmsBrand pmsBrand=new PmsBrand();
	        pmsBrand.setId((long)60);
	        pmsBrand.setFirstLetter("123131");
	        PmsBrandExample pmsBrandExample=new PmsBrandExample();
	        PmsBrandExample.Criteria criteria=pmsBrandExample.createCriteria();
	        criteria.andIdEqualTo((long)60);
	        int status=brandMapper.updateByExampleSelective(pmsBrand,pmsBrandExample);
	        return  "updateByExample更新"+(status==1? "成功":"失败");
	    }

   7  deleteByPrimaryKey

	    /*
	        以主键的方式 来删除对应的数据
	     */
	    @Test
	    @ResponseBody
	    @RequestMapping("deleteByPrimaryKey")
	    public String deleteByPrimaryKey()
	    {
	        int status=brandMapper.deleteByPrimaryKey((long)59);
	        return  "deleteByPrimaryKey删除"+(status==1? "成功":"失败");
	    }
	
	
	    @ResponseBody
	    @RequestMapping("/deleteByExample")
	    public String deleteByExample()
	    {
	        PmsBrandExample pmsBrandExample=new PmsBrandExample();
	        PmsBrandExample.Criteria criteria=pmsBrandExample.createCriteria();
	        criteria.andIdEqualTo((long)61);
	        int status=brandMapper.deleteByExample(pmsBrandExample);
	        return  "deleteByExample删除"+(status==1? "成功":"失败");
    }

     8   countByExample

  

	    @Test
	    @ResponseBody
	    @RequestMapping("countByExample")
	    public String countByExample()
	    {
	        PmsBrandExample pmsBrandExample=new PmsBrandExample();
	        PmsBrandExample.Criteria criteria=pmsBrandExample.createCriteria();
	        criteria.andShowStatusEqualTo(1);
	        int count=brandMapper.countByExample(pmsBrandExample);
	        return  "总数为"+(count);
	    }

 

4 问题汇总

     1 提示

	1    提示
	Field brandMapper in com.macro.mall.tiny.mbg.controller.testController required a bean of type 'com.macro.mall.tiny.mbg.mapper.PmsBrandMapper' that could not be found.
	
	The injection point has the following annotations:
		- @org.springframework.beans.factory.annotation.Autowired(required=true)
	
	
	Action:
	
	Consider defining a bean of type 'com.macro.mall.tiny.mbg.mapper.PmsBrandMapper' in your configuration.

 

解决

这种从字面意思上看是由于testController使用了PmsBrandMapper 并且使用了自动装配@Autowired ,但是并没有在容器汇总找到这种类型的

 

 2  提示

	Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

    问题:  大概意思就是 说没有找到是视图名

     

  解决办法:

 1 请求方法上加注解:@ResponseBody,无需模板文件   

 2

用thymeleaf模板

<!--thymeleaf 模板引擎--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>

 

 

 

 

这里参考了别人写的博客

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值