文章目录
一、连接池简介
- 连接池就是用于存储连接的
一个容器
- 容器其实就是一个集合,只是该集合必须是线程安全的,不允许两个线程拿到同一个连接
- 该集合还必须满足队列的特性:先进先出
二、mybatis中的连接池
1.两种基本方式
1.1POOLED
- 采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现
- 配置方式
1.2UNPOOLED
- 采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用池的思想。
- 配置方式
2.两种方式的区别
3.UNPOOLED实现细节
- 利用
cltr+n
搜索unpooled
查看源码
- 找到
getConnection
然后按照如下顺序追踪源码
- 发现这种方式获取连接的思路就和利用JDBC获取连接一样
4.POOLED实现细节(推荐使用)
- 同样的方式,找到
pooled
的相关源码,找打getConnection
函数
- 也就是说mybatis在这种方式中,设置了两个连接池
- 所以实际开发中使用POOLED方式
三、mybatis中的事务控制的设置(暂时了解)
1、四大相关问题
- 什么是事务
- 事务的四大特性ACID
- 不考虑隔离性会产生的3个问题
- 解决办法:四种隔离级别
2.实现方式
- 它是通过
sqlsession
对象的commit
方法和rollback
方法实现事务的提交和回滚
3.细节分析
分析出事务提交和回滚的最终执行代码
- 它是通过
sqlsession
对象的commit
方法和rollback
方法实现事务的提交和回滚 - 那根据前面的学习知道
sqlsession
只是接口,这里是DefaultSqlSession类实现了它
,下面进入这个类,找到相关方法
- 进入
executor
- 同样根据前文的学习,这里应该是
BaseExecutor
类实现了这个接口,下面进入这个类
- 进入
Transaction
接口,进一步进入JdbcTransaction
实现类
- 继续进入
connection
,发现都是使用的java本身的sql
相关的包
3.手动提交事务配置
- 每次执行,日志会打印输出,表示是手动提交
4.自动提交事务配置
- 查看
openssion
方法
- 设置
四、动态SQL语句
1.if标签
dao
接口新增按条件查询方法
/**
* 条件查询
* user 可能只有用户名 或者其他
* @param user
* @return
*/
List<User> findUserByCondition(User user);
- 映射配置文件中新增配置
<select id="findUserByCondition" resultType="User" parameterType="User">
select * from user where 1 = 1
<if test="username!=null">
and username = #{username}
</if>
</select>
- 注意点
- 同理,如果有多个条件,则多加几条
if
即可
<select id="findUserByCondition" resultType="User" parameterType="User">
select * from user where 1 = 1
<if test="username!=null">
and username = #{username}
</if>
<if test="sex != null">
and sex = #{sex}
</if>
</select>
2.where标签
可以去除只使用
if
标签时,必须写where 1=1
<select id="findUserByCondition" resultType="User" parameterType="User">
select * from user
<where>
<if test="username!=null">
and username = #{username}
</if>
<if test="sex != null">
and sex = #{sex}
</if>
</where>
</select>
3.foreach标签
问题引入
- 如何通过
mybatis
实现select * from user where id in(41,42,49)
呢? - 就是这种带有一个查询范围的情况如何实现呢?
foreach标签就是解决这个问题的
代码解决
QueryVo
中定义相关属性
public class QueryVo {
private User user;
List<Integer> ids;
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
dao
接口定义相关方法
/**
* 根据queryvo完成查询
* @param queryVo
* @return
*/
List<User> findUserByQueryVo(QueryVo queryVo);
- 映射配置文件相关配置
<select id="findUserInIds" resultType="user" parameterType="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>
- 测试类进行测试
@Test
public void testFindUserInIds(){
QueryVo queryVo = new QueryVo();
List<Integer> ids = new ArrayList<Integer>();
ids.add(41);
ids.add(42);
ids.add(43);
queryVo.setIds(ids);
List<User> users = userDao.findUserInIds(queryVo);
for (User item : users) {
System.out.println(item);
}
}
- 结果
-
foreach
使用注意点
4.简化sql语句的标签:sql
- 在映射配置文件中,有大量的重复的
sql
语句,这个可以通过sql
标签来一次定义,多出使用
- 基本使用
<sql id="selectAllUser">
select * from user;
</sql>
- 测试类测试通过
1.一个容易报错的细节
- 继续上述的使用,这次使用在上述配置中
<!-- 根据queryvo中的Id集合实现查询用户列表 -->
<select id="findUserInIds" resultType="user" parameterType="user" >
<!--select * from user-->
<include refid="selectAllUser"></include>
<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>
- 运行测试类,发现报错
- 这是因为在定义
sql
标签中的sql语句时加了;
号
- 去掉
;
后再运行测试类,可以通过 - 以后配置映射文件中的所有sql都不建议加分号