一、MyBatis Generator
MyBatis逆向工程是指可以根据数据库表的分析逆向生成Entity实体类、Mapper接口以及Mapper XML等类和XML文件,逆向工程会用到MyBatis官方提供的代码生成器即MyBatis Generator
1.1 工程搭建
新建项目mybatis-mbg-pagehelper,项目依赖与QA 由浅入深持久层框架(七)- MyBatis Cache中的mybatis-cache项目的依赖一致,这里不再重复。但是需要新增加如上所述的Mybatis Generator Core的依赖
<!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core --> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.4.0</version> </dependency> 复制代码
MyBatis Generator XML Configuration File 示例,拷贝内容放到resource目录下的generatorConfig.xml文件中。
主要修改
- 数据库连接信息配置
- 生成的Entity实体类位置配置
- 生成的Mapper XML文件存放位置配置
- 生成的Mapper接口位置配置
- 映射的Table配置
<?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> <!--Jar包路径,删除--> <!--<classPathEntry location="/Program Files/IBM/SQLLIB/java/db2java.zip" />--> <context id="test" targetRuntime="MyBatis3" > <!--修改数据库连接配置--> <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai" userId="root" password="root"> </jdbcConnection> <javaTypeResolver > <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!--生成Java Model即Entity实体类--> <javaModelGenerator targetPackage="com.citi.entity" targetProject="./src/main/java"> <property name="enableSubPackages" value="true" /> <property name="trimStrings" value="true" /> </javaModelGenerator> <!--SQL XML映射文件生成器--> <sqlMapGenerator targetPackage="mappers" targetProject="./src/main/resources"> <property name="enableSubPackages" value="true" /> </sqlMapGenerator> <!--生成Mapper接口--> <javaClientGenerator type="XMLMAPPER" targetPackage="com.citi.mapper" targetProject="./src/main/java"> <property name="enableSubPackages" value="true" /> </javaClientGenerator> <!--生成器所用到的表,配置生成的实体类名--> <table schema="test" tableName="t_cat" domainObjectName="Cat" > <!--<property name="useActualColumnNames" value="true"/>--> <!--<generatedKey column="ID" sqlStatement="DB2" identity="true" />--> <!--<columnOverride column="DATE_FIELD" property="startDate" />--> <!--<ignoreColumn column="FRED" />--> <!--<columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" />--> </table> <table schema="test" tableName="t_employee" domainObjectName="Employee" > </table> <table schema="test" tableName="t_teacher" domainObjectName="Teacher" > </table> </context> </generatorConfiguration> 复制代码
运行方式主要有三种,第一种是通过命令行的方式生成代码
java -jar mybatis-generator-core-x.x.x.jar -configfile \temp\generatorConfig.xml -overwrite 复制代码
第二种方式是在test包下新增测试代码,通过执行Java代码生成代码
public class MyBatisGenerator { 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); System.out.println("代码生成器运行结束"); } } 复制代码
第三种方式是通过通过Maven插件的方式生成代码,在pom.xml中增加build配置
<build> <finalName>mybatis-mbg-pagehelper</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.4.0</version> <configuration> <!--是否覆盖原有代码--> <overwrite>true</overwrite> <verbose>true</verbose> </configuration> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency> </dependencies> </plugin> </plugins> </build> 复制代码
打开右侧侧边栏的Maven目录下的Plugins,多出一个mybatis-generator插件
双击该插件即可生成代码
控制台输出BUILD SUCCESS,说明已经成功生成了Mapper接口、Mapper映射文件以及Entity实体类代码
可以看出entity包中除了实体类还有XXXEXample类,这是用来封装查询条件的实体类,MyBatis除了生成简单的CRUD代码,还生成了复杂查询的代码,mapper包中的Mapper接口封装复杂查询的方法,mappers目录下的Mapper XML文件中也实现了复杂查询的SQL语句。
当然,MyBatis也支持生成只有简单的CRUD代码,只需要讲generatorConfig.xml文件中context标签的属性更改一下就可以
<context id="test" targetRuntime="MyBatis3Simple" > <!--中间内容无变化--> </context> 复制代码
在context标签增加新的标签,去除自动生成的注释
<commentGenerator> <!-- 是否去除自动生成的注释 true:是 : false:否 --> <property name="suppressAllComments" value="true"/> </commentGenerator> 复制代码
1.2 测试
在test包下新建TeacherMapperTest类
public class TeacherMapperTest { SqlSessionFactory sqlSessionFactory = null; SqlSession openSession = null; @Before public void setUp() throws Exception { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); openSession = sqlSessionFactory.openSession(); } @After public void tearDown(){ openSession.close(); } @Test public void selectByExample() { TeacherMapper teacherMapper = openSession.getMapper(TeacherMapper.class); TeacherExample example = new TeacherExample(); example.setOrderByClause("id DESC"); TeacherExample.Criteria criteria = example.createCriteria(); criteria.andClassNameLike("三年%"); List<Teacher> teachers = teacherMapper.selectByExample(example); for (Teacher teacher : teachers) { System.out.println(teacher.getId()); } } } 复制代码
TeacherExample是用来构造查询条件的实体类,可以用来设置SQL语句中的order by、distinct、or等关键字。 而where后面的查询条件如:class_name like '%三年%'或者 id between 2,3 或者大于小于等都需要通过TeacherExample调用createCriteria()方法生成一个Criteria类, 然后设置查询条件
执行该测试方法
控制它打印出的SQL语句,实现了条件查询
二、PageHelper
快速进行分页的插件
1. 引入分页插件
在 pom.xml 中添加如下依赖:
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.3.0</version> </dependency> 复制代码
2. 配置拦截器插件
1. 在 MyBatis 配置 xml 中配置拦截器插件
<!-- plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下: properties?, settings?, typeAliases?, typeHandlers?, objectFactory?,objectWrapperFactory?, plugins?, environments?, databaseIdProvider?, mappers? --> <plugins> <!-- com.github.pagehelper为PageHelper类所在包名 --> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 --> <property name="param1" value="value1"/> </plugin> </plugins> 复制代码
TeacherMapper中新增方法insertBatch,批量插入数据用于分页
int insertBatch(@Param("teacherList") List<Teacher> teacherList); 复制代码
在TeacherMapper.xml中增加SQL 映射语句
<insert id="insertBatch"> INSERT INTO t_teacher(teacher_name, class_name, address, birth_date) VALUES <foreach collection="teacherList" separator="," item="teacher"> (#{teacher.teacherName}, #{teacher.className}, #{teacher.address}, #{teacher.birthDate}) </foreach> </insert> 复制代码
在TeacherMapperTest中增加测试方法
@Test public void insertBatch(){ TeacherMapper teacherMapper = openSession.getMapper(TeacherMapper.class); List<Teacher> teacherList = new ArrayList<>(); for (int i = 0; i < 51; i++) { Teacher teacher = new Teacher(); teacher.setTeacherName("Mark " + i); teacher.setClassName("三年" + i+ "班"); teacher.setAddress("New York"); teacher.setBirthDate(new Date()); teacherList.add(teacher); } teacherMapper.insertBatch(teacherList); openSession.commit(); } 复制代码
执行该测试,往数据库中插入50条数据
TeacherMapper接口中新增方法,获取所有的Teacher,对查询结果使用分页
List<Teacher> getAllTeachers(); 复制代码
在TeacherMapper.xml中增加SQL映射
<select id="getAllTeachers" resultType="com.citi.entity.Teacher"> select * from t_teacher </select> 复制代码
在test包下的TeacherMapperTest中增加测试方法
@Test public void getAllTeachers(){ TeacherMapper teacherMapper = openSession.getMapper(TeacherMapper.class); // 紧跟着PageHelp的查询是分页查询,其他的就是查询全部 PageHelper.startPage(4,5); List<Teacher> teacherList = teacherMapper.getAllTeachers(); // 将查询的结果使用pageInfo封装 PageInfo<Teacher> pageInfo = new PageInfo<>(teacherList); System.out.println("当前页码为:" + pageInfo.getPageNum()); System.out.println("总页码数:" + pageInfo.getPages()); System.out.println("总记录数:" + pageInfo.getTotal()); System.out.println("当前页面记录数:" + pageInfo.getSize()); System.out.println("上一页:" + pageInfo.getPrePage()); System.out.println("下一页:" + pageInfo.getNextPage()); } 复制代码
执行测试
控制台成功输出分页相关的信息