43. Mybatis3 - 动态 SQL, 批量操作, 一级缓存, 二级缓存, 第三方缓存, 逆向工程

动态 SQL

if

<if test=""></if> 通过 test 表达式,拼接 SQL语句。

EmpMapper 接口类中新建 getEmpListByMultipleCondition 方法,该方法用于执行多条件查询。

1
2
3
4
5
6
7
8
9
10
11
package com.atguigu.mapper;

import java.util.List;

import com.atguigu.bean.Emp;

public interface EmpMapper {

// 根据 eid, ename, age, sex 多条件查询员工信息
List<Emp> getEmpListByMultipleCondition(Emp emp);
}

EmpMapper.xml 映射文件中新增 if 标签,用于判断值是否为null 或者为空字符串。进行 SQL 的拼接。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?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.atguigu.mapper.EmpMapper">
<!--List<Emp> getEmpListByMultipleCondition();-->
<select id="getEmpListByMultipleCondition" resultType="Emp">
select eid, ename, age, sex, did from emp
where 1=1
<if test="eid != null">
and eid = #{eid}
</if>
<if test="ename != null and ename!=''">
and ename = #{ename}
</if>
<if test="age != null">
and age = #{age}
</if>
<if test="sex == 1 or sex == 0">
and sex = #{sex}
</if>
</select>
</mapper>

注意⚠️:上面加上 where 1=1 的目的是防止后面条件所有为空(也就是一个条件也没有)或者其他情况下导致 SQL 的拼接不完成。

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.atguigu.test;

import static org.junit.Assert.*;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import com.atguigu.bean.Emp;
import com.atguigu.mapper.EmpMapper;

public class TestSQL {

@Test
public void testIf() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession(true);
EmpMapper mapper = openSession.getMapper(EmpMapper.class);

// 查询 名称为 zhangsansan,age 为 33 的信息
Emp emp = new Emp();
emp.setEname("zhangsansan");
emp.setAge(33);

List<Emp> emps = mapper.getEmpListByMultipleCondition(emp);
System.out.println(emps);
}

public SqlSessionFactory getSqlSessionFactory() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-conf.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
return sqlSessionFactory;
}
}

where

where 标签的作用是添加 where 关键字,并且解决条件中第一个 and 或者 or 的问题。上面 if 中,我们为不让 SQL 条件拼接出错,我们在 SQL 中 where 的后面添加了 1=1 的恒等式,且不影响 SQL 的查询结果。除了上面在 where 后面添加 1=1 外,我们还可以用 where 标签来实现,他会帮我们解决第一个多的 and。(例如下面 eid != null 时,SQL 的拼接会在 where 后面多一个 and,这个 and where 标签就会帮我们自动去掉。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?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.atguigu.mapper.EmpMapper">
<!--List<Emp> getEmpListByMultipleCondition();-->
<select id="getEmpListByMultipleCondition" resultType="Emp">
select eid, ename, age, sex, did from emp
<where>
<if test="eid != null">
and eid = #{eid}
</if>
<if test="ename != null and ename!=''">
and ename = #{ename}
</if>
<if test="age != null">
and age = #{age}
</if>
<if test="sex == 1 or sex == 0">
and sex = #{sex}
</if>
</where>
</select>
</mapper>

trim

trim 可以在条件判断完的SQL语句前后 添加或者去掉指定的字符, prefix: 添加前缀,prefixOverrides: 去掉前缀suffix: 添加后缀,suffixOverrides: 去掉后缀。

例如下面的情况下,可能会在最后多出一个 or 或者 and 导致 SQL 语法错误,且前面差一个 where,所以可以使用 trim 标签在 prefix 中写入 where,suffixOverrides 写入 and|or。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<select id="getEmpListByMultipleCondition2" resultType="Emp">
select eid, ename, age, sex, did from emp
<trim prefix="where" suffixOverrides="and|or">
<if test="eid != null">
eid = #{eid} and
</if>
<if test="ename != null and ename!=''">
ename = #{ename} and
</if>
<if test="age != null">
age = #{age} or
</if>
<if test="sex == 1 or sex == 0">
sex = #{sex}
</if>
</trim>
</select>

set

set 的作用是添加 set 标签,并且解决修改操作中SQL语句中可能多出逗号的问题。(用得较少,因为 trim 也解决逗号多余的问题)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<update id="updateEmpByMutipleCondition">
update emp
<set>
<if test="ename != null and ename!=''">
ename=#{ename},
</if>
<if test="age != null">
age = #{age},
</if>
<if test="sex == 1 or sex == 0">
sex = #{sex}
</if>
</set>
where eid = #{eid}
</update>

choose

choose 主要是用于分支判断,类似于 if…else if …结构。只会满足所有分支中的一个,如果 when 中都不满足,还可以设置 otherwise。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- List<Emp> getEmpListByChoose(Emp emp); -->
<select id="getEmpListByChoose" resultType="Emp">
select eid, ename, age, sex from emp
where
<choose>
<when test="eid != null">
eid=#{eid}
</when>
<when test="ename != null and ename!=''">
ename=#{ename}
</when>
<when test="age != null">
age=#{age}
</when>
<otherwise>
sex = #{sex}
</otherwise>
</choose>
</select>

或者在插入数据的时候,对某些值进行判断转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- void insertEmp(Emp emp); -->
<insert id="insertEmp">
insert into emp values(
null,
#{ename},
#{age},
<choose>
<when test="sex == 0">
'nv',
</when>
<when test="sex == 1">
'nan',
</when>
<otherwise>
'unknow',
</otherwise>
</choose>
#{did}
)
</insert>
1
2
// 添加员工信息,将传入的员工性别 0,转换为 女,1 转化为 男
void insertEmp(Map<String, Object> emp);
1
2
3
4
5
6
HashMap<String,Object> hashMap = new HashMap<>();
hashMap.put("age", 90);
hashMap.put("sex", "0");
hashMap.put("ename", "aa");
hashMap.put("did", 9);
mapper.insertEmp(hashMap);

因为在 emp 表中 did 是部门 id,而在实体类中的表现方式是 dept 的实体类属性,所以我们在设计 insertEmp 方法的时候就最好不要传入 Emp 对象。因为 Emp 实体里面不是 did 属性,而是 dept 类型信息。所以这里采用传入 一个 Map 的方式更好些。

foreach

批量删除方式1

这里不实用 foreach 进行批量删除,采用将要删除的 id 进行用 ,进行拼接。

1
2
// 删除多个 Emp 信息,传入多个 eid,并使用 , 进行拼接
void deleteMutipleEmp(String eids);
1
2
3
4
<!-- void deleteMutipleEmp(String eids); -->
<delete id="deleteMutipleEmp">
delete from emp where eid in (${value})
</delete>

注意⚠️:因为这里传入的参数只有一个,且是批量删除,所以不能使用 #{} 来获取值,要改为 ${} , ${} 在一个参数的情况下只支持 ${value}${_parameter} 两种写法。

测试删除

1
2
String eids = "1,3,4";
mapper.deleteMutipleEmp(eids);
批量删除方式2

使用 foreach 实现批量删除。foreach 标签的作用就是对一个数组或者集合进行遍历。这种情况下就不用担心 #{}${} 的区别,因为不是直接将传递进来的参数进行赋值,而是使用 foreach 进行了拼接。

foreach 形式如下:

1
2
3
<foreach collection="" close="" index="" item="" open="" separator="">
...
</foreach>

collection: 用于指定要遍历的集合或者数组。
item: 当前从集合中迭代出的元素。
close: 结束字符。
open: 开始字符。
separator: 用于设置每次循环之间的分隔符。即元素与元素之间的分隔符
若遍历的是 List 集合 index 代表索引下标,若遍历的是 map 集合,则 index 代表当前元素的 key。

EmpMapper 接口种方法如下:

1
2
// 删除多个 Emp 信息
void deleteMutipleEmpByList(List<Integer> eids);

EmpMapper.xml 种配置如下:

1
2
3
4
5
6
7
8
9
<!-- void deleteMutipleEmpByList(List<Integer> eids); -->
<delete id="deleteMutipleEmpByList">
delete from emp where eid in
(
<foreach collection="list" item="eid" separator=",">
#{eid}
</foreach>
)
</delete>

注意⚠️:因为接口方法 deleteMutipleEmpByList 中传递的参数是一个 list,MyBatis 会将 List 或 Array 放在 map 中,List 以 list 为键,Array 以 array 为键。所以这里 collection 中使用 list 才能取到传递过来的值。item 是每次迭代出的元素,separator 是每次迭代元素与元素之间的分隔符。

或者上面的 EmpMapper.xml 可以改写成这样,设置 close 结束字符和 open 开始字符。

1
2
3
4
5
6
<delete id="deleteMutipleEmpByList">
delete from emp where eid in
<foreach collection="list" item="eid" separator="," open="(" close=")">
#{eid}
</foreach>
</delete>
批量删除方式3

第三种方式与上面两种相比,就是 SQL 语句不一样而已。上面的 SQL 语句是 delete from emp where eid in () 的方式,但批量删除其实还可以这样写 delete from emp where eid=1 or eid=2 or eid=3。这样的话,xml 中 SQL 拼接方式如下:

1
2
3
4
5
6
7
<!-- void deleteMutipleEmpByList(List<Integer> eids); -->
<delete id="deleteMutipleEmpByList">
delete from emp where
<foreach collection="list" item="eid" separator="or">
eid = #{eid}
</foreach>
</delete>

SQL

设置一个 SQL 片段,即公共的 SQL,可以被当前的映射文件中所有的 SQL 语句所访问。例如以前 xml 中某个 SQL 如下:

1
2
3
4
5
6
<insert id="insertMutipleEmp">
insert into emp value
<foreach collection="array" item="empItem" separator=",">
(null, #{empItem.ename}, #{empItem.age}, #{empItem.sex}, 1)
</foreach>
</insert>

可以使用 SQL 标签将 emp value 字段进行封装成一个片段 (这里封装 emp value 字段可能不太合适,应该封装得更完整和全面些,这里只是举例说明)。然后使用 include 标签进行包含。

1
2
3
4
5
6
7
8
9
10
11
12
<sql id="insertMutipleEmpColumns">
emp value
</sql>

<!-- void insertMutipleEmp(Emp[] emps); -->
<insert id="insertMutipleEmp">
insert into
<include refid="insertMutipleEmpColumns"></include>
<foreach collection="array" item="empItem" separator=",">
(null, #{empItem.ename}, #{empItem.age}, #{empItem.sex}, 1)
</foreach>
</insert>

批量操作

批量新增

批量新增的 SQL 格式为 insert into emp values(), (), () 所以我们也需要使用 foreach 进行拼接。接口中的方法如下:

1
2
// 批量添加多个 Emp
void insertMutipleEmp(Emp[] emps);

映射文件中内容如下:

1
2
3
4
5
6
7
<!-- void insertMutipleEmp(Emp[] emps); -->
<insert id="insertMutipleEmp">
insert into emp value
<foreach collection="array" item="empItem" separator=",">
(null, #{empItem.ename}, #{empItem.age}, #{empItem.sex}, 1)
</foreach>
</insert>

注意⚠️:接口中的 insertMutipleEmp 方法是使用数组进行传值过来的,所以这里 collection 中需要使用 array 进行接收,迭代的时候使用 . 就可以获取里面的值。

测试方法:

1
2
3
4
5
6
7
Emp emp2 = new Emp(null, "tiantian", 22, "1");
Emp emp3 = new Emp(null, "lanlan", 45, "0");
Emp emp4 = new Emp(null, "wangwang", 34, "1");
Emp emp5 = new Emp(null, "liiu", 65, "0");

Emp[] emps = {emp2, emp3, emp4, emp5};
mapper.insertMutipleEmp(emps);

批量修改

如果批量修改修改的内容是一致的,那么 SQL 语句的写法和第一种批量删除的方式是一样的,都是使用 in。这种方式就需要注意 #{}#() 的区别。

但是这里每条数据修改的是不一样的内容,所以这里要修改多条数据,就要写多条 SQL 语句。因为是一次性执行多条 SQL 所以必须在 jdbc 的 url 地址后面添加参数 allowMultiQueries=true ,即 jdbc.url = jdbc:mysql://localhost:3306/ssm?allowMultiQueries=true。这里也就不必考虑 #{}#() 的区别。

对应的 SQL 格式大致如下:

1
2
3
update emp set ... where ein = 1;
update emp set ... where ein = 2;
update emp set ... where ein = 3;

接口中的 updateMutipleEmp 方法

1
2
// 批量修改
void updateMutipleEmp(Emp[] emps);

xml 映射文件内容如下:

1
2
3
4
5
6
<!-- void updateMutipleEmp(Emp[] emps); -->
<update id="updateMutipleEmp">
<foreach collection="array" item="empItem">
update emp set ename=#{empItem.ename}, age=#{empItem.age}, sex=#{empItem.sex} where eid = #{empItem.eid};
</foreach>
</update>

测试内容如下:

1
2
3
4
5
6
Emp emp2 = new Emp(15, "zhenzhen1", 22, "1");
Emp emp3 = new Emp(16, "zhenzhen2", 23, "0");
Emp emp4 = new Emp(17, "zhenzhen3", 24, "1");
Emp emp5 = new Emp(18, "zhenzhen4", 25, "0");
Emp[] emps2 = {emp2, emp3, emp4, emp5};
mapper.updateMutipleEmp(emps2);

Mybatis 的缓存

一级缓存测试

Mybatis 中的一级缓存默认是开启的,是 SqlSession 级别的。即同一个 SqlSession 对于一个 sql 语句,执行之后就会存储在缓存中,下次执行相同的 SQL 的时候直接从缓存中取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Test
public void test() throws IOException {
/**
* Mybatis 中的一级缓存默认是开启的,是 SqlSession 级别的
* 即同一个SqlSession对于一个sql语句,执行之后就会存储在缓存中,下次执行相同的SQL的时候直接从缓存中取
*/
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession(true);
EmpMapper mapper = openSession.getMapper(EmpMapper.class);

System.out.println("第一次执行会显示出 SQL 语句");
Emp empByEid1 = mapper.getEmpByEid("10");
System.out.println(empByEid1);

System.out.println("-------------------------------");

System.out.println("执行相同的查询,不会再次出现 SQL 语句,因为被缓存了所以直接从缓存中读取");
Emp empByEid2 = mapper.getEmpByEid("10");
System.out.println(empByEid2);

上面查询示例中都是查询 id 为 10 的 emp 信息,且都是同一个 SqlSession,所以第二次查询的时候不会再次显示 SQL 了。

一级缓存失效的几种情况

  1. 不同的 SqlSession 对应不同的一级缓存
  2. 同一个 SqlSession 但是查询条件不同
  3. 同一个 SqlSession 两次查询期间执行了任何一次增删改操作
  4. 同一个 SqlSession 两次查询期间手动清空了缓存。使用 openSession.clearCache(); 方法进行清空

二级缓存

二级缓存默认不开启,需要手动配置

  1. 在 mybits 核心配置文件中新增标签 <setting name="cacheEnabled" value="true"/>
  2. POJO 中实现 Serializable 接口。
  3. 需要在 xml 映射文件中配置 <cache> 标签。
  4. 二级缓存需要在 Sqlsession 关闭或者提交后才能生效。

<cache> 标签中可以进行一些属性的设置

  1. eviction=“FIFO”:
    缓存回收策略(默认的是 LRU):
    ​ LRU – 最近最少使用的:移除最长时间不被使用的对象。
    ​ FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
    ​ SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
    ​ WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
  2. flushInterval:刷新间隔,单位毫秒
    默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新
  3. size:引用数目,正整数
    代表缓存最多可以存储多少个对象,太大容易导致内存溢出
  4. readOnly:只读,true/false
    true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。
    false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是 false。

EmpMapper.xml 中配置 <cache> 标签

1
2
<!-- 使用二级缓存 -->
<cache />

POJO 中实现 Serializable 接口

1
2
3
4
public class Emp implements Serializable{
private static final long serialVersionUID = 1L;
......
}

测试缓存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 @Test
public void testSecondCache() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession(true);
EmpMapper mapper = openSession.getMapper(EmpMapper.class);
Emp empByEid1 = mapper.getEmpByEid("10");
System.out.println(empByEid1);

openSession.commit(); // 提交 Sqlsession,这样二级缓存才能生效
System.out.println("-------------------------------");

EmpMapper mapper2 = openSession.getMapper(EmpMapper.class);
Emp empByEid2 = mapper2.getEmpByEid("10");
System.out.println(empByEid2);
}

二级缓存的注意点

  1. 需要在全局 setting 中设置 cacheEnable ,配置二级缓存的开关。并在 xml 文件中使用 <cache /> 标签来应用,这样这个 xml 中所有的 select 查询都开启了二级缓存。一级缓存一直是打开的,无法关闭。
  2. 如果某个查询不想使用二级缓存,那么我们可以在 select 标签中加上 useCache 属性来设置是否使用。
1
<select id="getEmpListByMultipleCondition" resultType="Emp" useCache="false">
  1. 增删改操作的标签后面都可以配置 flushCache 属性,默认为 true。表示增删改操作后是否刷新缓存。默认增删改后都是会清空一级和二级的。不建议将其设置为 false。
1
<update id="updateEmpByMutipleCondition" flushCache="true">
  1. openSession.clearCache(); 方法只能清除一级缓存。

整合第三方缓存

这里使用的是第三方的 EhCache 缓存。EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate 中默认的 CacheProvider。

整合步骤:

  1. 导入 jar 包
1
2
3
4
ehcache-core-2.6.8.jar
mybatis-ehcache-1.0.3.jar
slf4j-api-1.6.1.jar
slf4j-log4j12-1.6.2.jar
  1. 编写ehcache.xml配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<!-- 磁盘保存路径 -->
<diskStore path="D:\atguigu\ehcache" />

<defaultCache
maxElementsInMemory="1000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>

<!--
属性说明:
l diskStore:指定数据在磁盘中的存储位置。
l defaultCache:当借助CacheManager.add("demoCache")创建Cache时,EhCache便会采用<defalutCache/>指定的的管理策略

以下属性是必须的:
l maxElementsInMemory - 在内存中缓存的element的最大数目
l maxElementsOnDisk - 在磁盘上缓存的element的最大数目,若是0表示无穷大
l eternal - 设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断
l overflowToDisk - 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上

以下属性是可选的:
l timeToIdleSeconds - 当缓存在EhCache中的数据前后两次访问的时间超过timeToIdleSeconds的属性取值时,这些数据便会删除,默认值是0,也就是可闲置时间无穷大
l timeToLiveSeconds - 缓存element的有效生命期,默认是0.,也就是element存活时间无穷大
diskSpoolBufferSizeMB 这个参数设置DiskStore(磁盘缓存)的缓存区大小.默认是30MB.每个Cache都应该有自己的一个缓冲区.
l diskPersistent - 在VM重启的时候是否启用磁盘保存EhCache中的数据,默认是false。
l diskExpiryThreadIntervalSeconds - 磁盘缓存的清理线程运行间隔,默认是120秒。每个120s,相应的线程会进行一次EhCache中数据的清理工作
l memoryStoreEvictionPolicy - 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出)
-->
  1. 配置cache标签
1
<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>

代码地址

逆向工程

MyBatis Generator: 简称MBG,是一个专门为MyBatis框架使用者定制的代码生成器,可以快速的根据表生成对应的映射文件,接口,以及bean类。支持基本的增删改查,以及QBC风格的条件查询。但是表连接、存储过程等这些复杂sql的定义需要我们手工编写。官方文档地址 http://www.mybatis.org/generator/ 官方工程地址 https://github.com/mybatis/generator/releases

  1. 导入逆向工程的jar包
1
mybatis-generator-core-1.3.2.jar
  1. 编写 MBG 的配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?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="MyBatis3Simple">
<!-- 设置连接数据库的信息 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/ssm"
userId="root"
password="123456">
</jdbcConnection>

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

<!-- javabean的生成策略 -->
<javaModelGenerator targetPackage="com.atguigu.bean" targetProject="./src">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>


<!-- 映射文件的生成策略 -->
<sqlMapGenerator targetPackage="com.atguigu.mapper" targetProject="./conf">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>

<!-- mapper接口的生成策略 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.atguigu.mapper" targetProject="./src">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>

<!-- 设置要将数据库中的哪张表逆向生成哪一个javabean -->
<table tableName="emp" domainObjectName="Emp"></table>
<table tableName="dept" domainObjectName="Dept"></table>

</context>
</generatorConfiguration>
  1. 自动生成信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.atguigu.test;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;

public class TestSQL {
public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
File configFile = new File("mbg.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);
}
}

运行之后就能自动生成 bean,mapper 接口类,mapper.xml 中的信息。

代码地址