Mybatis 는 ognl 표현 식 을 어떻게 사용 하여 동적 sql 을 실현 합 니까?

14437 단어 Mybatisognl동적 sql
본 고 는 my batis 에서 ognl 표현 식 을 어떻게 사용 하여 동적 조립 sql 문 구 를 실현 하 는 지 설명 한다.
새 Users 실체 클래스:

public class Users {
    private Integer uid;
    private String userName;
    private String tel;
    //         get、set  
}
Dao 인터페이스 클래스 를 새로 만 듭 니 다.my batis 프로필 은 namespace 속성 을 설정 할 때 이 클래스 의 전체 클래스 이름 을 추가 해 야 합 니 다.이 클래스 의 방법 을 찾 아 실행 하 십시오.

public interface UserDao {
    /**
     *   userName      
     * @param user
     * @return
     */
    List<Users> listUser(Users user);
    /**
     *       
     * @param user
     * @return
     */
    List<Users> listUser2(Users user);
    /**
     *       
     * @param uids
     * @return
     */
    List<Users> listUser3(Integer[] uids);
    /**
     *         
     * @param user
     */
    void updateUser(Users user);
    /**
     *     
     * @param list
     */
    void addBatch(List<Users> list);
    /**
     *     
     * @param ids
     */
    void deleteBatch(int[] ids);
    /**
     *     
     * @param list
     */
    void updateBatch1(List<Users> list);
    /**
     *     
     * @param list
     */
    void updateBatch2(List<Users> list);
}
새 my batis 설정 파일(아래 코드 는 my batis 설정 파일 의 템 플 릿 으로 사용 할 수 있 습 니 다.여기 namespace 속성 은 위의 dao 류 의 전체 클래스 로 설정 할 수 있 습 니 다):

<?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  Dao       ,
  mybatis                 dao     --><mapper namespace="">   </mapper>
my batis 설정 파일 에 sql 문 구 를 조회 하 는 조건 을 쓰 십시오:

<!--     (  if    ,         ) -->
<select id="listUser" parameterType="users" resultMap="userMap">
    select u_id, u_name, u_tel from user_info4 user_info
    <where>
        <if test="userName != null and userName !=''">
            u_name = #{userName}
        </if>
        <if test="tel != null and tel !=''">
            and u_tel = #{tel}
        </if>
    </where>
</select>
여기에 where 와 if 라벨 을 사 용 했 습 니 다.는 sql 문장의 where 라 는 뜻 입 니 다.물론 where 는 sql 에 직접 써 도 됩 니 다.라벨 은 조건 판단 입 니 다.test 속성 에 조건 문 구 를 쓰 고 test 의 조건 문 구 는 true 라면 라벨 의 sql 문 구 는 위의 sql 문 구 를 연결 합 니 다.따라서 이 sql 문 구 는 전 달 된 Users 대상 에서 userName 필드 가 null 이 아니 거나 필드 값 이 비어 있 지 않 으 면 userName 에 대한 조 회 를 추가 하 라 는 뜻 입 니 다.tel 도 마찬가지 입 니 다.
메모:tel 필드 에 대한 판단 시 탭 에 있 는 sql 문 구 를 추가 합 니 다.이전 항목 이 false 로 판단 되면 my batis 는 and 키 워드 를 자동 으로 삭제 합 니 다.

<!--     (  choose    ,      ) -->
<select id="listUser2" parameterType="users" resultMap="userMap">
    select u_id, u_name, u_tel from user_info4
    <choose>
        <when test="userName != null and userName != ''">
            where u_name = #{userName}
        </when>
        <when test="tel != null and tel != ''">
            where u_tel = #{tel}
        </when>
        <otherwise>
            order by u_id desc
        </otherwise>
    </choose>
</select>
여 기 는 choose-when-otherwise 탭 을 사용 합 니 다.자바 의 switch-case-default 선택 조건 문 과 유사 합 니 다.if 탭 에 비해 하나만 선택 할 수 있 습 니 다.즉,하나 더 선택 할 수 있 습 니 다.
이 sql 문 구 는 when 절 을 순서대로 판단 합 니 다.모든 when 절 이 false 이면 other 절 에 있 는 sql 문 구 를 실행 합 니 다.

<!--     (  foreach    ,   in or  ) -->
<!-- int[] ids = new int[]{1,2,3,4}; -->
<select id="listUser3" parameterType="collection" resultMap="userMap">
    select u_id, u_name, u_tel from user_info4
    <where>
        u_id in
        <if test="array != null">
            <foreach collection="array" item="id" open="(" separator="," close=")">
                #{id}
            </foreach>
        </if>
    </where>
</select>
foreach 라벨 은 범위 조회(in 과 or 구문)에 적 용 됩 니 다.예 를 들 어 하나의 id 집합 을 옮 겨 다 니 며 집합 에 있 는 모든 id 에 대응 하 는 사용 자 를 조회 합 니 다.foreach 탭 에서 collection 속성 은 옮 겨 다 니 는 집합 이름 을 지정 합 니 다.여 기 는 하나의 인자 만 있 기 때문에 마음대로 찾 을 수 있 습 니 다.item 은 옮 겨 다 니 는 모든 항목 의 별명 을 지정 합 니 다.open 은 옮 겨 다 니 기 전에 추가 해 야 할 내용 을 지정 합 니 다.separator 는 옮 겨 다 니 면서 추가 할 내용 을 지정 합 니 다.close 는 옮 겨 다 니 기 전에 추가 해 야 할 내용 을 지정 합 니 다.예 를 들 어 위의 ids 집합 을 옮 겨 다 니 면 최종 적 으로 얻 은 내용 은(1,2,3,4)입 니 다.

<!--     (  set      ) -->
<update id="updateUser" parameterType="users" >
    update user_info4
    <trim prefix="set" suffixOverrides=",">
        <if test="userName != null and userName != ''">
            u_name = #{userName},
        </if>
        <if test="tel != null and tel != ''">
            u_tel = #{tel}
        </if>
    </trim>
    <!-- where u_id = #{uid} -->
    <where>
        u_id = #{uid}
    </where>
</update>
trim 탭 은 데 이 터 를 업데이트 할 때 변 경 된 필드 설정 을 동적 으로 설정 할 수 있 습 니 다.trim 탭 에서 prefix 속성 은 필드 를 업데이트 하기 전에 set 키 워드 를 추가 하 는 것 을 표시 합 니 다.suffix Overrides 는 마지막 업데이트 필드 의 쉼표 를 suffix 가 지정 한 빈 칸 으로 바 꾸 는 것 을 표시 합 니 다.suffix 를 지정 하지 않 으 면 기본 값 은 빈 칸 입 니 다.

<!--     ,  sql    -->
<insert id="addBatch" parameterType="list">
    insert into user_info4(u_id, u_name, u_tel) values
    <foreach collection="list" item="user" separator=",">
        (#{user.uid}, #{user.userName}, #{user.tel})
    </foreach>
</insert>
foreach 탭 은 범위 조회 뿐만 아니 라 집합 을 옮 겨 다 니 며 대량으로 추가 할 수 있 습 니 다.
sql 의 특성 을 이용 할 수 있 기 때 문 입 니 다.예 를 들 어 insert into userinfo4(u_name, u_tel) values('', ''), ('', ''), ('', '');이렇게 하면 이 sql 문 구 를 실행 하면 대량으로 추가 할 수 있 습 니 다.

<!--     1,          ,       -->
<update id="updateBatch1" parameterType="list">
    <foreach collection="list" item="user" separator=";">
        update user_info4
        <set>
            u_name = #{user.userName}
        </set>
        where u_id = #{user.uid}
    </foreach>
</update>
foreach 는 여러 개의 sql 문 구 를 옮 겨 다 니 며 한 번 에 여러 개의 sql 을 실행 할 수 있 습 니 다.물론 MySql 이 여러 개의 대량 작업 을 수행 해 야 할 때 대량 조회 기능 을 켜 야 합 니 다.즉,MySql 의 url 에 allow MultiQueries=true 를 추가 해 야 합 니 다.

<!--     2,  MySQL case when   -->
    <update id="updateBatch2" parameterType="list">
        update user_info4 set u_name = case u_id
        <foreach collection="list" item="user" separator=" ">
            when #{user.uid} then #{user.userName}
        </foreach>
        end
        where u_id in
        <foreach collection="list" item="user" open="(" close=")" separator=",">
            #{user.uid}
        </foreach>
    </update>
MySql 의 case when 문 구 를 사용 하여 업데이트 합 니 다.기본 문법:

update user_info4 set u_name = case u_id
  when 3 then '  1'
  when 4 then '  2'
  end
  where u_id in(3,4);
Mybatis 의 ognl 사용 총화
마 퍼 를 쓰 는 데 OGNL 을 많이 쓰 는데 정리 가 잘 안 돼 서 사용법 이 애매 해 요.시간 을 내 서 다른 사람의 블 로 그 를 찾 아 간단 한 정 리 를 했다.
1.개념
OGNL,Object Graph Navigation Language 는 강력 한 표현 식 언어 로 인터넷 검색 이라는 개념 은 주로 structs 와 관련 된 것 입 니 다.하지만 my batis 에 서 는 OGNL 응용 이 광범 위 합 니 다.
2.기본 매개 변수
Mybatis 에서 자주 사용 하 는 OGNL 표현 식 은 다음 과 같 습 니 다.
e1 or e2
e1 and e2
e1 == e2,e1 eq e2
e1 != e2,e1 neq e2
e1 lt e2:이하
e1 lt e2:작 으 면 같 고,기타 lt(크 면),gte(크 면 같 음)
e1 in e2
e1 not in e2
e1 + e2,e1 * e2,e1/e2,e1 - e2,e1%e2
!아니다
e.method(args)호출 대상 방법
e.property 대상 속성 값
e1[e2]색인 에 따라 값,List,배열 과 Map 을 추출 합 니 다.
@class@method(args)호출 클래스 의 정적 방법
@class@field호출 클래스 의 정적 필드 값
더 자세 한 소 개 는 홈 페이지 의 소 개 를 참고 할 수 있 습 니 다https://commons.apache.org/proper/commons-ognl/language-guide.html
특정한 의미 에서 말 하면 my batis 의 동적 sql 도 OGNL 표현 식 을 바탕 으로 합 니 다.그 중에서 자주 사용 하 는 요 소 는 다음 과 같은 몇 가지 가 있다.

    if
    choose(when,otherwise)
    trim
    where
    set
    foreach
3.응용;
OGNL 이 my batis 에서 의 응용 은 주로 두 가지 가 있다.
1)동적 SQL 표현 식;
밤 을 들다

