- Mybatis小技巧
- #{}和${}
- typeAliases起别名
- mappers标签属性
- idea配置文件模板
九、Mybatis小技巧
9.1 #{}和${}
#{}
和${}
的区别:#{}
:底层使用PreparedStatement
。特点:先进行 SQL 语句的编译,然后给 SQL 语句的占位符?
传值。可以避免 SQL 注入的风险。${}
:底层使用Statement
。特点:先进行 SQL 语句的拼接,然后再对 SQL 语句进行编译。存在 SQL 注入的风险。
优先使用
#{}
,这是原则。避免 SQL 注入的风险。那么什么时候使用
${}
呢?->P68-71
(代码就懒得写了,还是不清楚的话就根据集数看相应的视频)如果**需要将 SQL 语句的关键字放到 SQL 语句中,就只能使用
${}
**,因为#{}
是以值的形式放到 SQL 语句当中的。例如:当需要动态地对查询结果进行升序(asc
)或者降序(desc
)时,就只能使用${}
了。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#{}的执行结果:
Preparing: select
id, car_num as carNum, brand, guide_price as guidePrice, produce_time as produceTime, car_type as carType
from t_car order by produce_time ?
Parameters: asc(String)
===> 预编译并传值,发现asc是作为字符串值传入:
select
id, car_num as carNum, brand, guide_price as guidePrice, produce_time as produceTime, car_type as carType
from t_car order by produce_time 'asc'
${}的执行结果:
Preparing:
select id, car_num as carNum, brand, guide_price as guidePrice, produce_time as produceTime, car_type as carType
from t_car order by produce_time asc //先拼接再编译,asc直接以关键字拼接
Parameters:向 **SQL 语句当中拼接表名,就需要使用
${}
**。现实业务当中,可能会存在分表存储数据的情况。因为一张表存的话,数据量太大,查询效率比较低。可以将这些数据有规律的分表存储,这样在查询的时候效率就比较高,因为扫描的数据量变少了。
例如:日志表,专门存储日志信息的。如果
t_log
只有一张表,这张表中每一天都会产生很多log
,慢慢的,这个表中数据会很多。怎么解决?可以每天生成一个新表。每张表以当天日期作为名称,例如:
t_log_20220901
、t_log_20220902
……你想知道某一天的日志信息怎么办?-> 假设想查的日期是 20220901,那么直接查:
t_log_20220901
的表即可。所以 SQL 语句可以写成SELECT * FROM t_log_${date}
。
批量删除:一次删除多条记录。
批量删除的 SQL 语句有两种写法:
- 第一种
or
:delete from t_car where id=1 or id=2 or id=3;
- 第二种
in
:delete from t_car where id in(1,2,3);
应该采用
${}
的方式:delete from t_car where id in(${ids});
- 第一种
模糊查询:
like
。需求:根据汽车品牌进行模糊查询。例如:
select * from t_car where brand like '%奔驰%';
如果使用语句
select * from t_car where brand like '%#{brand}%';
,首先该语句会被预编译为select * from t_car where brand like '%?%';
,然后再给占位符传值。但是占位符?
被''
括起来了,就会被认为是字符串,就无法进行传值。所以需要使用下面的几种方案。- 第一种方案:
'%${brand}%'
- 第二种方案:
concat
函数,这个是 mysql 数据库当中的一个函数,专门进行字符串拼接:concat('%',#{brand},'%')
- 第三种方案:
"%"#{brand}"%"
- 第一种方案:
9.2 typeAliases起别名
mybatis 中的别名,通过在
mybatis-config.xml
文件中,配置typeAliases
标签进行设置,用于给resultType
的全限定类名取别名。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
<configuration>
<properties resource="jdbc.properties"/>
<!--起别名-->
<typeAliases>
<!--type:指定给哪个类型起别名-->
<!--alias:指定别名-->
<!--<typeAlias type="com.f.mybatis.pojo.Car" alias="car"/>-->
<!--使用默认的别名,默认的别名就是类的简名-->
<!--<typeAlias type="com.f.mybatis.pojo.Car"/>-->
<!--包下所有的类自动起别名。使用简名作为别名。-->
<package name="com.f.mybatis.pojo"/>
</typeAliases>
<environments default="mybatisDB">
<environment id="mybatisDB">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="CarMapper.xml"/>
</mappers>
</configuration>注意:
- 所有别名不区分大小写。
namespace
不能使用别名机制。alias
可以省略,省略alias
之后,默认别名就是类的简名,例如com.f.mybatis.pojo.Car
的默认别名就是Car
、car
、CAR
…(因为不区分大小写)
<package name="com.f.mybatis.pojo"/>
这一行配置会将该包下的所有类自动起别名,并使用默认别名,即使用类的简名作为别名。1
2
3<typeAliases>
<package name="com.f.mybatis.pojo"/>
</typeAliases>
9.3 mappers标签属性
mapper
标签的属性可以有三个:resource
:这种方式是从类的根路径下开始查找资源。采用这种方式的话,你的配置文件需要放到类路径当中才行。<mapper resource="CarMapper.xml"/>
要求类的根路径下必须有:
CarMapper.xml
url
:这种方式是一种绝对路径的方式,这种方式不要求配置文件必须放到类路径当中,哪里都行,只要提供一个绝对路径就行。这种方式使用极少,因为移植性太差。<mapper url="file:///d:/CarMapper.xml"/>
要求在 d:/ 下有
CarMapper.xml
文件
class
:这个位置提供的是mapper
接口的全限定接口名,必须带有包名的。<mapper class="全限定接口名,带有包名"/>
思考:
mapper
标签的作用是指定SqlMapper.xml
文件的路径,指定接口名有什么用呢?如果你的
class
指定是:com.f.mybatis.mapper.CarMapper
,即<mapper class="com.f.mybatis.mapper.CarMapper"/>
, 那么 mybatis 框架会自动去CarMapper
接口的同级目录下找CarMapper.xml
文件,也就是去com/f/mybatis/mapper
目录下查找CarMapper.xml
文件。也就是说:如果你采用这种方式,那么你必须保证
CarMapper.xml
文件和CarMapper
接口必须在同级目录下,并且名字一致。同级目录,
CarMapper
接口存放在com.f.mybatis.mapper
包下,而CarMapper.xml
文件则存放在com/f/mybatis/mapper
目录下。
当构建、编译生成
target
文件夹后,接口和配置文件就是在同一个目录下了,因为java
是类的根路径,resources
同样也是类的根路径。
既然可以使用
class
作为找 xml 配置文件的依据,如果 class 较多,那就可以更进一步简化,用包名的方式进行简化。1
2
3
4
5<mappers>
<!--这种方式在实际开发中是使用的-->
<!--前提:XML必须和接口放在同级目录下,并且名字一致-->
<package name="com.f.mybatis.mapper"/>
</mappers>
9.4 idea配置文件模板
mybatis-config.xml
和SqlMapper.xml
文件可以在 IDEA 中提前创建好模板,以后通过模板创建配置文件。
mybatis-config.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<!-- mybatis-config.xml文件 -->
<configuration>
<properties resource=""/>
<typeAliases>
<package name=""/>
</typeAliases>
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name=""/>
</mappers>
</configuration>1
2
3
4
5
6
7
<mapper namespace="">
</mapper>以后在创建 XML 配置文件的时候,就可以使用模板了: