- 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 配置文件的时候,就可以使用模板了:
