MyBatis 學習 (四) 動態SQL

通過mybatis提供的各種標籤方法實現動態拼接sql,這就是動態sql。

IF 標籤

接口

public interface UserDao {
   public List<User> selectUserBySexAndUserName (User user) ;
}

Mapper

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace:命名空間,用於隔離sql -->
<!-- 寫SQL語句 -->
<mapper namespace="cn.itcast.dao.UserDao" >
   <select id="selectUserBySexAndUserName" parameterType="User" resultType="User">
      select * from user
      where
      <!-- test裏面填判斷條件 -->
         <if test="sex != null and sex != ''">
             sex = #{sex}
         </if>
         <if test="username != null and username != ''">
             and username = #{username}
         </if>
   </select>
</mapper>

test

   @Test
   public void testFun2 () throws IOException
   {
       //加載核心配置文件
         String resource = "SqlMapConfig.xml" ;
         InputStream in = Resources.getResourceAsStream(resource) ;

         //創建SqlSessionFactory
         SqlSessionFactory ssf = new SqlSessionFactoryBuilder ().build(in) ;

         //創建SqlSession
         SqlSession sqlSession = ssf.openSession() ;

        UserDao userDao = sqlSession.getMapper(UserDao.class) ;

        User user = new User () ;
        user.setSex("1");
        user.setUsername("張三丰");

        List <User> list = userDao.selectUserBySexAndUserName(user);
         for ( User u  : list )
         {
           System.out.println(u);
         }

   }

若此時將setSex 註釋掉那麼 SQL語句就無法執行 如何解決?
用where 標籤

Where標籤

可以去掉sql中影響執行的and,前提:and必須在語句的前面

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace:命名空間,用於隔離sql -->
<!-- 寫SQL語句 -->
<mapper namespace="cn.itcast.dao.UserDao" >

   <select id="selectUserBySexAndUserName" parameterType="User" resultType="User">
      select * from user
      <!-- 根據性別和名字查詢用戶  where 可以去掉語句前的and.
         前提是此語句中的and影響SQL的執行
         比如說此案例中的sex字段,如果此字段爲空,
         那麼此時的sql語句就變爲 select * from user where and username = #{username}
         如果你用了where標籤,那麼標籤就可以幫你把and去掉,讓sql語句可以執行,注意只有and在語句的前面,
         where字段纔會生效
       -->
      <where>
      <!-- test裏面填判斷條件 -->
         <if test="sex != null and sex != ''">
             sex = #{sex}
         </if>
         <if test="username != null and username != ''">
             and username = #{username}
         </if>
      </where>
   </select>

</mapper>

SQL片段

即將重複的sql語句部分抽取出來,留作共用
用到兩個標籤
sql
include

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace:命名空間,用於隔離sql -->
<!-- 寫SQL語句 -->
<mapper namespace="cn.itcast.dao.UserDao" >

   <sql id="select">
      select * from user
   </sql>


   <select id="selectUserBySexAndUserName" parameterType="User" resultType="User">

      <!-- 引用抽取出來的sql片段 -->
      <include refid="select"></include>
      <where>
      <!-- test裏面填判斷條件 -->
         <if test="sex != null and sex != ''">
             sex = #{sex}
         </if>
         <if test="username != null and username != ''">
             and username = #{username}
         </if>
      </where>

   </select>

</mapper>

foreach標籤

從字面上也能看出這是一個循環遍歷標籤,用於遍歷要傳遞到sql語句的參數

需求:根據多個id查詢用戶
分爲四種情況
1.傳遞一個數組進去
2.傳遞一個list集合
3.傳遞一個包裝類,類裏面包含一個list
4.傳遞一個包裝類,類裏面包含一個數組

先考慮第三種
傳遞一個包裝類,類裏面包含一個list
bean

public class Users {
    private User user ;

    List <Integer> list ;

    Integer [] ids  ;

    public List<Integer> getList() {
        return list;
    }

    public void setList(List<Integer> list) {
        this.list = list;
    }

    public Integer[] getIds() {
        return ids;
    }

    public void setIds(Integer[] ids) {
        this.ids = ids;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}
public class User implements Serializable {

    private static final long serialVersionUID = 1L;
    private Integer id;
    private String username;// 用戶姓名
    private String sex;// 性別
    private Date birthday;// 生日
    private String address;// 地址


    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", sex=" + sex
                + ", birthday=" + birthday + ", address=" + address + "]";
    }
}

接口

public interface UserDao {

   //根據多個id查詢用戶信息
// public List<User> selectUserByIds ( Integer [] ids ) ;
// public List<User> selectUserByIds ( List <Integer> ids ) ;
   public List<User> selectUserByIds ( Users users ) ;
}

mapper

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace:命名空間,用於隔離sql -->
<!-- 寫SQL語句 -->
<mapper namespace="cn.itcast.dao.UserDao" >

   <sql id="select">
      select * from user
   </sql>

   <!-- 多個id查詢用戶 (1,2,3)-->
   <select id="selectUserByIds" parameterType="users" resultType="user">
      <include refid="select"></include>
      <where>
         id in
         <foreach collection="list" item="id" separator="," open="(" close=")" >
            #{id}
         </foreach>
      </where>
   </select>

