mybatis的注解開發之三種動態sql


腳本sql

XML配置方式的動態SQL我就不講了,有興趣可以自己了解,下面是用<script>的方式把它照搬過來,用注解來實現。適用於xml配置轉換到注解配置
@Select("<script>select * from user <if test=\"id !=null \">where id = #{id} </if></script>")    
public List<User> findUserById(User user);  

 

 
很明顯,在java中寫xml可讀性和維護性太差,尤其當SQL很長時,這樣寫是很痛苦的。

在方法中構建sql

dao接口中是不能寫實現的,所以這里借用內部類來生成動態SQL。增改刪也有對應的@InsertProvider、@UpdateProvider、@DeleteProvider
@Mapper  
public interface MybatisDao {  
    //使用UserDaoProvider類的findUserById方法來生成sql  
    @SelectProvider(type = UserDaoProvider.class, method = "findUserById")  
    public List<User> findUserById(User user);  
      
    class UserDaoProvider {  
        public String findUserById(User user) {  
            String sql = "SELECT * FROM user";  
            if(user.getId()!=null){  
                sql += " where id = #{id}";  
            }  
            return sql;  
        }  
    }  

 

 
這比<script>更加清晰,適用於查詢語句不是很長、條件不多的場景,SQL很直觀。但是在寫很長的SQL時,這樣拼接SQL同樣會很痛苦

結構化SQL

public String findUserById(User user) {      
            return new SQL(){{      
                SELECT("id,name");      
                SELECT("other");      
                FROM("user");      
                if(user.getId()!=null){      
                    WHERE("id = #{id}");      
                }      
                if(user.getName()!=null){      
                    WHERE("name = #{name}");      
                }      
            //從這個toString可以看出,其內部使用高效的StringBuilder實現SQL拼接      
            }}.toString();      
        } 

 

  

這是把前面的內部類改造一下
SELECT:表示要查詢的字段,如果一行寫不完,可以在第二行再寫一個SELECT,這兩個SELECT會智能的進行合並而不會重復
FROM和WHERE:跟SELECT一樣,可以寫多個參數,也可以在多行重復使用,最終會智能合並而不會報錯
這樣語句適用於寫很長的SQL時,能夠保證SQL結構清楚。便於維護,可讀性高。但是這種自動生成的SQL和HIBERNATE一樣,在實現一些復雜語句的SQL時會束手無策。所以需要根據現實場景,來考慮使用哪一種動態SQL
上面的例子只是最基本的用法:更多詳細用法,可以參考mybatis中文網的專門介紹
http://www.mybatis.org/mybatis-3/zh/statement-builders.html

List傳值錯誤

動態SQL中,有時要對批量數據進行處理,難免會使用list做為參數
@SelectProvider(type = UserDaoProvider.class, method = "find")  
    public List<Map> find(List list);      
      
    class UserDaoProvider {  
        public String find(List list) {  

 


這是一個最簡單的list傳參,但是在運行時會報傳參錯誤。這是mybatis內部機制造成的,其參數需要是key/value結構,當遇到這里不是key/value結構的list時,mybatis會自己把它轉換成key/value結構,key就是他的名字"list",value就是他的值List,要正確傳參需要使用key/value結構的map,如下
@SelectProvider(type = UserDaoProvider.class, method = "find")  
    public List<Map> find(List list);      
      
    class UserDaoProvider {  
        public String find(Map map) {  
            List list = (List) map.get("list");  

 


 
版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/wangb_java/article/details/73657958


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM