MyBatis 使用小技巧
# 1. #{}
与 ${}
#{}
:先编译 SQL 语句,再给占位符传值,底层是 PreparedStatement 实现。可以防止 SQL 注入,比较常用。${}
:先进行 SQL 语句拼接,然后再编译 SQL 语句,底层是 Statement 实现。存在 SQL 注入现象。只有在需要进行 SQL 语句关键字拼接的情况下才会用到。
优先使用 #{}
,只有当必须对 SQL 语句的关键字进行拼接的时候,才需要使用 ${}
。
# 2. typeAliases
在 mapper.xml 的 resultType
中,我们之前都是写的类的全限定名,也就是 com.example.demo.entity.User
,为了对其简化,我们可以为它起个别名。
<typeAliases>
用来为"全限定类名"起一个别名,该标签位于 mybatis-config.xml 这个核心配置文件中。
# 2.1 第一种方式:typeAlias
<typeAliases>
<typeAlias type="com.powernode.mybatis.pojo.Car" alias="Car"/>
</typeAliases>
2
3
- typeAliases 标签中的 typeAlias 可以写多个。
- typeAlias:
- type 属性:指定给哪个类起别名
- alias 属性:别名
- alias 属性不是必须的,如果缺省的话,type 属性指定的类型名的简类名作为别名。
- alias 是大小写不敏感的。也就是说假设 alias="Car",再用的时候,可以 CAR,也可以 car,也可以 Car,都行。
# 2.2 第二种方式:package
如果一个包下的类太多,每个类都要起别名,会导致 typeAlias 标签配置较多,所以 mybatis 用提供 package 的配置方式,只需要指定包名,该包下的所有类都自动起别名,别名就是简类名。并且别名不区分大小写。
<typeAliases>
<package name="com.powernode.mybatis.pojo"/>
</typeAliases>
2
3
这样在 mapper.xml 中,这个 package 下面的类可以直接只写个类名。
package 也可以配置多个的。
# 3. mappers 标签
mybatis-config.xml 里面还有个 <mappers>
标签,用来指定 mapper 映射文件,它的配置方式包括四种:
- resource:从类路径中加载
- url:从指定的全限定资源路径中加载
- class:使用映射器接口实现类的完全限定类名
- package:将包内的映射器接口实现全部注册为映射器
# 3.1 resource
这种方式是从类路径中加载配置文件,所以这种方式要求 SQL 映射文件必须放在 resources 目录下或其子目录下。
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
2
3
4
5
# 3.2 url
使用绝对路径的方式,这种配置对 SQL 配置文件存放的位置没有要求。极少使用,可移植性太差。
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
2
3
4
5
# 3.3 class
如果使用这种方式必须满足以下条件:
- SQL映射文件和 mapper 接口放在同一个目录下。
- SQL映射文件的名字也必须和 mapper 接口名一致。
<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
</mappers>
2
3
4
这样 MyBatis 会自动去 resource 目录的 org/mybatis/builder 目录下寻找 AuthorMapper.xml 文件。
# 3.4 package
如果 class 较多,可以使用这种 package 的方式,但前提条件和上一种方式一样。
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
<package name="com.powernode.mybatis.mapper"/>
</mappers>
2
3
4
# 3.4 IDEA 配置文件模板
mybatis-config.xml 和 SqlMapper.xml 文件可以在 IDEA 中提前创建好模板,以后通过模板创建配置文件。
# 3.5 插入数据时获取自动生成的主键
前提是:主键是自动生成的。
业务背景:一个用户有多个角色。
插入一条新的记录之后,自动生成了主键,而这个主键需要在其他表中使用时。
插入一个用户数据的同时需要给该用户分配角色:需要将生成的用户的id插入到角色表的user_id字段上。
- 第一种方式:可以先插入用户数据,再写一条查询语句获取id,然后再插入user_id字段。【比较麻烦】
- 第二种方式:mybatis提供了一种方式更加便捷。
CarMapper 接口:
/**
* 获取自动生成的主键
* @param car
*/
void insertUseGeneratedKeys(Car car);
2
3
4
5
CarMapper.xml 文件:
<insert id="insertUseGeneratedKeys" useGeneratedKeys="true" keyProperty="id">
insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})
</insert>
2
3
CarMapperTest.testInsertUseGeneratedKeys:
@Test
public void testInsertUseGeneratedKeys(){
CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
Car car = new Car();
car.setCarNum("5262");
car.setBrand("BYD汉");
car.setGuidePrice(30.3);
car.setProduceTime("2020-10-11");
car.setCarType("新能源");
mapper.insertUseGeneratedKeys(car);
SqlSessionUtil.openSession().commit();
System.out.println(car.getId());
}
2
3
4
5
6
7
8
9
10
11
12
13