</mapper>

測試

   @Test
   public void testFun3 () throws IOException
   {
       //加載核心配置文件
         String resource = "SqlMapConfig.xml" ;
         InputStream in = Resources.getResourceAsStream(resource) ;

         //創建SqlSessionFactory
         SqlSessionFactory ssf = new SqlSessionFactoryBuilder ().build(in) ;

         //創建SqlSession
         SqlSession sqlSession = ssf.openSession() ;

        UserDao userDao = sqlSession.getMapper(UserDao.class) ;

        Users user = new Users () ;
        List <Integer> list = new ArrayList <Integer> ();
        list.add(1) ;
        list.add(10) ;
        list.add(12) ;
        user.setList(list) ;

       List<User> list2 =  userDao.selectUserByIds(user);

       for ( User u : list2 )
       {
         System.out.println(u);
       }
   }

傳遞一個包裝類,類裏面包含一個數組

bean

public class Users {
    private User user ;

    List <Integer> list ;

    Integer [] ids  ;

    public List<Integer> getList() {
        return list;
    }

    public void setList(List<Integer> list) {
        this.list = list;
    }

    public Integer[] getIds() {
        return ids;
    }

    public void setIds(Integer[] ids) {
        this.ids = ids;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

xml

   <!-- 多個id查詢用戶 (1,2,3)-->
   <select id="selectUserByIds" parameterType="users" resultType="user">
      <include refid="select"></include>
      <where>
         id in
         <foreach collection="ids" item="id" separator="," open="(" close=")" >
            #{id}
         </foreach>
      </where>
   </select>

test

   @Test
   public void testFun4 () throws IOException
   {
       //加載核心配置文件
         String resource = "SqlMapConfig.xml" ;
         InputStream in = Resources.getResourceAsStream(resource) ;

         //創建SqlSessionFactory
         SqlSessionFactory ssf = new SqlSessionFactoryBuilder ().build(in) ;

         //創建SqlSession
         SqlSession sqlSession = ssf.openSession() ;

        UserDao userDao = sqlSession.getMapper(UserDao.class) ;

        Users users = new Users () ;

        Integer [] arr =  new Integer [] { 1 , 12 , 13 };
        users.setIds(arr);

       List<User> list2 =  userDao.selectUserByIds(users);

       for ( User user : list2 )
       {
         System.out.println(user);
       }
   }

下面考慮第一和第二種情況
傳遞list或數組,那麼在collection就要填入關鍵字 list 或 array 方可遍歷 ,注意遇到這種情況時parameterType 可以瞎寫或者不寫

array

@Test
   public void testFun4 () throws IOException
   {
       //加載核心配置文件
         String resource = "SqlMapConfig.xml" ;
         InputStream in = Resources.getResourceAsStream(resource) ;

         //創建SqlSessionFactory
         SqlSessionFactory ssf = new SqlSessionFactoryBuilder ().build(in) ;

         //創建SqlSession
         SqlSession sqlSession = ssf.openSession() ;

        UserDao userDao = sqlSession.getMapper(UserDao.class) ;

        Users users = new Users () ;

        Integer [] arr =  new Integer [] { 1 , 15 , 16 };
        users.setIds(arr);

       List<User> list2 =  userDao.selectUserByIds(arr);

       for ( User user : list2 )
       {
         System.out.println(user);
       }
   }
   <!-- 多個id查詢用戶 (1,2,3)-->
   <select id="selectUserByIds"  resultType="user">
      <include refid="select"></include>
      <where>
         id in
         <foreach collection="array" item="id" separator="," open="(" close=")" >
            #{id}
         </foreach>
      </where>
   </select>

list

   @Test
   public void testFun6 () throws IOException
   {
       //加載核心配置文件
         String resource = "SqlMapConfig.xml" ;
         InputStream in = Resources.getResourceAsStream(resource) ;

         //創建SqlSessionFactory
         SqlSessionFactory ssf = new SqlSessionFactoryBuilder ().build(in) ;

         //創建SqlSession
         SqlSession sqlSession = ssf.openSession() ;

        UserDao userDao = sqlSession.getMapper(UserDao.class) ;

        List <Integer> list = new ArrayList <Integer> ();
        list.add(1) ;
        list.add(10) ;
        list.add(12) ;

       List<User> list2 =  userDao.selectUserByIds(list);

       for ( User u : list2 )
       {
         System.out.println(u);
       }
   }
   <!-- 多個id查詢用戶 (1,2,3)-->
   <select id="selectUserByIds"  resultType="user">
      <include refid="select"></include>
      <where>
         id in
    <!-- foreach標籤,進行遍歷 -->
       <!-- collection:遍歷的集合,這裏是QueryVo的ids屬性 -->
       <!-- item:遍歷的項目,可以隨便寫,,但是和後面的#{}裏面要一致 -->
       <!-- open:在前面添加的sql片段 -->
       <!-- close:在結尾處添加的sql片段 -->
       <!-- separator:指定遍歷的元素之間使用的分隔符 -->
         <foreach collection="list" item="id" separator="," open="(" close=")" >
            #{id}
         </foreach>
      </where>
   </select>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章