目录
本次博文包括比较零散的MyBatis内容,包括MyBatis的连接池、事务和动态SQL语句的用法。
1 MyBatis连接池
实际开发中都会使用连接池,因为可以减少获取连接消耗的时间,连接池就是用来存储连接的一个容器,通常用一个集合对象表示,该集合必须是线程安全的,不能两个线程拿到同一个连接,该集合还必须实现队列的特性,先进先出。
MyBatis连接池的配置有3种方式,在主配置文件SqlMapConfig.xml的dataSource标签配置,其中type属性表示了采用了哪种连接池方式:
- 1)POOLED:传统的javax.sql.DataSource规范中的连接池,MyBatis有规范的实现;
- 2)UNPOOLED:传统的获取连接的方式,也实现了javax.sql.DataSource接口,但没有使用池的思想,每次用都是重新获取连接;
- 3)JNDI:采用服务器提供的JNDI技术实现,来获取DataSource对象,不同服务器能拿到的DataSource不同。需要注意的是,这种方式若不是web或maven的war工程,是不能使用的。如Tomcat服务器采用的是dbcp连接池。
1.1 UNPOOLED配置连接池的原理
我们使用上一博文的工程为基础进行演示分析,首先把SqlMapConfig.xml的dataSource标签的type属性取值为POOLED,运行测试类中的testFindAll方法,观察打印输出的信息:
再把SqlMapConfig.xml的dataSource标签的type属性取值为UNPOOLED,运行测试类中的testFindAll方法,观察打印输出的信息:
以上对比,我们可以知道,在使用UNPOOLED时,是直接创建连接的,用完后就关闭了,没有池子。
实际上UNPOOLED和POOLED分别对应的类是UnpooledDataSource和PooledDataSource,我们在在IDEA中打开UnpooledDataSource类,一路跟踪方法,可以发现这个原理:
getConnection()方法->doGetConnection()方法->doGetConnection():
1.2 POOLED配置连接池的原理
打开PooledDataSource类,一路跟踪方法:getConnection()->popConnection():
我们实际开发中一般都是使用POOLED。
2 MyBatis的事务
关于事务,不做过多说明了,可以参照下之前的博文。MyBatis中的事务是通过SqlSession对象的commit方法和rollback方法实现事务的提交和回滚。在上一博文中,我们对数据库的增删改查操作发现,必须使用sqlSession.commit()方法提交事务,原因是什么呢?
那是因为从连接池取出的连接都会调用connection.setAutoCommit(false)方法关闭自动提交事务,这一点从打印的信息就可以验证:
所以,要想不进行手动提交事务,是可以设置的,在此处设置为true即可:
【注意】:设置自动提交事务,这种在实际开发中也是不常用的,因为每一次操作数据库都要提交一次事务,这会加大开销,最明显的例子就是往数据库中批量插入数据时,每次都提交一次事务的话,插入速度是很慢的。
3 MyBatis的动态SQL用法
由上一博文我们熟悉了使用MyBatis的CRUD简单操作,但是我们发现操作的输入条件都比较单一,或者是指定id查询的、或者是查询所有的、或者是根据用户名模糊查询的,那要是实际业务中涉及到查询条件比较复杂的场景该怎么办?所以,这里就用到了动态SQL。
3.1 if标签的使用
if标签在多条件组合查询中比较常用,根据实体类的不同取值,使用不同的sql语句查询,以一个具体的例子看下用法:
1)用户接口中添加 根据输入的参数条件查询 方法:
-
//用户持久层接口
-
public
interface UserDao {
-
//根据输入的参数条件查询,user就是查询的条件,可能只有其中一个属性,也可能都有或都没有
-
List<User> findUserByCondition(User user);
-
}
2)用户映射配置文件中配置,注意if的写法格式,其中的1个条件内的组合用 and连接(不能用&&),有多个条件就用多个if标签
-
<!-- 根据条件查询-->
-
<select id="findUserByCondition" parameterType="com.winter.domain.User" resultType="com.winter.domain.User">
-
select *from user where 1=1
-
<if test="username != null and username != ''">
-
and username LIKE #{username}
-
</if>
-
<if test="sex != null and sex != ''">
-
and sex = #{sex}
-
</if>
-
</select>
3)测试类中进行测试:查询姓名中包含“王”的女性用户
-
//测试使用动态sql查询
-
@Test
-
public void testFindByCondition(){
-
User user =
new User();
-
user.setUsername(
"%王%");
-
user.setSex(
"女");
-
List<User> users = userDao.findUserByCondition(user);
-
for (User user1 : users) {
-
System.out.println(user1);
-
}
-
}
3.2 where标签的使用
上述if标签 select * from user 后要加个条件whre 1=1,这个就是让其永远为真,理解起来挺另类的,所以可以使用where标签,更直观些,使用起来比较方便,就是将if内的条件用where标签包裹起来,映射配置文件中修改如下:
-
<!-- 根据条件查询-->
-
<select id="findUserByCondition" parameterType="com.winter.domain.User" resultType="com.winter.domain.User">
-
select *from user
-
<where>
-
<if test="username != null and username != ''">
-
and username LIKE #{username}
-
</if>
-
<if test="sex != null and sex != ''">
-
and sex = #{sex}
-
</if>
-
</where>
-
</select>
3.3 foreach标签的使用
若我们要查询多个指定id用户信息该怎么办?SQL语句是很容易写的:select * from user where id in(1,2),但是在MyBatis映射配置文件中如何传递参数呢? 这时候就用到了foreach标签,其就是来遍历集合的,属性如下:
collection | 要遍历的集合元素 |
open | 语句的开始部分 |
close | 语句结束部分 |
item | 遍历集合的每个元素,生产的变量,可以自定义,但要和#{}中的保持一致 |
sperator | 分隔符 |
1)QueryVo类中添加ids List集合;
2)用户接口中添加 根据QueryVo的id集合查询用户 方法:
-
public
interface UserDao {
-
//根据QueryVo的id集合查询用户
-
List<User> findUserInIds(QueryVo vo);
-
}
3)用户映射配置文件中配置,注意foreach的写法格式,注意item 属性名要和 #{}中的保持一致;
-
<select id="findUserInIds" parameterType="com.winter.domain.QueryVo" resultType="com.winter.domain.User">
-
select * from user
-
<where>
-
<if test="ids != null and ids.size()>0">
-
<foreach collection="ids" open="and id in(" close=")" item="uid" separator=",">
-
#{uid}
-
</foreach>
-
</if>
-
</where>
-
</select>
4)测试类中进行测试:查询id为1和2 的用户信息
-
//测试使用QueryVo作为查询条件
-
@Test
-
public void testFindUserInIds(){
-
QueryVo vo =
new QueryVo();
-
List<Integer> ids =
new ArrayList<>();
-
ids.add(
1);
-
ids.add(
2);
-
vo.setIds(ids);
-
//5.执行查询
-
List<User> users = userDao.findUserInIds(vo);
-
for (User user1 : users) {
-
System.out.println(user1);
-
}
-
}
———————————————————————————————————
本文为博主原创文章,转载请注明出处!
若本文对您有帮助,轻抬您发财的小手,关注/评论/点赞/收藏,就是对我最大的支持!
祝君升职加薪,鹏程万里!
转载:https://blog.csdn.net/w464960660/article/details/108606644