1.动态SQL
问题
之前我们在查询用户信息的时候,可以设置根据不同的条件查询用户信息,具体代码如下:
可以根据用户id查询用户的信息
Mapper接口
public List<User> queryUserById(Integer id);
Mapper.xml
<select id="queryUserById" resultType="user">
select * from user where id=#{id}
</select>
也可以根据用户名查询用户的信息
Mapper接口
public List<User> queryUserByName(String name);
Mapper.xml
<select id="queryUserByName" resultType="user">
select * from user where user_name=#{name}
</select>
其实也可以根据密码查询用户的信息
Mapper接口
public List<User> queryUserByPassword(String password);
Mapper.xml
<select id="queryUserByPassword" resultType="user">
select * from user where password=#{password}
</select>
解决方案
使用Mybatis的动态SQL来解决
下面我们按照不同的类型来分别讲解Mybatis中的动态SQL
1.1.条件分支SQL
1.1.1.if标签和where标签
UserMapper接口
public interface UserMapper {
public List<User> findUserByConditions(@Param("id") Integer id,@Param("name") String name,@Param("password") String password);
}
UserMapper.xml配置文件
<!--
如何用一个sql语句实现如下操作:
如果传递了id,没有传递用户名和密码,那根据id查询用户信息
如果传递了用户名,没有传递id和密码,那根据用户名查询用户信息
如果传递了密码,没有传递id和用户名,那根据密码查询用户信息
如果id、用户名、密码都传递了,那根据id、用户名、密码查询用户信息
如果id、用户名、密码都没有传递,那查询全部用户信息
-->
<select id="findUserByConditions" resultType="user">
select * from user where
<if test="id != null and id > 0">
id = #{id}
</if>
<if test="name != null and name != ''">
and user_name = #{name}
</if>
<if test="password != null and password != ''">
and password = #{password}
</if>
</select>
MybatisTest.java单元测试类
public class MybatisTest {
@Test
public void queryAllUserTest() throws IOException {
InputStream resourceAsStream =Resources.getResourceAsStream("Mybatis-Config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);//采用动态代理的方式,构建出usermapper实现类对象
List<User> users = mapper.findUserByConditions(0,"","");
System.out.println(users);
sqlSession.close();
}
}
运行测试
出现问题的原因是因为传入的条件都不满足if标签的判断,所以最终的sql变成了select * from user where,这样的sql语句是不对的,那就是说问题其实就是where关键字引起的,如何解决 呢?对此Mybatis提供了where标签来替代where关键字。
<!--
如何用一个sql语句实现如下操作:
如果传递了id,没有传递用户名和密码,那根据id查询用户信息
如果传递了用户名,没有传递id和密码,那根据用户名查询用户信息
如果传递了密码,没有传递id和用户名,那根据密码查询用户信息
如果id、用户名、密码都传递了,那根据id、用户名、密码查询用户信息
如果id、用户名、密码都没有传递,那查询全部用户信息
-->
<!--
if标签:动态判断传递的参数是否满足test中规定的条件,满足将if标签中的内容拼接到sql语句中,不满足就不拼接
where标签:动态去除条件前面的and、or等sql关键字
-->
<select id="findUserByConditions" resultType="user">
select * from user
<where>
<if test="id != null and id > 0">
id=#{id}
</if>
<if test="userName != null and userName != ''">
and user_name=#{userName}
</if>
<if test="password != null and password != ''">
and password=#{password}
</if>
</where>
</select>
再次运行测试
如果传递的条件符合,则会使用条件
注意:where关键字会自动将拼接多个条件之间的诸如AND、OR这些多余的关键字去掉。
1.1.2.choose&when&otherwise
UserMapper.java接口中
public interface UserMapper {
public List<User> findUserByConditionsTwo(@Param("user") User user);
}
UserMapper.xml配置文件
<!--choose动态条件sql语句-->
<!-- if标签相当于java中的if判断(没有else和else if),每个if判断都会执行判
断choose when otherwise相当于java中的 if else if else ,如果if满足
了,else if else是不执行判断
-->
<select id="findUserByConditionsTwo" parameterType="user" resultType="user">
select * from user
<where>
<choose>
<when test="user.id != null and user.id > 0">
id=#{user.id}
</when>
<when test="user.userName != null and user.userName != ''">
and user_name=#{user.userName}
</when>
<when test="user.password != null and user.password !=''">
and password=#{user.password}
</when>
<otherwise>
id=1
</otherwise>
</choose>
</where>
</select>
MybatisTest.java单元测试类
public class MybatisTest {
@Test
public void queryAllUserTest2() throws IOException {
InputStream resourceAsStream =Resources.getResourceAsStream("Mybatis-Config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);//采用动态代理的方式,构建出usermapper实现类对象
List<User> users = mapper.findUserByConditionsTwo(new User(0,"",""));
System.out.println(users);
sqlSession.close();
}
}
运行测试
会发现:if 和 choose分支的区别在于,if有可能满足多个分支,而choose语句即使条件都 满足,也只能从多个分支中选一个。
1.2.循环SQL
1.2.1forEach
forEach标签的使用场景:批量插入、in语句等。
批量插入
UserMapper.java接口中
public void insertArrayUser(List<User> users);
UserMapper.xml映射文件
<!-- 需求:需要根据实际传入的要添加的用户的个数,动态调整sql语句实现,批量插入所有用户 -->
<!--foreach标签,本质就是遍历操作
collection:要遍历的集合或数组参数的名称,
如果是list集合参数,直接使用内置的list名称即可,也可以使用@Param去自定义
数组名称是array,也可以使用@Param去自定义
set、map集合是没有名称的,需要使用@Param定义
item: 遍历出来的元素存放的变量
separator:拼接sql时以什么来拼接
close: 拼接结束之后以什么结尾
index: 遍历的元素的索引
open:拼接以什么开头
-->
<insert id="insertArrayUser" parameterType="user">
insert into user(user_name,password) values
<foreach collection="users" item="user" separator="," close=";" index="idx" open="">
(#{user.userName},#{user.password})
</foreach>
</insert>
MybatisTest.java单元测试类
@Test
public void test2(){
SqlSessionFactory sqlSessionFactory = MybatisUtil.getSqlSessionFactory("Map-Config.xml");
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = new ArrayList<>();
users.add(new User("孙尚香","dsfslf"));
users.add(new User("周瑜","2232342"));
users.add(new User("小乔","55575756"));
users.add(new User("大乔","8908098908"));
mapper.insertArrayUser(users);
}
运行测试
会发现批量插入最终形成的sql语句为:insert into user (user_name,password) values ("孙尚 香","dsfslf"),("周瑜","2232342"),("小乔","55575756"),("大乔","8908098908");
注意:collection在使用时,如果不指定传入参数名称,List对象默认用"list"代替作为键;对象数组用"array"代替作为键;list和数组也可以使用@Param自定义名称,Set对象、Map对象没有默认的键,比如使用@Param自定义名称
循环Map参数、Set参数
UserMapper.xml接口
public interface UserMapper {
public void insertMapUser(@Param("users") Map<String,User> map);
}
UserMapper.xml映射文件
<!--批量插入map map:{"aa":{"战给","1231231"}}-->
<insert id="insertMapUser" parameterType="user">
insert into user(user_name,password) values
<foreach collection="users" item="user" separator="," close=";"index="idx" open="">
(#{user.userName},#{user.password})
</foreach>
</insert>
MybatisTest.java单元测试类
public class MybatisTest {
@Test
public void insertMapUserTest() throws IOException {
InputStream resourceAsStream =
Resources.getResourceAsStream("Mybatis-Config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);//采用动态代理的方式,构建出usermapper实现类对象
Map<String,User> map = new HashMap<String,User>();
map.put("one",new User("唐僧","ts"));
map.put("two",new User("孙悟空","swk"));
map.put("three",new User("猪八戒","zbj"));
mapper.insertMapUser(map);
sqlSession.close();
}
}
运行测试
当然,collection在使用时,传入参数为List对象、数组对象也可以不使用默认值,直接在 Mapper接口的方法中使用@Param()指定传入参数的名称进行使用。
1.3.其他特殊SQL
1.3.1.set
set 元素会动态前置 SET 关键字,同时也会删掉无关的逗号(如:语句最后的逗号)
使用示例:
UserMapper.java接口中
public void updateUser(User user);
UserMapper.xml配置文件
<!--set标签,自动可以将拼接的sql语句中的,去掉,但是只能去掉一个-->
<!-- update user set user_name=xxx,password=xxx, where id=xxx -->
<update id="updateUser" parameterType="user">
update user
<set>
user_name=#{userName},password=#{password},
</set>
<where>
id=#{id}
</where>
</update>
MybatisTest.java单元测试类
public class MybatisTest {
@Test
public void updateUserTest() throws IOException {
InputStream resourceAsStream =Resources.getResourceAsStream("Mybatis-Config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);//采用动态代理的方式,构建出usermapper实现类对象
mapper.updateUser(new User(5,"黄忠","hz"));
sqlSession.close();
}
}
1.3.2.trim
trim标签是这三个标签中最灵活的一个, where和set标签的功能其实通过trim标签都能实现
常用属性:
- prefix : 添加指定前缀
- suffix:添加后缀
- prefixOverrides : 删除指定前缀
- suffixOverrides : 删除指定后缀
UserMapper.xml配置文件中
<!--trim标签
prefix:添加前缀
suffix:添加后缀
prefixOverrides:删除指定前缀
suffixOverrides:删除指定后缀缀
-->
<update id="updateUser" parameterType="user">
update user
<trim prefix="set" suffixOverrides=",">
user_name=#{userName},password=#{password},
</trim>
<trim prefix="where" prefixOverrides="and | or">
and id=#{id}
</trim>
</update>
1.4.动态传入表名、表字段名
Mybatis中支持将表名、表字段名作为参数传递给映射文件,而映射文件中使用${}来获取使用。
UserMapper.java接口中
public void deleteById(@Param("user")String user,@Param("u_id")String u_id,@Param("id")Integer id);
UserMapper.xml配置文件中
<delete id="deleteById" >
delete from ${user} where ${u_id}=#{id}
</delete>
MybatisTest.java单元测试
@Test
public void test7(){
SqlSessionFactory sqlSessionFactory = MybatisUtil.getSqlSessionFactory("Map-Config.xml");
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.deleteById("user","id",3);
}
1.5.抽取公共sql和引入公共sql标签
抽取公共sql-sql标签
<!--抽取sql标签-->
<sql id="selectSqlId">
select * from user
</sql>
引入公共sql-include标签
<select id="findUserByConditions" resultType="user">
<include refid="selectSqlId"/>
.....
</select>
2.批量插入
2.1.通过forEach动态SQL方式
2.1.1.实现原理
forEach批量插入的原理是直接通过forEach动态标签,根据传过来的参数数量动态生成一个很长的SQL语句。一个语句就是一次批量插入。
语句形如:
insert into user (username, age) values
('张三', 10),
('李四', 10),
('王五', 10),
('赵六', 10),
('盖聂', 9000)
# 上面的语句一次会插入5条数据
我们需要做的就是生成此语句就可以了。
2.1.2.具体做法
UserMapper.java接口
public void insertArrayUser(List<User> users);
UserMapper.xml映射文件
<insert id="insertArrayUser" parameterType="user">
insert into user (user_name,password) values
<!-- collection:要遍历集合的名称,List对象默认用"list"代替作为键;数组对象有"array"代替作为键;Set对象、Map对象没有默认的键
index:索引下标
item:遍历元素存放的载体
separator:<foreach></foreach>中间遍历内容的间隔符
close:遍历结束的符号
-->
<foreach collection="list" index="idx" item="user" separator=","close=";">
(#{user.userName},#{user.password})
</foreach>
</insert>
insert into user(user_name,password) values (xxx,xxx),(xxxx,xxxx)
此种批量插入不适合大数据量批量插入,性能消耗比较大(5000条数据,约耗时14分钟),一般来说一次性插20~50条数量时此操作是比较适合的。
2.2.通过ExecutorType.BATCH的方式
2.2.1.实现原理
这种批量插入在底层的Mapper接口和Mapper映射文件中,都只是一个普通插入单条数据的写法。它通过在上层获取SqlSession时,指定执行类型是批量ExecutorType.BATCH的方式,实现每次执行完单条插入以后并没有真正写入数据库,只有当调用 sqlSession.flushStatements()时,才会将这一批数据一次性写入数据库,从而实现批量操作。
2.2.2.使用步骤
1.Mapper接口和Mapper映射文件中只需按照单条插入去写方法和SQL语句即可
UserMapper.java接口
public void insertUser(User user);
UserMapper.xml映射文件
<insert id="insertUser" parameterType="user">
insert into user(user_name,password) values(#{userName},#{password})
</insert>
2.获取SqlSession时指定执行类型为批量,控制批量的大小,在够一批数据时,调用 sqlSession.flushStatement() 去整体往数据库写一次,而此种方式获取影响条数没有那么直接,需要去API返回的BatchResult对象中读取updateCounts方法才能拿到。
@Test
public void test4(){
SqlSessionFactory sqlSessionFactory = MybatisUtil.getSqlSessionFactory("Map-Config.xml");
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH,true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = new ArrayList<>();
users.add(new User("张辽","dsfslf"));
users.add(new User("曹操","2232342"));
users.add(new User("曹昂","55575756"));
users.add(new User("曹冲","8908098908"));
//批处理操作
int batchSize=10;//一批数据的量
int count=0;//计数器
// 将每次flushStatements返回的本批次操作的返回结果累加到一个全局的集合中,方便最后统计
List<BatchResult> resultList = new ArrayList<>();
for (User user:users) {
mapper.insertUser(user);
count++;
if (count % batchSize == 0){ //如果大于batchSize,那每batchSize往数据库更新一次数据
List<BatchResult> batchResults =sqlSession.flushStatements();
resultList.addAll(batchResults);
}
}
//如果不到batchSize,则只往数据库中更新一次数据
if(count % batchSize != 0) {
resultList.addAll(sqlSession.flushStatements());
}
//获取影响的条数
int rows = 0;
for(BatchResult batchResult : resultList) {
int[] updateCounts = batchResult.getUpdateCounts();
for(int updateCount : updateCounts) {
rows += updateCount;
}
}
System.out.println("批量插入成功,响应的行数:" + rows);
}
3.Mybatis缓存
3.1.一级缓存(本地缓存)
Mybatis的一级缓存是指SqlSession缓存。一级缓存的作用域默认是一个SqlSession。 Mybatis默认开启一级缓存。
也就是在同一个SqlSession中,执行相同的查询SQL,第一次会去数据库进行查询,并写到缓存 中; 第二次以后是直接去缓存中取。 当执行SQL查询中间发生了增删改的操作,MyBatis会把SqlSession的缓存清空。
3.1.1测试方法
1.我们在一个 sqlSession 中,对 User 表根据id进行两次查询,查看他们发出sql语句的情况 UserMapper.java接口中
public interface UserMapper {
public User queryUserById(Integer id);
}
UserMapper/xml配置文件
<select id="queryUserById" resultType="user">
select * from user where id=#{id}
</select>
MybatisTest.java单元测试类
@Test
public void insertUserTest() throws IOException {
InputStream resourceAsStream =Resources.getResourceAsStream("Mybatis-Config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
OneCacheMapper mapper = sqlSession.getMapper(OneCacheMapper.class);
//mybatis的一级缓存,就是sqlSession缓存,作用域只在一个sqlSession中生效、
//1.同一个SqlSession,第一次查询,会查询数据库并将数据存储到缓存中,第二次查询,如果是相同的查询,则不在查询数据库,而是从缓存中获取
//2.同一个SqlSession,第一次查询之后,会缓存数据,之后做了更新数据库操作,缓存会被自动清空,第二次查询,还是会查询数据库的
//第一次查询
User u1 = mapper.queryUserById(1);
System.out.println("第一次查询的结果:"+u1);
//第二次查询
User u2 = mapper.queryUserById(1);
System.out.println("第二次查询的结果:"+u2);
sqlSession.close();
}
执行结果
同样是对user表进行两次查询,只不过两次查询之间进行了一次update操作
@Test
public void insertUserTest() throws IOException {
InputStream resourceAsStream =Resources.getResourceAsStream("Mybatis-Config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
OneCacheMapper mapper = sqlSession.getMapper(OneCacheMapper.class);
//mybatis的一级缓存,就是sqlSession缓存,作用域只在一个sqlSession中生效、
//1.同一个SqlSession,第一次查询,会查询数据库并将数据存储到缓存中,第二次查询,如果是相同的查询,则不在查询数据库,而是从缓存中获取
//2.同一个SqlSession,第一次查询之后,会缓存数据,之后做了更新数据库操作,缓存会被自动清空,第二次查询,还是会查询数据库的
//第一次查询
User u1 = mapper.queryUserById(1);
System.out.println("第一次查询的结果:"+u1);
//更新操作
mapper.updateUserById(new User(24,"颜鸿爽","123456"));
//第二次查询
User u2 = mapper.queryUserById(1);
System.out.println("第二次查询的结果:"+u2);
sqlSession.close();
}
运行测试
3.1.2.如何禁用一级缓存
-
在映射文件中给对应的select标签上添加 flushCache="true" 属性
<!-- flushCache:true表示暂停使用一级缓存,false表示使用一级缓存 --> <select id="queryUserById" resultType="user" flushCache="true"> select * from user where id=#{id} </select>
-
在核心配置文件中将localCacheScope设置成STATEMENT(默认值是SESSION)
<settings> <!-- 暂停使用一级缓存,默认为SESSION --> <setting name="localCacheScope" value="STATEMENT"/> </settings>
3.2.二级缓存(全局缓存)
3.2.1.什么是二级缓存?
Mybatis中二级缓存相比一级(本地)缓存来说是一个作用域更大的缓存方案。 二级缓存的作用 域可以跨多个SqlSession,只要是同一个namespace下的mapper映射文件都可以共享缓存。 但是不能跨SqlSessionFactory。
Mybatis二级缓存需要手动开启。
3.2.2.开启二级缓存的方法
1.在 SqlMapConfig.xml 文件开启二级缓存
<settings>
<!-- 开启全局二级缓存的支持 -->
<setting name="cacheEnabled" value="true"/>
</settings>
2.配置相关的 Mapper 映射文件 (因为二级缓存就是针对特定的mapper namespace的)
<?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.lanou.mybatis.mapper.UserMapper">
<!-- 开启二级缓存 -->
<cache/>
</mapper>
标签表示当前这个 mapper 映射将使用二级缓存,能否命中二级缓存就看多次查询是否属于同一个namespace。
3.案例测试
@Test
public void test6(){
SqlSessionFactory sqlSessionFactory =MybatisUtil.getSqlSessionFactory("Map-Config.xml");
SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = mapper1.queryUserById(1);
System.out.println(user1);
sqlSession1.close();
SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.queryUserById(1);
System.out.println(user2);
sqlSession2.close();
}
4.二级缓存注意事项
1. 二级缓存只有每次查询结束,正常关闭SqlSession会话对象,才能触发。
2. 当我们在使用二级缓存时,所缓存的类一定要实现 java.io.Serializable 接口,这种就可以使用序列化 方式来保存对象。
public class User implements Serializable { }
5.运行测试
3.2.3设置某个特定的查询语句不用二级缓存
<!-- useCache:true表示使用二级缓存,默认值;false表示不使用二级缓存 -->
<select id="queryUserById" resultType="user" useCache="false">
select * from user where id=#{id}
</select>
注意: 如果mapper文件中没有开启 仅在语句上添加useCache="true"是无法开启二级缓存的。这个属性本意是用来关闭特定查询的二级缓存。
运行测试
4.Mybatis逆向工程
mybatis逆向工程是官方为了简化Mybatis的开发,提供的一个可以根据数据库自动生成POJO 类、Mapper接口和Mapper映射文件的工具。
4.1.使用方法
-
通过命令行使用
java -jar mybatis-generator-core-1.3.7.jar -configfile .\generatorConfig.xml -overwrite
-
通过Java代码调用
-
通过maven插件使用
<build> <plugins> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.5</version> <configuration> <verbose>true</verbose> <!-- 是否覆盖生成实体类和Mapper接口类 --> <overwrite>true</overwrite> <!-- 指定逆向工程工具的配置文件路径,默认: src/main/resources/generatorConfig.xml --> <!-- <configurationFile></configurationFile> --> </configuration> <dependencies> <!-- 逆向工程需要依赖的jar包 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.32</version> </dependency> </dependencies> </plugin> </plugins> </build>
注意: 无论是那种方式,overwrite参数只能覆盖生成的JAVA类,对于Mapper映射文件永远不会覆盖,而是追加!!!
4.2.配置文件说明
mybatis逆向工程工具由配置文件和一个jar包组成,配置文件中主要有以下配置项:
- 配置逆向工程依赖的第三方jar包
- 配置逆向工程生成代码的类型
- 配置数据库的连接参数
- 配置逆向工程生成代码的位置
- 配置要生成的表
附完整配置文件说明
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!--数据库驱动-->
<classPathEntry
location="D:\Lesson\WorkSpace\Test\Mybatis\mybatis_generator_maven\mysqlconnector-java-5.1.32.jar"/>
<!-- 一个数据库一个context -->
<context id="MYTables" targetRuntime="MyBatis3">
<commentGenerator>
<!--suppressDate:**阻止**生成的注释包含时间戳-->
<property name="suppressDate" value="true"/>
<!--suppressAllComments:**阻止**生成注释-->
<property name="suppressAllComments" value="false"/>
</commentGenerator>
<!--数据库链接地址账号密码-->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mybatistest?
characterEncoding=utf8&serverTimezone=UTC"
userId="root" password="root">
</jdbcConnection>
<javaTypeResolver>
<!--控制是否强制DECIMAL和NUMERIC类型的字段转换为Java类型的
java.math.BigDecimal-->
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!--生成Model类(JavaBean实体类)存放位置
targetPackage:包
targetProject:包所在的目录
-->
<javaModelGenerator targetPackage="com.test.mybatis.pojo" targetProject="D:\Lesson\WorkSpace\Test\Mybatis\mybatis_generator_maven\src\main\java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--生成映射文件存放位置
targetPackage:包
targetProject:包所在的目录
-->
<sqlMapGenerator targetPackage="com.lanou.mybatis.mapper"
targetProject="D:\Lesson\WorkSpace\Test\Mybatis\mybatis_generator_maven\src\main\resources">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!--生成Dao类存放位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.test.mybatis.mapper"
targetProject="D:\Lesson\WorkSpace\Test\Mybatis\mybatis_generator_maven\src\main\java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!--生成对应表及类名
tableName:表明
domainObjectName:实体类
-->
<table tableName="user" domainObjectName="User"/>
</context>
</generatorConfiguration>
标签:04,UserMapper,MyBatis03,public,sqlSession,user,id,User
From: https://www.cnblogs.com/jiabaolatiao/p/17529788.html