Mybatis的事务控制
在 JDBC中我们可以通过手动方式将事务的提交改为手动方式,通过setAutoCommit()方法就可以调整。Mybatis框架因为是对JDBC的封装,所以Mybatis框架的事务控制方式,本身也是用 JDBC 的setAutoCommit()方法来设置事务提交方式的。
之前的CUD(增删改) 操作过程中,我们都要手动进行事务的提交,原因是setAutoCommit()方法,在执行时它的值被设置为false了,所以我们在CUD操作中,必须通过sqlSession.commit()方法来执行提交操作。
设置自动提交事务
为什么CUD过程中必须使用sqlSession.commit()提交事务?
主要原因就是在连接池中取出的连接,都会将调用connection.setAutoCommit(false)方法,这样我们就必须使用 sqlSession.commit()方法,相当于使用了JDBC中的 connection.commit()方法实现事务提交。
设置自动提交事务代码
//4.创建 SqlSession 对象 false改成true就会自动执行session.commit自动提交
//SqlSession session = sqlSessionFactory.openSession(false);
session = factory.openSession(true);
Mybatis的动态SQL语句
Mybatis的映射文件中,前面我们的SQL都是比较简单的,有些时候业务逻辑复杂时,我们的SQL是动态变化的,此时在前面的学习中我们的SQL就不能满足要求了。
if标签
我们根据实体类的不同取值,使用不同的SQL语句来进行查询。比如在id如果不为空时可以根据id查询,如果username不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。
持久层Dao接口
/**
* 根据传入参数条件
* @param user 查询的条件:有可能有用户名,有可能有性别,也有可能有地址,还有可能是都有
* @return 实体的list集合
*/
List<User> findUserByCondition(User user);
持久层Dao映射配置
<!-- 配置 查询结果的列名和实体类的属性名的对应关系 -->
<resultMap id="userMap" type="uSeR">
<!-- 主键字段的对应 -->
<id property="userId" column="id"></id>
<!--非主键字段的对应-->
<result property="userName" column="username"></result>
<result property="userAddress" column="address"></result>
<result property="userSex" column="sex"></result>
<result property="userBirthday" column="birthday"></result>
</resultMap>
<!-- 根据条件查询-->
<select id="findUserByCondition" resultMap="userMap" parameterType="user">
select * from user where 1=1
<if test="userName != null">
and username = #{userName}
</if>
<if test="userSex != null">
and sex = #{userSex}
</if>
</select>
where标签
为了简化上面 where 1=1 的条件拼装,我们可以采用where
标签来简化开发。
<select id="findUserByCondition" resultMap="userMap" parameterType="user">
select * from user
<where>
<if test="userName != null">
and username = #{userName}
</if>
<if test="userSex != null">
and sex = #{userSex}
</if>
</where>
</select>
trim
自定义字符串截取(用的不多,根据需求选择)。
<!--public List<Employee> getEmpsByConditionTrim(Employee employee); -->
<select id="getEmpsByConditionTrim" resultType="com.coydone.mybatis.bean.Employee">
select * from tbl_employee
<!-- 后面多出的and或者or where标签不能解决
prefix="":前缀:trim标签体中是整个字符串拼串 后的结果。
prefix给拼串后的整个字符串加一个前缀
prefixOverrides="":
前缀覆盖: 去掉整个字符串前面多余的字符
suffix="":后缀
suffix给拼串后的整个字符串加一个后缀
suffixOverrides=""
后缀覆盖:去掉整个字符串后面多余的字符
-->
<!-- 自定义字符串的截取规则 -->
<trim prefix="where" suffixOverrides="and">
<if test="id!=null">
id=#{id} and
</if>
<if test="lastName!=null && lastName!=""">
last_name like #{lastName} and
</if>
<if test="email!=null and email.trim()!=""">
email=#{email} and
</if>
<!-- ognl会进行字符串与数字的转换判断 "0"==0 -->
<if test="gender==0 or gender==1">
gender=#{gender}
</if>
</trim>
</select>
choose分支选择
<!-- public List<Employee> getEmpsByConditionChoose(Employee employee); -->
<select id="getEmpsByConditionChoose" resultType="com.coydone.mybatis.bean.Employee">
select * from tbl_employee
<where>
<!-- 如果带了id就用id查,如果带了lastName就用lastName查;只会进入其中一个!! -->
<choose>
<when test="id!=null">
id=#{id}
</when>
<when test="lastName!=null">
last_name like #{lastName}
</when>
<when test="email!=null">
email = #{email}
</when>
<otherwise>
gender = 0
</otherwise>
</choose>
</where>
</select>
foreach标签
传入多个id查询用户信息,用下边两个 SQL实现:
SELECT * FROM USERS WHERE id IN (41,42,43)
这样我们在进行范围查询时,就要将一个集合中的值,作为参数动态添加进来。
在 QueryVo 中加入一个 List 集合用于封装参数。
private List<Integer> ids;
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
持久层 Dao 接口
//根据 id 集合查询用户
List<User> findInIds(QueryVo vo);
持久层 Dao 映射配置
<!-- 查询所有用户在 id 的集合之中 -->
<select id="findInIds" resultType="user" parameterType="queryvo">
<!-- select * from user where id in (1,2,3,4,5); -->
select * from user
<where>
<if test="ids != null and ids.size() > 0">
<foreach collection="ids" open="id in ( " close=")" item="uid"
separator=",">
#{uid}
</foreach>
</if>
</where>
</select>
SQL 语句:select 字段 from user where id in (?)
foreach
标签用于遍历集合,它的属性:
-
collection:代表要遍历的集合元素,注意编写时不要写
#{}
。 -
open:代表语句的开始部分。
-
close:代表结束部分。
-
item:代表遍历集合的每个元素,生成的变量名。
-
sperator:代表分隔符。
编写测试方法
@Test
public void testFindInIds() {
QueryVo vo = new QueryVo();
List<Integer> ids = new ArrayList<Integer>();
ids.add(41);
ids.add(42);
ids.add(43);
vo.setIds(ids);
//6.执行操作
List<User> users = userDao.findInIds(vo);
for(User user : users) {
System.out.println(user);
}
}
简化编写的SQL片段
定义代码片段
<sql id="defaultUser">
select * from user
</sql>
引用代码片段
<!-- 根据queryvo中的Id集合实现查询用户列表 -->
<select id="findUserInIds" resultMap="userMap" parameterType="queryvo">
<include refid="defaultUser"></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>
评论区