MyBatis 动态Sql

Posted 路过春天的雨点

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis 动态Sql相关的知识,希望对你有一定的参考价值。

               第三课(Mybatis动态SQL

目录

概述 2

本章目标 3

1.了解Mybatis动态SQL 3

2.掌握Mybatis动态SQL元素的使用 3

本章内容 3

用于实现动态SQL的元素 3

if元素 4

if元素查询数据 4

where元素 5

If+Where 查询数据 5

set元素 7

使用set更新数据 7

trim元素 8

Trim查询数据 9

Trim更改数据 10

foreach元素 11

总结 17

 

 

 

概述

     在很多情况下,查询条件并非固定不变的,而是需要根据用户的设置进行动态的组合。比如一个复杂的查询表单最多允许用户设置十个个查询条件,但用户不一定每一次设置全部的十个条件,有可能只设置其中的几个条件,或者一个也不设置。这就要求我们必须根据用户实际设置的条件来动态生成WHERE子句。下面我们就来看一下MyBatis如何实现这一点。

 

 

本章目标

1.了解Mybatis动态SQL

2.掌握Mybatis动态SQL元素的使用

3掌握Mybatis缓存的使用

本章内容

1.用于实现动态SQL的元素

     if : 利用if实现简单的条件选择

where : 简化SQL语句中的where的条件判断

set : 解决动态更新语句

trim : 可以灵活地去除多余的关键字

foreach : 迭代一个集合,通用于in条件

choose : 相当于Java中的switch语句,通常与whenotherwise搭配

 

 

if元素

if元素简单实现的条件判断,if元素的test属性表示进入if内需要满足的条件

 

if元素查询数据

1.创建mapper 中的动态SQL语句

 <!-- if 练习 -->

      <select id="getif" resultType="b">

         select * from book where

          <if test="author!=null and author!=‘‘">

             author=#{author}

          </if> 

          <if test="title and title!=‘‘">

            and title=#{title}

          </if>     

    </select>

  1. 接口方法

      //if条件查询

   public List<Book> getif(@Param("author")String author,@Param("title")String title);

  1. 编写测试代码

public List<Book> getif(){

List<Book> list=null;

 SqlSession sqlSession;

try {

String author=null;

String title="标题";

sqlSession = MybatisUtil.getSession();

// 调用mapper文件对数据进行操作

list = sqlSession.getMapper(bookmapper.class).getif(author, title);  

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return list;

}

where元素

     where元素主要用来简化SQL语句中的where条件判断,并能智能的处理andor,不必担心多于关键字的语法错误

 

If+Where 查询数据

1.创建mapper 中的动态SQL语句

 <!-- 动态 where 查询 -->

 <select id="getwheres" resultType="b">

      select * from book

        <where>

           <if test="author!=null and author!=‘‘">

               and author=#{author}

           </if>          

           <if test="title and title!=‘‘">

             and title=#{title}

           </if>            

       </where>

  </select>

2.接口方法

   //动态where条件查询

   public List<Book> getwheres(@Param("author")String author,@Param("title")String title);

3.编写测试代码

public List<Book> getwhssa(){

List<Book> list=null;

 SqlSession sqlSession;

try {

String author=null;

String title="标题";

sqlSession = MybatisUtil.getSession();

// 调用mapper文件对数据进行操作

list = sqlSession.getMapper(bookmapper.class).getwheres(author, title);

 

} catch (IOException e) {

 // TODO Auto-generated catch block

e.printStackTrace();

}

return list;

}

set元素

set元素主要用于更新操作,它的主要功能和where元素差不多,主要是在包含的语句前输出一个set,若包含的语句是逗号结束,会自动把逗号忽略掉,再配合if元素就可以动态地更新需要修改的字段;而不修改的字段,则可以不再被更新。

 

使用set更新数据

1.创建mapper 中的动态SQL语句

<!--set 和if 更新数据 -->

<update id="update">

        update book

      <set>

<if test="title!=null and title!=‘‘">title=#{title},</if>

       <if test="author!=null and author!=‘‘">author=#{author},</if>

         <if test="price!=null and price!=‘‘">price=#{price},</if>         

      </set>   

        where id=#{id}  

</update>

2.接口方法

    //set更新数据

 public int update(Book book);

3.编写测试代码

public int update(){

int num=0;

 SqlSession sqlSession;

try {

Book book=new Book();

    book.setId(2);

    book.setTitle("");

    book.setAuthor("");

    book.setPrice(35.6);

sqlSession = MybatisUtil.getSession();

// 调用mapper文件对数据进行操作

 num = sqlSession.getMapper(bookmapper.class).update(book);

 sqlSession.commit();  

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return num;

}

trim元素

trim会自动识别是否有返回值,若有返回值,会在自己包含的内容前的首部加上某些前缀,也可以在其后加上某些后缀,也可以把包含内容的首部某些内容覆盖,或者把尾部的某些内容覆盖

 

trim属性:

         prefix : 前缀 在语句后面加上某些内容

       prefixOverrides  : 去除Trim内容的首部 指定内容

       suffixOverrides  :去除Trim内容的尾部 指定内容

       suffix :后缀 在语句后面加上某些内容

       

Trim查询数据
  1. 创建mapper 中的动态SQL语句

 

  <!-- Trim 查询  -->

<select id="gettrim" resultType="b">

      select * from book        

         <!-- 在if判断成立时,在if语句前加上Where  , prefixOverrides:去除trim包含的首部的内容  例and ,or-->

    <trim prefix="where" prefixOverrides="and">

        <if test="author!=null and author!=‘‘">

            and author=#{author}

        </if>           

        <if test="title and title!=‘‘">

            and title=#{title}

        </if>        

         </trim>

      </select>

  1. 接口方法

//Tirm查询

public List<Book> gettrim(@Param("author")String author,@Param("title")String title);

3.编写测试代码

public List<Book> gettrim(){

List<Book> list=null;

SqlSession sqlSession;

try {

String author="";

String title="标题";

sqlSession = MybatisUtil.getSession();

// 调用mapper文件对数据进行操作

list = sqlSession.getMapper(bookmapper.class).gettrim(author, title);  

} catch (IOException e) {

// TODO Auto-generated catch block

   e.printStackTrace();

}

return list;

}

 

 

Trim更改数据

1.创建mapper 中的动态SQL语句

 <!-- Trim 和if 更新数据 -->

  <update id="updateTrim">

        update book      

   <trim prefix="set" suffixOverrides="," suffix="where id=#{id}">

        <if test="title!=null and title!=‘‘">title=#{title},</if>

       <if test="author!=null and author!=‘‘">author=#{author},</if>

        <if test="price!=null and price!=‘‘">price=#{price},</if> 

   </trim>   

</update>

 

2.接口方法

//Tirm更新数据

   public int updateTrim(Book book);

3.编写测试代码

public int updateTrim(){

int num=0;

SqlSession sqlSession;

try {

Book book=new Book();

book.setId(2);

book.setTitle("");

book.setAuthor("试试");

book.setPrice(35.6);

sqlSession = MybatisUtil.getSession();

// 调用mapper文件对数据进行操作

num = sqlSession.getMapper(bookmapper.class).updateTrim(book);

sqlSession.commit();

 

} catch (IOException e) {

// TODO Auto-generated catch block

e.pintStackTrace();

}

return num;

}

 

foreach元素

foreach主要用在in条件中

 

主要属性:

   item: 表示迭代中每一个元素进行迭代时的别名

   index: 指定一个名称,用于表示在迭代过程中,每次迭代到的位置

   collection:

       若参数传入类型是一个List的时候,   collection属性值为list

      若参数传入类型是一个数组的时候,   collection属性值为array

      若传入参数为多参数,就需要把他们封装为一个Map进行处理

   open:表示语句以什么开始

   separator:表示每次进行迭代之间以什么符号作为分隔符

   close:表示语句以什么结束

  1. 创建mapper 中的动态SQL语句

 

<!-- foreach  array数组类型查询-->

 

 <select id="getforeach_array" resultType="b">

       select * from book where id in

       <foreach collection="array" item="id" 

         open="(" separator="," close=")">

           #{id}

       </foreach>

  </select>

      

<!-- foreach  list集合类型查询-->

 

  <select id="getforeach_list" resultType="b">

      select * from book where id in

       <foreach collection="list" item="id" 

         open="(" separator="," close=")">

           #{id}

       </foreach>

  </select>

      

 <!-- foreach  Map查询-->

 

 <select id="getforeach_Map" resultType="b">

      select * from book where  id in

      <foreach  collection="Mapid" item="id" 

         open="(" separator="," close=")">

           #{id}

     </foreach>

 </select>

      

<!-- foreach  Map多条件查询-->

 

   <select id="getforeach_Maps" resultType="b">

      select * from book where title=#{title} and id in

        <foreach  collection="Mapid" item="id" 

           open="(" separator="," close=")">

            #{id}

       </foreach>

   </select>

2.接口方法

   //foreach array数组类型查询

   public List<Book> getforeach_array(Integer[] id);

   

   // foreach list集合类型查询

   public List<Book> getforeach_list(List<Integer> id);

  

   // foreach Map查询

   public List<Book> getforeach_Map(Map<String, Object> map);

   

   // foreach Map多条件查询

   public List<Book> getforeach_Maps(Map<String, Object> map);

 

3.编写测试代码

 

/*** foreach array数组类型查询

 * @return

 */

public List<Book> getforeach_array(){

List<Book> list=null;

 SqlSession sqlSession;

try {

Integer[] id={2,3};

sqlSession = MybatisUtil.getSession();

// 调用mapper文件对数据进行操作

 list = sqlSession.getMapper(bookmapper.class).getforeach_array(id);  

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return list;

}

 

 

/**

 * foreach List集合类型查询

 * @return

 */

public List<Book> getforeach_list(){

List<Book> list=null;

 

 SqlSession sqlSession;

 List<Integer> id=new ArrayList<Integer>();

id.add(1);

id.add(2);

try {

sqlSession = MybatisUtil.getSession();

// 调用mapper文件对数据进行操作

 list = sqlSession.getMapper(bookmapper.class).getforeach_list(id);  

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return list;

}

 

/**

 * foreach Map查询

 * @return

 */

public List<Book> getforeach_Map(){

List<Book> list=null;

 

 SqlSession sqlSession;

 Map<String, Object> map=new HashMap<String, Object>();

 List<Integer> list2=new ArrayList<Integer>();

list2.add(5);

list2.add(6);

 map.put("Mapid", list2);

try {

sqlSession = MybatisUtil.getSession();

// 调用mapper文件对数据进行操作

 list = sqlSession.getMapper(bookmapper.class).getforeach_Map(map);  

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return list;

}

 

/**

 * foreach Map多条件查询

 * @return

 */

public List<Book> getforeach_Maps(){

List<Book> list=null;

 

 SqlSession sqlSession;

 Map<String, Object> map=new HashMap<String, Object>();

 List<Integer> list2=new ArrayList<Integer>();

list2.add(5);

list2.add(6);

 map.put("title", "标题");

 map.put("Mapid", list2);

try {

sqlSession = MybatisUtil.getSession();

// 调用mapper文件对数据进行操作

list = sqlSession.getMapper(bookmapper.class).getforeach_Maps(map);  

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return list;

}

Choose

<select id="findUserInfoByOneParam" parameterType="Map" resultMap="UserInfoResult">

select * from userinfo

<choose>

<when test="searchBy==‘department‘">

where department=#{department}

</when>

<when test="searchBy==‘position‘">

where position=#{position}

</when>

<otherwise>

where gender=#{gender}

</otherwise>

 

</choose>

<if test="gender!=null">

and gender=#{gender}

<span style="white-space:pre"> </span></if>

 

Mybatis的缓存策略

一级缓存为配置文件session

必须是同一个Session,如果session对象已经close()过了就不可能用了 。

二级缓存为映射文件

在配置文件中:开启二级缓存

<settings>

 <!--开启二级缓存-->

        <setting name="cacheEnabled" value="true"/>

</settings>

 

二级缓存补充说明

  1. 映射语句文件中的所有select语句将会被缓存。

  2. 映射语句文件中的所有insertupdatedelete语句会刷新缓存。

  3. 缓存会使用Least Recently UsedLRU,最近最少使用的)算法来收回。

  4. 缓存会根据指定的时间间隔来刷新。

  5. 缓存会存储1024个对象

cache标签常用属性:

<cache

eviction="FIFO"  <!--回收策略为先进先出-->

flushInterval="60000" <!--自动刷新时间60s-->

size="512" <!--最多缓存512个引用对象-->

readOnly="true"/> <!--只读-->

 

使用缓存实体全部要序列化

implements Serializable

总结

本章主要介绍mybatis的搭建方式,及两种获取数据的方式,并通过分页方法让学员熟练掌握mybatis的用法。

 

以上是关于MyBatis 动态Sql的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis 动态SQL

MyBatis:动态sql语句

mybatis 动态SQL .2

mybatis 详解------动态SQL

mybatis 详解------动态SQL

MyBatis学习——动态SQL