天天看點

MyBatis之動态sql

如果使用JDBC或者Hibernate等ORM架構,很多時候你要根據需要去拼接sql,這是一個很麻煩的事情。而MyBatis提供對動态sql的組裝能力,而且它隻有為數不多的幾個基本元素,簡單明了,大量的判斷可以在MyBatis的映射檔案xml進行配置,以達到我們需要編寫大量代碼才能實作的需求。動态sql減少了很多編寫代碼量的工作。

這從中又展現了MyBatis的優點,可配置性,靈活性和可維護性。

MyBatis之動态sql

注意該例子在MyBatis+Hibernate+JDBC分析對比的文章上基礎進行的

下面進行對上述表中的例子進行示範:

package cn.mybatis;

import org.apache.ibatis.annotations.Param;

public interface UserMapper {

    
    User getUserById(Integer Id);
    //注意@Param 适用場景針對于參數n<=5的情況下進行,如果參數n大于5以上建議将參數改為JavaBean
    User getUserByName(@Param("userName") String userName);
}      

if示範示例:

<?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">
<mapper namespace="cn.mybatis.UserMapper">
    <!--如果一部分字段查詢比較頻繁,建議使用sql标簽,将查詢過頻繁的字段放進去,這樣方面管理和修改-->    
    <sql id="user">
    id,user_name
    </sql>
    
    <select id="getUserById" parameterType="Integer" resultMap="users">
        select <include refid="user"/> from `user` where id=#{Id}
    </select>    
    
    <!-- 
    if标簽主要适用于多條件查詢,例如分頁查詢,比如部落格,比如時間日期,标簽類型,時間類型等等
     單個條件可以使用下面的例子
      如果條件多的話,建議在<if></if>外嵌套<where>标簽
    -->
     <select id="getUserByName" parameterType="String" resultMap="users">
         select     id,user_name from `user` where
         <if test="userName!=null and userName !=''">
              user_name like concat ('%',#{userName},'%')             
         </if>
     </select>


     
    <resultMap type="User" id="users">
    <id column="id" property="Id"/>
    <result column="user_name" property="userName"/>
    </resultMap>

</mapper>      

choosey示範示例:

<?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">
<mapper namespace="cn.mybatis.UserMapper"> 
      
     <!-- 
     Choose相當于Java中的
     if(..){
     }else if(..){
     }else{
     
     }
     otherwise這裡就不做示範了,otherwise相當于否則的意思,可以說就是else
      
      注意 在外層必須嵌套<where>标簽,否則會一直顯示sql錯誤
      -->
      
           <select id="getUserByName" parameterType="Map" resultMap="users">
           select * from `user`
           <where>
           <choose>
           <when test="Id!=null and Id!=''">
               and id = #{Id}
           </when>
            <when test="userName != null and userName != ''">
               and  user_name = #{userName}
            </when>     
           </choose>
           </where>
          
     </select>
     
    <resultMap type="User" id="users">
    <id column="id" property="Id"/>
    <result column="user_name" property="userName"/>
    </resultMap>

</mapper>      

接口類

package cn.mybatis;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Param;

public interface UserMapper {

    
    User getUserByName(Map<String,Object> map);
}      

測試類

package cn.mybatis;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

public class TestMyBatis {

    public static void main(String[] args) {
        SqlSession sqlSession = null;
        sqlSession = MyBatisExample.getSqlSessionFactory().openSession();
        
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User users = new User();
        users.setId(1);
        users.setUserName(null);
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("user", users);
        User user = userMapper.getUserByName(map);
        System.out.println(user.getUserName());
        
        
        

    }
}      

trim示範示例:

<?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">
<mapper namespace="cn.mybatis.UserMapper">
     
     <!-- 
     trim意味着去掉一些特殊字元
     trim prefix表示字首 通常加上where的話,表示已經将where寫進字首,這時就不用寫where了
     prefixOverrides 表示将第一個and或者or去掉 
      -->
      <select id="getUserByName" parameterType="String" resultMap="users">
         select id,user_name from `user`
         <trim prefix="where" prefixOverrides="and|or">
            <if test="userName!=null">
             and user_name = #{userName}    
             </if>
         </trim>
     </select>
  
     
    <resultMap type="User" id="users">
    <id column="id" property="Id"/>
    <result column="user_name" property="userName"/>
    </resultMap>

</mapper>      

接口類:

package cn.mybatis;



import org.apache.ibatis.annotations.Param;

public interface UserMapper {

    
    
    User getUserByName(@Param ("userName") String userName);
}      

測試類:

package cn.mybatis;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

public class TestMyBatis {

    public static void main(String[] args) {
        SqlSession sqlSession = null;
        sqlSession = MyBatisExample.getSqlSessionFactory().openSession();
        
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.getUserByName("張飛");
        System.out.println(user.getUserName());
        
        
        

    }
}      

set

<?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">
<mapper namespace="cn.mybatis.UserMapper">


     
      

     <!--
  set 當滿足條件時繼續下一個,否則報錯,這裡也相當于做一個判斷驗證
     -->
     
<!--      <update id="updateUserInfo" parameterType="User">
      update `user`
      <set>
          <if test="userName != null and userName !='' ">
           user_name = #{userName}
          </if>
      </set>
      where id = #{Id}
     </update> -->
    
<!--
trim在這裡也可以應用
-->
    <update id="updateUserInfo" parameterType="User">
     update `user`
     <trim prefix="set" prefixOverrides=",">
     
     <if test="userName !=null and userName !=''">
     user_name = #{userName}
     </if>
     </trim>
    where id= #{Id}
    </update>
         
    <resultMap type="User" id="users">
    <id column="id" property="Id"/>
    <result column="user_name" property="userName"/>
    </resultMap>

</mapper>      
package cn.mybatis;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Param;

public interface UserMapper {

    
    
    int updateUserInfo(User user);
    
}      
package cn.mybatis;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

public class TestMyBatis {

    public static void main(String[] args) {
        SqlSession sqlSession = null;
        sqlSession = MyBatisExample.getSqlSessionFactory().openSession(true);
        
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        user.setId(1);
        user.setUserName("張好s");
        int lines =userMapper.updateUserInfo(user);
        if(lines==1) {
            System.out.println("Yes");
            
        }else {
            System.out.println("No");
        }
        
        

    }
}      

foreach這裡就不示範了,參照我的博文批量更新,那裡寫的比較詳細

當然接下來還有bind,不過這個不常用,以上說的包括沒說的foreach是開發過程中常用的動态sql。