日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Mybatis学习--Mapper.xml映射文件

發布時間:2024/4/17 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mybatis学习--Mapper.xml映射文件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • 簡介

  Mapper.xml映射文件中定義了操作數據庫的sql,每個sql是一個statement,映射文件是mybatis的核心。

  映射文件中有很多屬性,常用的就是parameterType(輸入類型)、resultType(輸出類型)、resultMap()、rparameterMap()。

  • parameterType(輸入類型)

  1、#{}與${}

  #{}實現的是向prepareStatement中的預處理語句中設置參數值,sql語句中#{}表示一個占位符即?

?

1 <!-- 根據id查詢用戶信息 --> 2 <select id="findUserById" parameterType="int" resultType="user"> 3 select * from user where id = #{id} 4 </select>

?

  使用占位符#{}可以有效防止sql注入,在使用時不需要關心參數值的類型,mybatis會自動進行java類型和jdbc類型的轉換。#{}可以接收簡單類型值或pojo屬性值,如果parameterType傳輸單個簡單類型值,#{}括號中可以是value或其它名稱。

  ${}#{}不同,通過${}可以將parameterType?傳入的內容拼接在sql中且不進行jdbc類型轉換,?${}可以接收簡單類型值或pojo屬性值,如果parameterType傳輸單個簡單類型值,${}括號中只能是value。使用${}不能防止sql注入,但是有時用${}會非常方便,如下的例子:

  

1   <!-- 根據名稱模糊查詢用戶信息 --> 2 <select id="selectUserByName" parameterType="string" resultType="user"> 3 select * from user where username like '%${value}%' 4 </select>

?

  如果本例子使用#{}則傳入的字符串中必須有%號,而%是人為拼接在參數中,顯然有點麻煩,如果采用${}sql中拼接為%的方式則在調用mapper接口傳遞參數就方便很多。

  //如果使用占位符號則必須人為在傳參數中加%

?

  List<User>?list?=?userMapper.selectUserByName("%張三%");

  //如果使用${}原始符號則不用人為在參數中加%

?

  List<User>list?=?userMapper.selectUserByName("張三");

  再比如order?by排序,如果將列名通過參數傳入sql,根據傳的列名進行排序,應該寫為:

  ORDER?BY?${columnName},如果使用#{}將無法實現此功能。

  2、傳遞簡單類型

  傳遞簡單類型只需要注意#{}與${}的使用就可以。

  3、傳遞pojo對象

  Mybatis使用ognl表達式解析對象字段的值,如下例子:

?

1   <!—傳遞pojo對象綜合查詢用戶信息 --> 2 <select id="findUserByUser" parameterType="user" resultType="user"> 3 select * from user where id=#{id} and username like '%${username}%' 4 </select>

?

  測試代碼:

1 Public void testFindUserByUser()throws Exception{ 2 //獲取session 3 SqlSession session = sqlSessionFactory.openSession(); 4 //獲限mapper接口實例 5 UserMapper userMapper = session.getMapper(UserMapper.class); 6 //構造查詢條件user對象 7 User user = new User(); 8 user.setId(1); 9 user.setUsername("管理員"); 10 //傳遞user對象查詢用戶列表 11 List<User>list = userMapper.findUserByUser(user); 12 //關閉session 13 session.close(); 14 }

  如果將username寫錯后,會報以下異常

1 org.apache.ibatis.exceptions.PersistenceException: 2 ### Error querying database. Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'dusername' in 'class com.luchao.mybatis.first.po.User' 3 ### Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'dusername' in 'class com.luchao.mybatis.first.po.User'

  可以看出MyBatis是通過反射來講java對象映射到查詢參數中的。

  4、傳遞pojo包裝對象

  開發中通過pojo傳遞查詢條件?,查詢條件是綜合的查詢條件,不僅包括用戶查詢條件還包括其它的查詢條件(比如將用戶購買商品信息也作為查詢條件),這時可以使用包裝對象傳遞輸入參數。

  (1)、定義包裝對象

  定義包裝對象將查詢條件(pojo)以類組合的方式包裝起來。

?

1 public class QueryVo { 2 private User user; 3 //自定義用戶擴展類 4 private UserCustom custom; 5 public User getUser() { 6 return user; 7 } 8 public void setUser(User user) { 9 this.user = user; 10 } 11 public UserCustom getCustom() { 12 return custom; 13 } 14 public void setCustom(UserCustom custom) { 15 this.custom = custom; 16 } 17 }

?

  (2)、?mapper.xml映射文件

?

1 <select id="findUser" parameterType="com.luchao.mybatis.first.po.QueryVo" resultType="com.luchao.mybatis.first.po.User"> 2 select * from user where username like '%${user.username}%' and sex = #{user.sex} 3 </select>

?

  說明:mybatis底層通過ognlpojo中獲取屬性值:#{user.username}user即是傳入的包裝對象的屬性。

  5、傳遞hashmap

  Sql映射文件定義如下:

?

1 <select id="findUserByIdMap" parameterType="hashmap" resultType="com.luchao.mybatis.first.po.User"> 2 select * from user where id = #{id} 3 </select>

?

  測試代碼:

1 Public void testFindUserByHashmap()throws Exception{ 2 //獲取session 3 SqlSession session = sqlSessionFactory.openSession(); 4 //獲限mapper接口實例 5 UserMapper userMapper = session.getMapper(UserMapper.class); 6 //構造查詢條件Hashmap對象 7 HashMap<String, Object> map = new HashMap<String, Object>(); 8 map.put("id", 1); 9 //傳遞Hashmap對象查詢用戶列表 10 List<User>list = userMapper.findUserByHashmap(map); 11 //關閉session 12 session.close(); 13 }

  傳遞的map中的keysql中解析的key不一致。測試結果沒有報錯,只是通過key獲取值為空。這種用法一般用在POJO與數據庫字段不一致的時候。

  • parameterMap和resultMap

  resultType可以指定pojo將查詢結果映射為pojo,但需要pojo的屬性名和sql查詢的列名一致方可映射成功。如果sql查詢字段名和pojo的屬性名不一致,可以通過resultMap將字段名和屬性名作一個對應關系?,resultMap實質上還需要將查詢結果映射到pojo對象中。resultMap可以實現將查詢結果映射為復雜類型的pojo,比如在查詢結果映射對象中包括pojolist實現一對一查詢和一對多查詢。

?

  下面是在數據庫列于POJO不一致的時候,將輸入參數映射到數據庫列的一種方式 

1 <resultMap type="Book.dao.Book" id="BookResultMap"> 2 <id column="id" property="id"/> 3 <result column="name" property="bookName"/> 4 <result column="price" property="bookPrice"/> 5 </resultMap> 6 7 <!-- resultMap:resultMap的id ,bookName:resultMap的property,即實體類中的屬性 --> 8 <parameterMap type="Book.dao.Book" id="BookParameterMap"> 9 <parameter property="bookName" resultMap="BookResultMap" /> 10 <parameter property="bookPrice" resultMap="BookResultMap" /> 11 </parameterMap> 12 <!-- 保存一個Book --> 13 <insert id="saveBook" parameterMap="BookParameterMap"> 14 insert into BOOK_MANAGE 15 (ID,NAME,PRICE) 16 values 17 (Bookmanage_Seq.Nextval,#{bookName},#{bookPrice}) 18 </insert> 19 20 <!-- 根據ID修改Book --> 21 <update id="updatePersnById" parameterMap="BookParameterMap"> 22 update BOOK_MANAGE 23 set 24 NAME=#{bookName}, 25 PRICE=#{bookPrice} 26 WHERE id=#{id} 27 </update>

?

  當查詢的結果與POJO名字不一致的時候,用resultMap來實現映射。

1 <resultMap type="user" id="userMap"> 2 <id column="id_" property="id" /> 3 <result column="username_" property="username" /> 4 </resultMap> 5 <select id="findUserMapById" parameterType="java.lang.Integer" resultMap="userMap" > 6 select id id_,username username_ from user where id = #{id} 7 </select>

  <id?/>:此屬性表示查詢結果集的唯一標識,非常重要。如果是多個字段為復合唯一約束則定義多個<id?/>

  Property:表示person類的屬性。

  Column:表示sql查詢出來的字段名。

  Columnproperty放在一塊兒表示將sql查詢出來的字段映射到指定的pojo類屬性上。

?  ?<result?/>:普通結果,即pojo的屬性。

?

  使用resultType進行輸出映射,只有查詢出來的列名和pojo中的屬性名一致,該列才可以映射成功。如果查詢出來的列名和pojo的屬性名不一致,通過定義一個resultMap對列名和pojo屬性名之間作一個映射關系。

  • resultType(輸出類型)

  1、輸出簡單類型

  映射文件:

?

1 <select id="findUserCount" parameterType="user" resultType="int"> 2 select count(1) from user 3 </select>

?

  輸出簡單類型必須查詢出來的結果集有一條記錄,最終將第一個字段的值轉換為輸出類型。使用sessionselectOne可查詢單條記錄。

  2、輸出pojo對象

  映射文件

?

1 <!-- 根據id查詢用戶信息 --> 2 <select id="findUserById" parameterType="int" resultType="user"> 3 select * from user where id = #{id} 4 </select>

?

  3、輸出pojo列表

  映射文件:

?

1 <!-- 根據名稱模糊查詢用戶信息 --> 2 <select id="findUserByUsername" parameterType="string" resultType="user"> 3 select * from user where username like '%${value}%' 4 </select>

?

  注意:MyBatis會根據Mapper接口方法的返回類型來選擇調用selectOne還是selectList方法,如果是List這調用selectList方法,如果是POJO則調用selectOne方法。

  4、輸出hashmap

?

  輸出pojo對象可以改用hashmap輸出類型,將輸出的字段名稱作為mapkeyvalue為字段值。

  resultType總結:

?

  輸出pojo對象和輸出pojo列表在sql中定義的resultType是一樣的。返回單個pojo對象要保證sql查詢出來的結果集為單條,內部使用session.selectOne方法調用,mapper接口使用pojo對象作為方法返回值。返回pojo列表表示查詢出來的結果集可能為多條,內部使用session.selectList方法,mapper接口使用List<pojo>對象作為方法返回值。

  • 動態SQl

?

  mybatis核心?對sql語句進行靈活操作,通過表達式進行判斷,對sql進行靈活拼接、組裝。對查詢條件進行判斷,如果輸入參數不為空才進行查詢條件拼接。

  1、if

1 <!-- 傳遞pojo綜合查詢用戶信息 --> 2 <select id="findUserList" parameterType="user" resultType="user"> 3 select * from user 4 where 1=1 5 <if test="id!=null and id!=''"> 6 and id=#{id} 7 </if> 8 <if test="username!=null and username!=''"> 9 and username like '%${username}%' 10 </if> 11 </select>

  2、Where

  上面的配置也可以按如下來寫:

1 <select id="findUserList" parameterType="user" resultType="user"> 2 select * from user 3 <where> 4 <if test="id!=null and id!=''"> 5 and id=#{id} 6 </if> 7 <if test="username!=null and username!=''"> 8 and username like '%${username}%' 9 </if> 10 </where> 11 </select>

  <where?/>可以自動處理第一個and

  3、foreach

  sql傳遞數組或Listmybatis使用foreach解析,如下:

  如果我們需要傳入多個ID來查詢多個用戶的信息,這也就可以使用foreach。我們先考慮下如果只寫sql語句是如下:

?

1 SELECT * FROM USERS WHERE username LIKE '%張%' AND (id =10 OR id =89 OR id=16) 2 SELECT * FROM USERS WHERE username LIKE '%張%' id IN (10,89,16)

?

  index:為數組的下標。

  item:為數組每個元素的名稱,名稱隨意定義

  open:循環開始

  close:循環結束

  separator:中間分隔輸出

  通過POJO傳入List,映射文件如下:

1 <if test="ids!=null and ids.size>0"> 2 <foreach collection="ids" open=" and id in(" close=")" item="id" separator="," > 3 #{id} 4 </foreach> 5 </if>

  或者:

1 <if test="ids!=null and ids.size>0"> 2 <foreach collection="ids" open=" and (" close=")" item="id" separator="," > 3 id = #{id} 4 </foreach> 5 </if>

?  傳遞單個List

  傳遞List類型在編寫mapper.xml沒有區別,唯一不同的是只有一個List參數時它的參數名為list

  配置文件如下:

?

<select id="selectUserByList" parameterType="java.util.List" resultType="user">select * from user <where><!-- 傳遞List,List中是pojo --><if test="list!=null"><foreach collection="list" item="item" open="and id in("separator=","close=")">#{item.id} </foreach></if></where> </select>

?

  傳遞單個數組(數組中是POJO)

<!-- 傳遞數組綜合查詢用戶信息 --><select id="selectUserByArray" parameterType="Object[]" resultType="user">select * from user <where><!-- 傳遞數組 --><if test="array!=null"><foreach collection="array" index="index" item="item" open="and id in("separator=","close=")">#{item.id} </foreach></if></where> </select>

  sql只接收一個數組參數,這時sql解析參數的名稱mybatis固定為array,如果數組是通過一個pojo傳遞到sql則參數的名稱為pojo中的屬性名。

  傳遞單個數組(數組中是簡單類型)

  配置文件如下:

1 <!-- 傳遞數組綜合查詢用戶信息 --> 2 <select id="selectUserByArray" parameterType="Object[]" resultType="user"> 3 select * from user 4 <where> 5 <!-- 傳遞數組 --> 6 <if test="array!=null"> 7 <foreach collection="array"index="index"item="item"open="and id in("separator=","close=")"> 8 #{item} 9 </foreach> 10 </if> 11 </where> 12 </select>

  如果數組中是簡單類型則寫為#{item},不用再通過ognl獲取對象屬性值了。

?

? ? Sql片段

  Sql中可將重復的sql提取出來,使用時用include引用即可,最終達到sql重用的目的,如下:

  映射文件如下:

?

1 <!-- 傳遞pojo綜合查詢用戶信息 --> 2 <select id="findUserList" parameterType="user" resultType="user"> 3 select * from user 4 <where> 5 <if test="id!=null and id!=''"> 6 and id=#{id} 7 </if> 8 <if test="username!=null and username!=''"> 9 and username like '%${username}%' 10 </if> 11 </where> 12 </select>

?

  如果有多個statement都使用相同的查詢條件,那么就可以把查詢條件抽取出來作為單獨的Sql片段。

  Sql片段配置:

1 <sql id="query_user_where"> 2 <if test="id!=null and id!=''"> 3 and id=#{id} 4 </if> 5 <if test="username!=null and username!=''"> 6 and username like '%${username}%' 7 </if> 8 </sql>

  使用include引用:

?

1 <select id="findUserList" parameterType="user" resultType="user"> 2 select * from user 3 <where> 4 <include refid="query_user_where"/> 5 </where> 6 </select>

?

  注意:如果引用其它mapper.xmlsql片段,則在引用時需要加上namespace,如下:<include?refid="namespace.sql片段”/>

  Mapper配置文件中常用的基本屬性就是這些,如果還有其他的特殊需求可以根據需要來進行修改配置。另外,在我們的設計中,如果已經定義好了基本的POJO在引用的時候可以在定義一個視圖查詢層的POJO在其中封裝基本的POJO和自定義的POJO(繼承基本的POJO),這樣就可以較容易實現擴展。當數據庫需求有變化的時候可以不修改基本POJO,而修改自定義的POJO,這樣就可以實現較好的擴展,而不影響其他模塊。如果前端需求有變動,可以通過修改前端的POJO來實現較小的改動。如下實現:

  基本的POJO類型:

1 public class User { 2 private int id; 3 private String username;// 用戶姓名 4 private String sex;// 性別 5 private Date birthday;// 生日 6 private String address;// 地址 7 public int getId() { 8 return id; 9 } 10 public void setId(int id) { 11 this.id = id; 12 } 13 public String getUsername() { 14 return username; 15 } 16 public void setUsername(String username) { 17 this.username = username; 18 } 19 public String getSex() { 20 return sex; 21 } 22 public void setSex(String sex) { 23 this.sex = sex; 24 } 25 public Date getBirthday() { 26 return birthday; 27 } 28 public void setBirthday(Date birthday) { 29 this.birthday = birthday; 30 } 31 public String getAddress() { 32 return address; 33 } 34 public void setAddress(String address) { 35 this.address = address; 36 } 37 @Override 38 public String toString() { 39 // TODO Auto-generated method stub 40 return this.id+"-"+this.username+"-"+this.sex+"-"+this.address+"-"+this.birthday.toString(); 41 } 42 43 }

  自定義的POJO繼承基本的POJO:

1 public class UserCustom extends User{ 2 3 }

  如果我們的數據庫有變動,我們可以在UserCustom添加屬性,只滿足當前修改。

  前端POJO實現:

1 public class QueryVo { 2 private User user; 3 //自定義用戶擴展類 4 private UserCustom custom; 5 public User getUser() { 6 return user; 7 } 8 public void setUser(User user) { 9 this.user = user; 10 } 11 public UserCustom getCustom() { 12 return custom; 13 } 14 public void setCustom(UserCustom custom) { 15 this.custom = custom; 16 } 17 }

  可以滿足基本的需求,如果我們在查詢中需要加入其他查詢條件,如:商品、訂單等,只需要修改QueryVo,這樣就可以實現較好的可擴展性。?

?

總結

以上是生活随笔為你收集整理的Mybatis学习--Mapper.xml映射文件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。