<set>元素
在Hibernate中,如果想要更新某一个对象,就需要发送所有的字段给持久化对象,然而实际应用中,大多数情况下都是更新的某一个或几个字段。如果更新的每一条数据都要将其所有的属性都更新一遍,那么其执行效率是非常差的。有没有办法让程序只更新需要更新的字段呢?
为了解决上述情况中的问题,MyBatis中提供了<set>元素来完成这一工作。<set>元素主要用于更新操作,其主要作用是在动态包含的SQL语句前输出一个SET关键字,并将SQL语句中最后一个多余的逗号去除。
以入门案例中的更新操作为例,使用<set>元素对映射文件中更新客户信息的SQL语句进行修改的代码如下所示。
<!-- <set>元素 -->
<update id="updateCustomer" parameterType="com.itheima.po.Customer">
update t_customer
<set>
<if test="username !=null and username !=''">
username=#{username},
</if>
<if test="jobs !=null and jobs !=''">
jobs=#{jobs},
</if>
<if test="phone !=null and phone !=''">
phone=#{phone},
</if>
</set>
where id=#{id}
</update>
在上述配置的SQL语句中,使用了<set>和<if>元素相结合的方式来组装update语句。其中<set>元素会动态前置SET关键字,同时也会消除SQL语句中最后一个多余的逗号;<if>元素用于判断相应的字段是否传入值,如果传入的更新字段非空,就将此字段进行动态SQL组装,并更新此字段,否则此字段不执行更新。
为了验证上述配置,可以在测试类中编写测试方法updateCustomerTest(),其代码如下所示。
/**
* 更新客户
*/
@Test
public void updateCustomerTest(){
// 获取SqlSession
SqlSession sqlSession = MybatisUtils.getSession();
// 创建Customer对象,并向对象中添加数据
Customer customer = new Customer();
customer.setId(3);
customer.setPhone("13311111234");
// 执行SqlSession的更新方法,返回的是SQL语句影响的行数
int rows = sqlSession.update("com.itheima.mapper"
+ ".CustomerMapper.updateCustomer", customer);
// 通过返回结果判断更新操作是否执行成功
if(rows > 0){
System.out.println("您成功修改了"+rows+"条数据!");
}else{
System.out.println("执行修改操作失败!!!");
}
// 提交事务
sqlSession.commit();
// 关闭SqlSession
sqlSession.close();
}
从上述代码可以看出,与入门案例中的更新方法有所不同的是,这里只设置了其id和Phone的属性值,也就是需要修改id为3的客户电话信息。
使用JUnit4执行updateCustomerTest()方法后,控制台的输出结果如图1所示。
图1 运行结果
从图1可以看出,控制台中已经提示成功更新了1条数据。为了验证是否真的执行成功,此时查看数据库t_customer表中的数据,如图2所示。
图2 t_customer表
从图2可以看出,使用<set>元素已成功对数据表中id为3的客户电话进行了修改。
由于篇幅有限,本案例中未演示不使用<set>元素时,执行单个字段更新的情况,读者可以自行修改入门案例进行测试。
注意:
在映射文件中使用<set>和<if>元素组合进行update语句动态SQL组装时,如果<set>元素内包含的内容都为空,则会出现SQL语法错误。所以在使用<set>元素进行字段信息更新时,要确保传入的更新字段不能都为空。