【Java】MyBatis框架初步學習總結

  本篇篇幅較長,請善用 Ctrl + F 搜索功能。html

  結尾補充了 MyBatis 中 resultMap 的映射級別。java

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- git

  MyBatis學完也有幾天了,總結一下學習到的內容,也算是複習了。github

 

  使用MyBatis以前,咱們要知道,什麼是MyBatis?sql

  MyBatis是apache一個開源的,基於Java的持久層框架。數據庫

  MyBatis的優勢有哪些?apache

  學習簡單,提供半自動的關係映射,SQL語句與代碼分離。api

  MyBatis的缺點又有哪些?數組

  要會寫SQL語句;每一個數據庫的SQL語句都多少會有誤差,因此不方便更換數據庫。mybatis

  MyBatis適合什麼樣的項目?

  適合性能要求很高,或者須要變化較多的項目。

  

  要使用MyBatis,得有MyBatis的jar包。

  在https://github.com/mybatis/mybatis-3/releases下載mybatis-x.x.x.zip,我用的版本是3.3.2。

  壓縮包裏的mybatis-x.x.x.jar就是咱們要的jar包了,.pdf的是幫助文檔,lib文件夾裏的是MyBatis的依賴包,具體做用自行百度,一塊兒丟到項目的lib的文件夾裏所有add build一下就好了。

  哦對了,jdbc的jar包請自行準備。

  

  只有jar包還不夠,咱們還須要xml配置文件。

  新建一個Source Folder,將配置文件統一放在裏面。爲了方便識別,MyBatis的配置文件咱們能夠命名爲「mybatis-config.xml」,配置文件的內容大體是這樣的,改改就能用:  

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE configuration  3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  4 "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5 <configuration>
 6     <properties resource="mybatis.properties" /><!-- jdbc配置文件 -->
 7     <typeAliases><!-- 類型別名 -->
 8         <typeAlias type="cn.bwm.pojo.User" alias="User"/><!-- 給指定的類起一個別名 -->
 9         <package name="cn.bwm.pojo" /><!-- 給包裏的全部類起一個和類名同樣的別名 -->
10     </typeAliases>
11     <environments default="test"><!-- 配置環境 ,default選擇默認配置-->
12         <environment id="test"><!-- 環境元素 -->
13             <transactionManager type="JDBC" />    <!-- 配置事務管理器 -->
14             <dataSource type="POOLED"><!-- 數據源 -->
15                 <property name="driver" value="${driver}" /><!-- jdbc配置文件對應屬性 -->
16                 <property name="url" value="${url}" />
17                 <property name="username" value="${username}" />
18                 <property name="password" value="${password}" />
19             </dataSource>
20         </environment>
21     </environments>
22     <mappers><!-- 映射器 -->
23         <mapper resource="cn/bwm/dao/IUserMapper.xml" /><!-- xml映射文件 -->
24     </mappers>
25 </configuration>

  每一個標籤的具體做用請參考官方文檔,中文的,http://www.mybatis.org/mybatis-3/zh/getting-started.html

  

  最後一步也是舉足輕重的一步,配置MyBatis的兩個dtd文件。

  這兩個文件,一個叫「mybatis-3-config.dtd」,另外一個叫「mybatis-3-mapper.dtd」,咱們能夠經過解壓縮mybatis-x.x.x.jar,在\org\apache\ibatis\builder\xml 這個目錄下找到這兩個文件。

  我用的是MyEclipse10.6,配置的步驟是:

  Windows → Preferences ; 選擇XML Catalog ,選擇User Specified Entries,單擊 Add ; 單擊 File System 後選擇dtd文件, Key填寫 -//mybatis.org//DTD Config 3.0//EN (與MyBatis-config.xml文件投中的 -//mybatis.org//DTD Config 3.0//EN 相同)。

  兩個dtd文件配置步驟同樣,配置完成之後,在MyBatis-config.xml文件和xml映射文件中就可使用 alt + / 自動聯想了。

  
  完成以上步驟之後,MyBatis就算是部署到項目中了,至於如何使用MyBatis,咱們還須要準備一個數據庫。這個數據庫至少要有兩張結構簡單有主外鍵關係的表,以及少許數據。在項目中建立與數據庫的表對應的實體類,在數據訪問層建立實體類對應的接口,並聲明抽象方法,例如:

/** * 老師類 * @author Administrator * */
public class Teacher { private int id; private String name; private Student student; private List<Student> studentList; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } public List<Student> getStudentList() { return studentList; } public void setStudentList(List<Student> studentList) { this.studentList = studentList; } } /** * 學生類 * @author Administrator * */
public class Student { private int id; private String name; private int tid; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getTid() { return tid; } public void setTid(int tid) { this.tid = tid; } } /** * Teacher實體類的對應接口 * @author Administrator * */
public interface ITeacherMapper { /** * 根據id查詢老師 * @param id * @return Teacher對象 */
    public Teacher queryTeacherById(int id); }

  在接口的同目錄下建立同名xml文件:

1 <?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5 <mapper namespace="cn.bwm.dao.ITeacherMapper">
6     <select id="queryTeacherById" parameterType="int" resultType="Teacher">
7  SELECT `Id`,`Name` FROM `teacher` WHERE `Id` = #{id} 8     </select>
9 </mapper>

  寫完這些代碼和配置文件,如今,咱們再來簡單瞭解一下MyBatis的核心接口和類:

  • SqlSessionFactoryBuilder:提供多個build()方法的重載,只負責構建SqlSessionFactory的對象,只須要使用一次。
  • SqlSessionFactory:提供OpenSession()方法的重載,用來建立SqlSession對象,須要使用屢次。
  • SqlSession:用於執行已映射的SQL語句,在未使用close()方法關閉前可屢次使用SQL。

  深刻了解請查看官方文檔,中文的, http://www.mybatis.org/mybatis-3/zh/java-api.html 。

  根據三個核心接口和類,咱們再寫一個用來獲取SqlSession對象的工具類:

 1 public class SqlSessionUtil {  2     private static SqlSessionFactory sqlSessionFactory;  3     
 4     static{  5         SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();  6         try {  7             InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");  8             sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);  9         } catch (IOException e) { 10  e.printStackTrace(); 11  } 12  } 13     
14     /**
15  * 獲取SqlSession對象 16  * @return
17      */
18     public static SqlSession getSqlSession(){ 19             return sqlSessionFactory.openSession(); 20  } 21     
22     /**
23  * 關閉SqlSession對象 24  * @param sqlSession 25      */
26     public static void closeSqlSession(SqlSession sqlSession){ 27         if (sqlSession != null) { 28  sqlSession.close(); 29  } 30  } 31 }

  如今,咱們能夠寫測試代碼了:

1 public class Test { 2     public static void main(String[] args) { 3         SqlSession sqlSession = SqlSessionUtil.getSqlSession(); 4         Teacher teacher = sqlSession.getMapper(ITeacherMapper.class).queryTeacherById(1); 5         System.out.println("編號:" + teacher.getId() + "\t姓名:" + teacher.getName()); 6  SqlSessionUtil.closeSqlSession(sqlSession); 7  } 8 }

  相信你們也看出來了,咱們使用MyBatis執行了簡單的查詢操做,並將結果封裝成了一個對象,而這其中的關鍵就在於與接口同名的xml映射文件。

  咱們來看一下映射文件中用到了哪些元素:

  • mapper標籤:映射文件的根節點。
    • namespace屬性:用於區分不一樣的napper,全局惟一,必須與對應的接口同名。
  • select標籤:映射查詢語句。
    • id屬性:命名空間中惟一的標識符,與接口中的方法名對應。
    • parameterType:表示傳入參數的類型的徹底限定名或別名。徹底限定名就是 java.long.String 這樣的完整路徑,別名則是在 mybatis-config.xml 中設置的別名,MyBatis已經爲部分Java類型提供了別名。能夠省略(省略好像也沒有什麼影響)
    • resultType:查詢語句返回結果類型的徹底限定名或別名。在這裏我寫的是 Teacher ,MyBatis就會按照查詢的結果的列名和類的屬性字段進行匹配映射,同樣的就調用set方法進行賦值,因此類的屬性要儘可能和數據庫的字段名同樣,不然就要在查詢的時候給查詢結果起別名。若是想返回 int 或 String ,可使用MyBatis提供的別名。若是方法想返回一個List集合,這裏寫List集合裏元素的類型。
  • #{id}:這就告訴 MyBatis 建立一個預處理語句參數,經過 JDBC,這樣的一個參數在 SQL 中會由一個「?」來標識,並被傳遞到一個新的預處理語句中。實際上,不管MyBatis的入參是哪一種參數類型,都會被放在一個Map中,單參數入參就會有這些狀況 
    • 基本類型:對應接口中方法的參數名做爲 key , 變量值爲 value。
    • 對象:對象的屬性名做爲 key,屬性值爲 value。
    • List:默認 list 做爲 key,該 list 即爲 value。
    • 數組:默認 array 做爲 key,該數組即爲 value。
    • Map:鍵值不變。

  咱們在查詢的時候,不可能只有單參數查詢,而parameterType只能寫一個類型,這個時候,有三種方法:

  1. 使用對象做爲參數。
  2. 將參數封裝成Map集合。
  3. 使用@Param註解。

  先說第一種,使用對象做爲參數。這種方法應該比較適合插入操做,咱們這裏強行使用一波。

  先在接口裏寫上方法:

1 /**
2  * 根據編號和姓名查詢老師 3  * @param t Teacher對象 4  * @return Teacher對象 5      */
6     public Teacher queryTeacherByIdName(Teacher t);

  在xml映射文件裏寫對應的SQL語句,parameterType寫的是參數類型 Teacher,#{id}和#{name}都是 Teacher 類的屬性,CONCAT()是MySQL的函數,用來拼接字符串:

1 <select id="queryTeacherByIdName" parameterType="Teacher" resultType="Teacher">
2  SELECT `Id`,`Name` FROM `teacher` WHERE `Id` = #{id} AND `Name` LIKE CONCAT('%' , #{name} , '%') 3 </select>

  測試代碼是這樣的:

1     public static void main(String[] args) { 2         SqlSession sqlSession = SqlSessionUtil.getSqlSession(); 3         Teacher t = new Teacher(); 4         t.setId(1); 5         t.setName("小"); 6         Teacher teacher = sqlSession.getMapper(ITeacherMapper.class).queryTeacherByIdName(t); 7         System.out.println("編號:" + teacher.getId() + "\t姓名:" + teacher.getName()); 8  SqlSessionUtil.closeSqlSession(sqlSession); 9     }

  這樣便完成了使用對象做爲參數來進行查詢的操做。

  而後是第二種,將參數封裝成Map集合,咱們修改一下剛纔的方法,把參數改爲 Map<String , Object>集合:

1     /**
2  * 根據編號和姓名查詢老師 3  * @param map Map<String,Object>集合 4  * @return Teacher對象 5      */
6     public Teacher queryTeacherByIdName(Map<String,Object> map);

  xml映射文件裏,parameterType改爲了 map,是MyBatis提供的別名:

1     <select id="queryTeacherByIdName" parameterType="map" resultType="Teacher">
2  SELECT `Id`,`Name` FROM `teacher` WHERE `Id` = #{id} AND `Name` LIKE CONCAT('%' , #{name} , '%') 3     </select>

  測試代碼把剛纔做爲參數的 Teacher 對象改爲 Map<String , Object>集合:

1     public static void main(String[] args) { 2         SqlSession sqlSession = SqlSessionUtil.getSqlSession(); 3         Map<String,Object> map = new HashMap<String,Object>(); 4         map.put("id", 1); 5         map.put("name", "小"); 6         Teacher teacher = sqlSession.getMapper(ITeacherMapper.class).queryTeacherByIdName(map); 7         System.out.println("編號:" + teacher.getId() + "\t姓名:" + teacher.getName()); 8  SqlSessionUtil.closeSqlSession(sqlSession); 9     }

  這樣就完成了使用 Map 傳遞多個參數。

  最後是第三種,使用@Param註解,仍是直接修改剛纔的方法,把 Map<String , Object> 換成 @Param 註解的參數:

1     /**
2  * 根據編號和姓名查詢老師 3  * @param id 編號 4  * @param name 姓名 5  * @return Teacher 對象 6      */
7     public Teacher queryTeacherByIdName(@Param("tid")int id , @Param("tname")String name);

  xml文件裏,由於@Param("")裏寫的是 tid 和 tname,因此 #{} 也要寫的同樣:

1     <select id="queryTeacherByIdName" parameterType="map" resultType="Teacher">
2  SELECT `Id`,`Name` FROM `teacher` WHERE `Id` = #{tid} AND `Name` LIKE CONCAT('%' , #{tname} , '%') 3     </select>

  測試代碼裏,參數也不用放在 Map 集合裏了:

1     public static void main(String[] args) { 2         SqlSession sqlSession = SqlSessionUtil.getSqlSession(); 3         Teacher teacher = sqlSession.getMapper(ITeacherMapper.class).queryTeacherByIdName(1 , "小"); 4         System.out.println("編號:" + teacher.getId() + "\t姓名:" + teacher.getName()); 5  SqlSessionUtil.closeSqlSession(sqlSession); 6     }

  這就是 @Param 的使用方法。

  三種方法說完了,但無論參數有多少,咱們如今查詢的結果都只是一個簡單對象,若是結果的類型包含另外一個類型,或者包含一個集合,這裏咱們就要了解一下 <resultMap> 元素及其子元素 <result>、<association> 和 <conllection> 。

  咱們經過代碼來說解這幾個個元素的使用方法,個人 Teacher 類中已經有一個 Student 屬性和一個 List<Student> 屬性:

 1 /**
 2  * 老師類  3  * @author Administrator  4  *  5  */
 6 public class Teacher {  7     private int id;  8     private String name;  9     private Student student;    //學生對象
10     private List<Student> studentList;    //學生集合 11     //省略 getset 方法
12 }

  接口裏的方法能夠不用修改,xml映射文件須要大改一下:

 1     <select id="queryTeacherByIdName" resultMap="query">
 2  select t.`Id` as tid , t.`Name`as tname , s.`Id` as sid , s.`Name` as sname from `teacher` as t  3  inner join `student` as s on s.`Tid` = t.`Id` where t.`Id` = #{tid}  4     </select>    
 5     <resultMap type="Teacher" id="query">
 6         <id column="tid" property="id"/>
 7         <result column="tname" property="name"/>
 8         <association property="student" javaType="Student">
 9             <id column="sid" property="id"/>
10             <result column="sname" property="name"/>
11             <result column="tid" property="tid"/>
12         </association>
13         <collection property="studentList" ofType="Student">
14             <id column="sid" property="id"/>
15             <result column="sname" property="name"/>
16             <result column="tid" property="tid"/>
17         </collection>
18     </resultMap>

  select 標籤的 resultType 屬性換成了 resultMap屬性,值與 resultMap 標籤的 id 同樣。

  • resultMap標籤:用來自定義結果映射,一般在實體類的屬性名與數據庫裏表的字段不一致致使沒法自動映射時,以及須要映射覆雜對象時使用。要注意的是,resultMap 和 resultType 這兩個元素只能使用其中一個,不能同時存在。
    • id屬性:resultMap 的惟一標識。
    • type屬性:表示該 resultMap 的映射結果類型。
  • id 標籤:用來標記主鍵,能夠提升總體性能。
    • column 屬性:對應SQL語句查詢結果的字段名。
    • property 屬性:對應要賦值的屬性。
  • result 標籤:標誌簡單屬性。
  • association 標籤:用來映射 JavaBean 的某個 複雜類型 屬性,僅處理一對一的關聯關係。
    • javaType 屬性:完整 Java 類名或者別名。
  • collection 元素:映射 JavaBean 的某個 複雜類型 的集合屬性,用來處理一對多的關聯關係。
    • ofType 屬性:完整 Java 的類名或或別名,即集合所包含的類型。

  另外,resultMap 結果映射能夠複用,咱們改一下xml映射文件的代碼:

 1     <select id="queryTeacherByIdName" resultMap="query1">
 2  select t.`Id` as tid , t.`Name`as tname , s.`Id` as sid , s.`Name` as sname from `teacher` as t  3  inner join `student` as s on s.`Tid` = t.`Id` where t.`Id` = #{tid}  4     </select>    
 5         
 6     <resultMap type="Student" id="student">
 7             <id column="sid" property="id"/>
 8             <result column="sname" property="name"/>
 9             <result column="tid" property="tid"/>
10     </resultMap>
11     
12     <resultMap type="Teacher" id="query1">
13         <id column="tid" property="id"/>
14         <result column="tname" property="name"/>
15         <association resultMap="student" property="student" javaType="Student"/>
16     </resultMap>
17     
18     <resultMap type="Teacher" id="query2">
19         <id column="tid" property="id"/>
20         <result column="tname" property="name"/>
21         <collection resultMap="student" property="studentList" ofType="Student"/>
22     </resultMap>

  在代碼裏,兩個 resultMap 裏的 association 和 collection 都重用了 query 這個 resultMap ,能夠節省很多代碼。順便一提,我在測試時,association 和 collection 沒法在一個 resultMap 裏重用同一個 resultMap ,collection 會失效,最終查詢出來的結果,List的元素數量是0,具體緣由暫時還沒找到。

  

  查詢部分算是結束了,接下是比較簡單的增刪改操做,先在接口裏寫上對應的方法:

 1     /**
 2  * 增長老師  3  * @param teacher Teacher對象  4  * @return
 5      */
 6     public int addTeacher(Teacher teacher);  7     
 8     /**
 9  * 修改老師 10  * @param teacher Teacher對象 11  * @return
12      */
13     public int updateTeacher(Teacher teacher); 14     
15     /**
16  * 根據id刪除老師 17  * @param id 老師的編號 18  * @return
19      */
20     public int deleteTeacher(int id);

  xml映射文件裏也要使用對應的標籤,分別是 <insert>、<update>和<delete>

 1     <insert id="addTeacher" parameterType="Teacher">
 2  INSERT INTO `teacher`(`Name`) VALUES(#{name})  3     </insert>
 4     
 5     <update id="updateTeacher" parameterType="Teacher">
 6  UPDATE `teacher` SET `Name` = #{name} WHERE id = #{id}  7     </update>
 8     
 9     <delete id="deleteTeacher" parameterType="int">
10  DELETE FROM `teacher` WHERE `Id` = #{id} 11     </delete>

  由於增刪改的操做返回的是數據庫受影響的行數,因此這個三個標籤是沒有 resultType 和 resultMap 兩個屬性的。

  測試部分須要增長一點點代碼:

 1     /**
 2  * 添加老師  3      */
 4     private static void addTeacher() {  5         SqlSession sqlSession = SqlSessionUtil.getSqlSession();  6         Teacher teacher = new Teacher();  7         teacher.setName("小黑白");  8         int result = sqlSession.getMapper(ITeacherMapper.class).addTeacher(teacher);  9         if (result > 0) { 10             sqlSession.commit();    //提交事務
11             System.out.println("添加成功!"); 12         }else{ 13             System.out.println("添加失敗!"); 14  } 15  SqlSessionUtil.closeSqlSession(sqlSession); 16  } 17 
18     /**
19  * 修改老師 20      */
21     private static void updateTeacher() { 22         SqlSession sqlSession = SqlSessionUtil.getSqlSession(); 23         Teacher teacher = new Teacher(); 24         teacher.setId(2); 25         teacher.setName("小黑"); 26         int result = sqlSession.getMapper(ITeacherMapper.class).updateTeacher(teacher); 27         if (result > 0) { 28             sqlSession.commit();    //提交事務
29             System.out.println("修改爲功!"); 30         }else{ 31             System.out.println("修改失敗!"); 32  } 33  SqlSessionUtil.closeSqlSession(sqlSession); 34  } 35     
36     /**
37  * 根據id刪除老師 38      */
39     private static void deleteTeacher() { 40         SqlSession sqlSession = SqlSessionUtil.getSqlSession(); 41         int result = sqlSession.getMapper(ITeacherMapper.class).deleteTeacher(2); 42         if (result > 0) { 43             sqlSession.commit();    //提交事務
44             System.out.println("刪除成功!"); 45         }else{ 46             System.out.println("刪除失敗!"); 47  } 48  SqlSessionUtil.closeSqlSession(sqlSession); 49     }

  這三個操做都有一個共同的特色,就是在判斷數據庫受影響的行數大於0之後,都會調用 SqlSession 的 commit() 方法。

  這是由於 MyBatis 在執行增刪改操做的時候並無直接操做數據庫,咱們能夠理解成是在操做一個虛擬的數據庫,當咱們調用 commit() 方法後,咱們所作的操做纔會對真正的數據庫產生影響。

  以上就是使用 MyBatis 對數據庫進行增刪改查操做的示例,咱們不難發現,把 SQL語句寫在 xml映射文件裏會致使咱們沒法用代碼改變 SQL 語句,顯得不夠靈活,對此,MyBatis爲咱們提供了動態SQL

  

  動態SQL是MyBatis的一個強大的特性,基於 OGNL 的表達式,使咱們能夠方便的動態改變 SQL 語句。

  用於動態SQL的元素有:

  • if
  • choose(when , otherwise)
  • trim(where , set)
  • foreach

  假設,咱們使用 id 和 name 來查詢老師,若是 name 沒有傳入參數,就只用 id 查詢老師,這時候就能夠使用 if 來進行判斷

1     <select id="queryTeacher" parameterType="map" resultType="Teacher">
2  SELECT * FROM `teacher` 3  WHERE `Id` = #{id} 4         <if test="name != null and name != ''">
5  AND `Name` LIKE CONCAT('%' , #{name} , '%') 6         </if>
7     </select>

  test 屬性其餘標籤也有,用來判斷條件。

  再假設,id 和 name 只要有其中一個就能夠了,按照有條件進行查詢,若是沒有就查詢所有,這時可使用 choose 和 它的子元素 when、otherwise來實現:

 1     <select id="queryTeacher" parameterType="map" resultType="Teacher">
 2  SELECT * FROM `teacher`  3  WHERE  4         <choose>
 5             <when test="id != null and id != 0">
 6  `Id` = #{id}  7             </when>
 8             <when test="name != null and name != ''">
 9  `Name` = #{name} 10             </when>
11             <otherwise>
12  1 = 1 13             </otherwise>
14         </choose>
15     </select>

  choose 至關於 Java 中的 switch 語句,從上向下開始判斷,只要有 when 的 test 成立,就返回該 when 裏的 SQL 語句並跳出 choose,若是全部的 when 都不成立,就返回 otherwise 裏的SQL語句。由於是從上向下判斷的,因此要注意 SQL 語句的優先順序。

  還有最後的 otherwise 裏的 1 = 1,若是沒有這個的話,頗有可能由於 id 和 name 兩個都沒有參數而形成 where 後面什麼都沒有,形成 SQL 語句報錯。這時,就須要使用 trim元素,它能夠靈活的去除多餘的關鍵字

 1     <select id="queryTeacher" parameterType="map" resultType="Teacher">
 2  SELECT * FROM `theacher`  3         <trim prefix="WHERE" prefixOverrides="and | or">
 4             <if test="id != null and id != 0">
 5  AND `id` = #{id}  6             </if>
 7             <if test="name != null and name != ''">
 8  AND `name` = #{name}  9             </if>
10         </trim>
11     </select>

  trim 元素會自動識別標籤內是否有返回值,有的話就在內容的前面加上 prefix 屬性的值 where,並忽略 prefixOverrides 裏所包含的內容 and 和 or 。(這部分代碼只爲了展現 trim 的做用,請忽略代碼的意義)

  這部分的 trim 的使用等價於 where 標籤:

 1     <select id="queryTeacher" parameterType="map" resultType="Teacher">
 2  SELECT * FROM `theacher`  3         <where>
 4             <if test="id != null and id != 0">
 5  AND `id` = #{id}  6             </if>
 7             <if test="name != null and name != ''">
 8  AND `name` = #{name}  9             </if>
10         </where>
11     </select>

  trim 不只能夠在 SQL 語句前添加內容和忽略內容,也能夠在 SQL 語句後追加內容和忽略內容,例如剛纔的修改操做:

 1     <update id="updateTeacher" parameterType="Teacher">
 2  UPDATE `teacher` SET `Name` = #{name} WHERE id = #{id}  3         <trim prefix="Set" suffixOverrides="," suffix="WHERE id = #{id}">
 4             <if test="id != null">
 5  `id` = #{id} ,  6             </if>
 7             <if test="name != null">
 8  `name` = #{name} ,  9             </if>
10         </trim>
11     </update>

  使用 prefix 在 SQL 語句前加上 prefix 的值 Set, 在 SQL 語句的最後加上 suffix 的值 WHERE id = #{id},忽略 SQL 語句最後的 suffixOverrides 的值  , 。(這段代碼只展現了 trim 的做用,請無視不合理的部分)

  這部分 trim 的使用等價於 set 標籤:

 1     <update id="updateTeacher" parameterType="Teacher">
 2  UPDATE `teacher` SET `Name` = #{name} WHERE id = #{id}  3         <set>
 4             <if test="id != null">
 5  `id` = #{id} ,  6             </if>
 7             <if test="name != null">
 8  `name` = #{name} ,  9             </if>
10         </set>
11  WHERE `id` = #{id} 12     </update>

  不過 WHERE 須要本身寫。

  另外,prefix、perfixOverriders、suffix 和 suffixOverriders四個屬性是能夠同時使用的,根據時間狀況選擇。

  foreach 元素,用於循環集合,主要用於構建 IN 條件語句的時候使用

1     <select id="queryTeacher" resultType="Teacher">
2  SELECT * FROM `theacher` 3  WHERE `id` IN 4         <foreach collection="list" item="id" index="index" open="(" separator="," close=")">
5  #{id} 6         </foreach>
7     </select>

  這裏咱們迭代了 list 集合,collection 屬性表示迭代時每一個元素的別名;index 表示每次迭代到的位置;open 表示 SQL 語句以什麼開始;separator 表示每次迭代直接用什麼進行分隔;close 表示 SQL 語句以什麼結束;collection 必須指定,對應要遍歷的集合。

  在遍歷 對象 和 數組時,index 表示當前迭代的次數,item 的值是表示當前迭代獲取的元素。

  遍歷 Map 時,index 是鍵, item 是值。

 

  補充一下 resultMap 的映射級別

  我在使用 resultMap 自定義映射結果的時候發現,即便我只在 resultMap 裏定義一個 id ,其餘的屬性也仍是會自動映射上去。

  這是由於 MyBatis 的配置文件中,autoMappingBehavior 的默認級別是 PARTIAL,只會自動映射沒有定義嵌套結果集映射的結果集,改爲 NONE 就能夠取消自動映射,改爲FULL的話,會自動映射覆雜的結果集,不管是否嵌套。

  
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  到這裏,關於MyBatis我所學習到的內容就所有結束了。

  第一次寫博客沒有經驗,寫的很長,也很爛

  感謝耐心看到這裏的你,若是對你有所幫助就再好不過了

相關文章
相關標籤/搜索