MBG与Example
GitHub - mybatis/generator: A code generator for MyBatis.
我们在项目中使用Mybatis的时候,针对需要操作的一张表,需要创建实体类、Mapper映射器、Mapper接口,里面又有很多的字段和方法的配置,这部分的工作是非常频繁的。而大部分时候我们对于表的基本操作都是相同的,比如根据主键查询、根据Map查询、单条插入、批量插入、根据主键删除等等等等。当我们的表很多的时候,意味着有大量的重复工作。
所以有没有一种办法,可以根据我们的表,自动生成实体类、Mapper映射器、Mapper接口、里面包含了我们需要用到的这些基本方法和SQL呢。
Mybatis也提供了一个代码生成器,叫做Mybatis Generator,建成MBG,是mybatis的一个插件。我们只需要修改一个配置文件,使用相关的jar包命令或者java代码就可以帮助我们生成实体类、映射器和接口文件。
MBG的配置文件里面有一个Example的开关,这个东西用来构造复杂的筛选条件的,换句话说就是根据我们的代码去生成where条件。
原理:在实体类中包含了两个继承关系的Criteria,用其中自动生成的方法来构建查询条件。把这个包含了Criteria的实体类作为参数传到查询参数中,在解析Mapper映射器的时候会转换成SQL条件。
添加配置文件
我们添加如下的配置文件
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration><!-- 数据库的驱动包路径 --><classPathEntry location="C:\Users\dpb\.m2\repository\mysql\mysql- connectorjava\8.0.11\mysql-connector-java-8.0.11.jar" /><context id="DB2Tables" targetRuntime="MyBatis3"><!-- 去掉生成文件中的注释 --><commentGenerator><property name="suppressAllComments" value="true" /></commentGenerator><!-- 数据库链接URL、用户名、密码 --><jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/mybatisdb?
characterEncoding=utf-8&serverTimezone=UTC"userId="root"password="123456"><property name="nullCatalogMeansCurrent" value="true" /></jdbcConnection><!-- <jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver"connectionURL="jdbc:oracle:thin:@localhost:1521:XE"userId="car"password="car"></jdbcConnection> --><javaTypeResolver ><property name="forceBigDecimals" value="false" /></javaTypeResolver><!-- 生成模型的包名和位置 --><javaModelGenerator targetPackage="com.gupaoedu.vip.domain" targetProject="./src/main/java"><!-- 是否在当前路径下新加一层schema,eg:fase路径com.oop.eksp.user.model,true:com.oop.eksp.user.model.[schemaName] --><property name="enableSubPackages" value="false" /><property name="trimStrings" value="true" /></javaModelGenerator><!-- 生成的映射文件包名和位置 --><sqlMapGenerator targetPackage="com.gupaoedu.vip.mapper" targetProject="./src/main/java"><property name="enableSubPackages" value="false" /></sqlMapGenerator><!-- 生成DAO的包名和位置 --><javaClientGenerator type="XMLMAPPER" targetPackage="com.gupaoedu.vip.mapper" targetProject="./src/main/java"><property name="enableSubPackages" value="false" /></javaClientGenerator><table tableName="t_user" domainObjectName="User" /></context>
</generatorConfiguration>
添加插件
我们需要在pom.xml中添加对应的插件
<build><plugins><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.2</version><configuration><!-- 指定配置文件的位置 --><configurationFile>src/main/resources/generatorConfig.xml</configurationFile></configuration></plugin></plugins>
</build>
生成
然后我们就可以利用插件帮助我们快速生成我们需要的表结构对应的相关文件
通用Mapper
问题:当我们的表字段发生变化的时候,我们需要修改实体类和Mapper文件定义的字段和方法。如 果是增量维护,那么一个个文件去修改。如果是全量替换,我们还要去对比用MBG生成的文件。字段变动一次就要修改一次,维护起来非常麻烦。
方式一
第一个,因为MyBatis的Mapper是支持继承的(见:https://github.com/mybatis/mybatis-3/issue s/35)。所以我们可以把我们的Mapper.xml和Mapper接口都分成两个文件。一个是MBG生成的,这部 分是固定不变的。然后创建DAO类继承生成的接口,变化的部分就在DAO里面维护。
public interface UserMapperExt extends UserMapper {public List<User> selectUserByName(String userName);
}
对应的映射文件
<?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.gupaoedu.vip.mapper.UserMapperExt" ><resultMap id="BaseResultMapExt" type="com.gupaoedu.vip.domain.User" ><id column="id" property="id" jdbcType="INTEGER" /><result column="user_name" property="userName" jdbcType="VARCHAR" /><result column="real_name" property="realName" jdbcType="VARCHAR" /><result column="password" property="password" jdbcType="VARCHAR" /><result column="age" property="age" jdbcType="INTEGER" /><result column="d_id" property="dId" jdbcType="INTEGER" /><result column="i_id" property="iId" jdbcType="INTEGER" /></resultMap><select id="selectUserByName" resultMap="BaseResultMapExt" >select * from t_user where user_name = #{userName}</select>
</mapper>
在全局配置文件中我们也需要扫描
<mappers><mapper resource="mapper/UserMapper.xml"/><mapper resource="mapper/UserMapperExt.xml"/>
</mappers>
所以以后只要修改Ext的文件就可以了。这么做有一个缺点,就是文件会增多。
方式二
既然针对每张表生成的基本方法都是一样的,也就是公共的方法部分代码都是一样的,我们能不能把 这部分合并成一个文件,让它支持泛型呢? 当然可以!
编写一个支持泛型的通用接口,比如叫GPBaseMapper,把实体类作为参数传入。这个接口里面定义 了大量的增删改查的基础方法,这些方法都是支持泛型的。 自定义的Mapper接口继承该通用接口,例如BlogMapper extends GPBaseMapper,自动获得对实 体类的操作方法。遇到没有的方法,我们依然可以在我们自己的Mapper里面编写。
我们能想到的解决方案,早就有人做了这个事了,这个东西就叫做通用Mapper。
https://github.com/abel533/Mapper/wiki
用途:主要解决单表的增删改查问题,并不适用于多表关联查询的场景。
除了配置文件变动的问题之外,通用Mapper还可以解决:
- 每个Mapper接口中大量的重复方法的定义;
- 屏蔽数据库的差异;
- 提供批量操作的方法;
- 实现分页。
使用方式:在Spring中使用时,引入jar包,替换applicationContext.xml中的sqlSessionFactory和configure。
<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.gupaoedu.crud.dao"/>
</bean>