MyBatis 动态SQL和缓存机制实例详解
|
有的时候需要根据要查询的参数动态的拼接SQL语句 常用标签: - if:字符判断 - choose【when...otherwise】:分支选择 - trim【where,set】:字符串截取,其中where标签封装查询条件,set标签封装修改条件 - foreach: if案例 1)在EmployeeMapper接口文件添加一个方法 public Student getStudent(Student student); 2)如果要写下列的SQL语句,只要是不为空,就作为查询条件,如下所示,这样写实际上是有问题的,所以我们要写成动态SQL语句:
<select id="getEmployeeByConditionIf" resultType="com.neuedu.entity.Employee">
select *from tbl_employee where id = #{id} and user_name = #{userName} and email = #{email} and gender = #{gender}
</select>
3)用if标签改写为动态SQL,如下所示: test:判断表达式(OGNL):OGNL参照PPT或者官方文档。 test从参数中取值进行判断 遇见特殊符号,应该去写转义字符:如<>分别为<,>
<select id="getStudent" resultType="com.neuedu.mybatis.entity.Student">
SELECT *
FROM student
where
<if test="id != null">
id=#{id}
</if>
<if test="name !=null and name!=''">
and name=#{name}
</if>
<if test="password !=null and password !=''">
and password=#{password}
</if>
<if test="email !=null and email !=''">
and email=#{email}
</if>
</select>
4)测试代码
@Test
public void TestgetStudent(){
StudentMapper bean = ioc.getBean(StudentMapper.class);
Student student = new Student(4,"jack","111","jack@qq.com");
System.out.println(student);
Student student2 = bean.getStudent(student);
System.out.println(student2);
}
#测试结果没问题,
但是仔细来说,上面的sql语句是有问题的,当我们不给动态sql语句传递id值的时候,sql语句的拼装就会有问题!【name前有一个and】 - where 标签 解决办法 1.给where后面加上1=1,以后的条件都可以使用and xxx了 2.可以使用 where 标签来将所有的查询条件包括在内 mybatis就会将where标签中拼装的sql,多出来的and或者or去掉!
<select id="getStudent" resultType="com.neuedu.mybatis.entity.Student">
SELECT *
FROM student
<where>
<if test="id != null">
id=#{id}
</if>
<if test="name !=null and name!=''">
and name=#{name}
</if>
<if test="password !=null and password !=''">
and password=#{password}
</if>
<if test="email !=null and email !=''">
and email=#{email}
</if>
</where>
</select>
3.需要注意:where标签只会去掉第一个多出来的and或者or 也就是说使用where标签有时候还是不能解决问题的,那怎么办呢?我们这里可以使用trim标签! - trim标签:可以自定义字符串的截取规则 后面多出的and或者or where标签不能够解决
<select id="getStudent" resultType="com.neuedu.mybatis.entity.Student">
SELECT *
FROM student
<trim prefix="where" prefixOverrides="and">
<if test="id != null">
id=#{id}
</if>
<if test="name !=null and name!=''">
and name=#{name}
</if>
<if test="password !=null and password !=''">
and password=#{password}
</if>
<if test="email !=null and email !=''">
and email=#{email}
</if>
</trim>
</select>
- choose标签:分支选择,类似于Java中的带了break的switch...case 相当于确保了第一个case 符合之后,就跳出 案例演示: 1.在EmployeeMapper接口中添加一个方法 public List<Student> getStus(Student student); 2.sql映射文件
<select id="getStus" resultType="com.neuedu.mybatis.entity.Student">
select * from student
<where>
<choose>
<when test="id !=null">
id = #{id}
</when>
<when test="name !=null and name!=''">
name = #{name}
</when>
<when test="password !=null and password!=''">
password = #{password}
</when>
<when test="email !=null and email!=''">
email = #{email}
</when>
<otherwise>
1 = 1
</otherwise>
</choose>
</where>
</select>
- set标签:字符串截取,可以写在trim里面 set元素会动态前置set关键字,同时也会消除无关的逗号 1)在EmployeeMapper中添加一个更新的方法 public void updateStu(Student student); 2)在sql映射文件中,填写相应的sql语句,如下所示【set标签可以将字段后面的逗号去掉】
<update id="updateStu">
update student
<set>
<if test="name !=null and name!=''">
name=#{name},</if>
<if test="password !=null and password !=''">
password=#{password},</if>
<if test="email !=null and email !=''">
email=#{email}
</if>
</set>
where id = #{id}
</update>
3)测试类代码为
@Test
public void TestUpdateStu(){
StudentMapper bean = ioc.getBean(StudentMapper.class);
bean.updateStu(new Student(4,"jackk",null,null));
}
将set标签用trim标签代替
<update id="updateStu">
update student
<trim prefix="set" suffixOverrides=",">
<if test="name !=null and name!=''">
name=#{name},</if>
<if test="email !=null and email !=''">
email=#{email}
</if>
</trim>
where id = #{id}
</update>
- foreach:遍历元素 动态SQL的另一个常用的操作是需要对一个集合进行遍历,通常在构建in条件语句的时候! foreach元素允许指定一个集合,声明集合项和索引变量,并可以指定开闭匹配的字符串以及在迭代之间放置分隔符。 案例演示: 1.在EmployeeMapper接口中加入一个方法
public List<Student> getStuByIdForEach(@Param("ids")List<Integer> ids);
2.在MyBatis的sql映射文件中写相应的代码
<select id="getStuByIdForEach" resultType="com.neuedu.mybatis.entity.Student">
select * from student
where id
in
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
3.测试类代码
@Test
public void getStuByIdForEach(){
StudentMapper bean = ioc.getBean(StudentMapper.class);
List<Integer> list = Arrays.asList(16,17,18,19);
List<Student> stuByIdForEachlist = bean.getStuByIdForEach(list);
for (Student student : stuByIdForEachlist) {
System.out.println(student);
}
}
foreach标签还可以用于批量保存数据, 1.在EmployeeMapper接口类中添加批量插入的方法
public void insertStus(@Param("stus")List<Student> student);
2.在EmployeeMapper.xml的sql映射文件中添加响应的语句 foreach 中用 collection,collection中是从Mapper接口传来的参数,separator是去掉中间符号
<insert id="insertStus">
insert into student (name,password,email) values
<foreach collection="stus" item="stu" separator=",">
(#{stu.name},#{stu.password},#{stu.email})
</foreach>
</insert>
(编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