<code class="language-xml hljs  has-numbering"><span class="hljs-tag"><<span class="hljs-title">select</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"demo1"</span> <span class="hljs-attribute">...</span>></span>
</code><pre name="code" class="prettyprint"><code class="language-xml hljs  has-numbering">    select id, name from users
    <span class="hljs-tag"><<span class="hljs-title">bind</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"nameLike"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"'%' + name + '%'"</span>/></span>
    <span class="hljs-tag"><<span class="hljs-title">where</span>></span>
        <span class="hljs-tag"><<span class="hljs-title">if</span> <span class="hljs-attribute">test</span>=<span class="hljs-value">"name != null and name != ''"</span>></span>
            name like '${nameLike}'
        <span class="hljs-tag"></<span class="hljs-title">if</span>></span>
    <span class="hljs-tag"></<span class="hljs-title">where</span>></span>
<span class="hljs-tag"></<span class="hljs-title">select</span>></span></code>
그 중의 bid 의 value 값 은 OGNL 로 계산 합 니 다.ps.그 중에서 bid 의 매개 변 수 는$로 만 가 져 올 수 있 습 니 다.
2)${param}인자 중

<code class="language-xml hljs  has-numbering"><span class="hljs-tag"><<span class="hljs-title">select</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"demo2"</span> <span class="hljs-attribute">...</span>></span>
    select id,name from users
    <span class="hljs-tag"><<span class="hljs-title">where</span>></span>
        <span class="hljs-tag"><<span class="hljs-title">if</span> <span class="hljs-attribute">test</span>=<span class="hljs-value">"name != null and name != ''"</span>></span>
            name like '${'%' + name + '%'}'
        <span class="hljs-tag"></<span class="hljs-title">if</span>></span>
    <span class="hljs-tag"></<span class="hljs-title">where</span>></span>
<span class="hljs-tag"></<span class="hljs-title">select</span>></span></code>
${'%'+name+'%'}이 라 고 쓰 여 있 습 니 다.%${name}%가 아 닙 니 다.이 두 가지 방식 의 결 과 는 같 지만 처리 과정 은 다 릅 니 다.
ps.\#와$의 차 이 를 설명 합 니 다.${}은 원래 출력 입 니 다.당신 이 전달 하 는 대로 sql 에 입력 합 니 다.예 를 들 어 따옴표 가 있 으 면 sql 에 그대로 채 워 집 니 다.\#{}Prepared Statement,변 수 를 사용 합 니까?대신
sql 주입 을 방지 할 수 있 도록\#{}을 사용 할 수 있 습 니 다.
다음은 OGNL 이 정적 방법 을 호출 하 는 예제 입 니 다.

    <select id="getRecentQuestionTitle" parameterType="java.lang.String" resultType="java.lang.String">  
            select title from song_question where questionState = #{value}   
            <if test="@Ognl@isSolve(value[0],0)">  
            order by questionTime desc   
            </if>  
            <if test="@Ognl@isSolve(value[0],1)">  
            order by answerTime desc   
            </if>                
            limit 0,1  
      </select>  
정적 방법 은 다음 과 같다.

public static boolean isSolve(Object o,String soleState){  
        if(o == null)  
            return false;  
        String str = null;  
        if(o instanceof String[]){  
            String[]objects = (String[])o;  
            str = objects[0];  
        }else if(o instanceof Character){  
            Character c = (Character) o;  
            str =  Character.toString(c);  
        }  
            if(StringUtils.equals(str, soleState))  
                return true;  
        return false;  
          
    } 
값 이 0 이면 order by questionTime desc 는 필드 questionTime 에 따라 정렬 합 니 다.
값 이 1 이면 order by answerTime desc 는 필드 answerTime 에 따라 정렬 합 니 다.
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기