Mapper.xml映射文件---Mybatis学习笔记(八)
Mapper.xml映射文件中定義了操作數據庫的sql,每個sql是一個statement,映射文件是mybatis的核心。
parameterType(輸入類型)
1.#{}與${}
#{}實現的是向prepareStatement中的預處理語句中設置參數值,sql語句中#{}表示一個占位符即?。
<!-- 根據id查詢用戶信息 --><select id="findUserById" parameterType="int" resultType="user">select * from user where id = #{id}</select>使用占位符#{}可以有效防止sql注入,在使用時不需要關心參數值的類型,mybatis會自動進行java類型和jdbc類型的轉換。
#{}可以接收簡單類型值或pojo屬性值,如果parameterType傳輸單個簡單類型值,#{}括號中可以是value或其它名稱。
${}和#{}不同,通過${}可以將parameterType 傳入的內容拼接在sql中且不進行jdbc類型轉換。
${}可以接收簡單類型值或pojo屬性值,如果parameterType傳輸單個簡單類型值,${}括號中只能是value。使用不能防止sql注入,但是有時用{}會非常方便,如下的例子:
如果本例子使用#{}則傳入的字符串中必須有%號,而%是人為拼接在參數中,顯然有點麻煩,如果采用${}在sql中拼接為%的方式則在調用mapper接口傳遞參數就方便很多。
//如果使用占位符號則必須人為在傳參數中加% List<User> list = userMapper.selectUserByName("%管理員%"); //如果使用${}原始符號則不用人為在參數中加% List<User>list = userMapper.selectUserByName("管理員");再比如order by排序,如果將列名通過參數傳入sql,根據傳的列名進行排序,應該寫為:
ORDER BY ${columnName}如果使用#{}將無法實現此功能。
2.傳遞簡單類型
<select id="findUserById" parameterType="int" resultType="user">select * from user where id=#{id} </select>3.傳遞pojo對象
Mybatis使用ognl表達式解析對象字段的值,如下例子:
<!—傳遞pojo對象綜合查詢用戶信息 --><select id="findUserByUser" parameterType="user" resultType="user">select * from user where id=#{id} and username like '%${username}%'</select>上邊sql語句中的id和username是user對象中的字段名稱。
注意:parameterType中的user是事先在sqlMapConfig.xml文件中配置了別名的,如下:
4.傳遞pojo包裝對象
需求:
開發中通過pojo傳遞查詢條件 ,查詢條件是綜合的查詢條件,不僅包括用戶查詢條件還包括其它的查詢條件(比如將用戶購買商品信息也作為查詢條件),這時可以使用包裝對象傳遞輸入參數。
1.自定義包裝對象:
定義包裝對象將查詢條件(pojo)以類組合的方式包裝起來。
2.映射文件:
<select id="findUserList" parameterType="com.huihui.pojo.UserQueryVo" resultType="user">select * from user where username=#{user.username} and sex=#{user.sex} </select>說明:mybatis底層通過ognl從pojo中獲取屬性值:#{user.username},user即是傳入的包裝對象的屬性。com.huihui.pojo.UserQueryVo是定義的包裝對象類型。
3.Mapper接口
public interface UserMapper {public List<User> findUserList(UserQueryVo queryVo) throws Exception;}5.傳遞hashmap
映射文件:
<!-- 傳遞hashmap綜合查詢用戶信息 --><select id="findUserByHashmap" parameterType="hashmap" resultType="user">select * from user where id=#{id} and username like '%${username}%'</select>注意:
1.sql語句中的id和username是hashmap的key。
2.parameterType中的hashmap是別名
Mapper接口:
public interface UserMapper {public User findUserByHashMap(Map map) throws Exception; }測試類:
@Testpublic void testFindUserByHashMap() throws Exception{SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);Map<String,Object> map = new HashMap<String,Object>();map.put("id", 26);map.put("username", "王五");User user = userMapper.findUserByHashMap(map);System.out.println(user);}1.resultType(輸出類型)
使用resultType進行輸出映射,只有查詢出來的列名和pojo中的屬性名一致,該列才可以映射成功。
如果查詢出來的列名和pojo中的屬性名全部不一致,那么就不會創建pojo對象。
只要查詢出來的列名和pojo中的屬性有一個一致,就會創建pojo對象。
輸出簡單類型:
映射文件:
<!-- 獲取用戶列表總數 --> <select id="findUserCount" resultType="int">select count(*) from user </select>Mapper接口:
public int findUserCount() throws Exception;測試類:
Public void testFindUserCount() throws Exception{//獲取sessionSqlSession session = sqlSessionFactory.openSession();//獲取mapper接口實例UserMapper userMapper = session.getMapper(UserMapper.class);int count = userMapper.findUserCount();//關閉sessionsession.close();}總結:
輸出簡單類型必須查詢出來的結果集有一條記錄,最終將第一個字段的值轉換為輸出類型。
使用session的selectOne可查詢單條記錄。
輸出pojo對象:
映射文件:
<!-- 根據id查詢用戶信息 --><select id="findUserById" parameterType="int" resultType="user">select * from user where id = #{id}</select>mapper接口:
public User findUserById(int id) throws Exception;測試:
Public void testFindUserById() throws Exception {//獲取sessionSqlSession session = sqlSessionFactory.openSession();//獲限mapper接口實例UserMapper userMapper = session.getMapper(UserMapper.class);//通過mapper接口調用statementUser user = userMapper.findUserById(1);System.out.println(user);//關閉sessionsession.close();}這里使用session調用selectOne查詢單條記錄。
輸出pojo列表:
映射文件:
<!-- 根據名稱模糊查詢用戶信息 --><select id="findUserByUsername" parameterType="string" resultType="user">select * from user where username like '%${value}%'</select>mapper接口:
public List<User> findUserByUsername(String username) throws Exception;測試:
Public void testFindUserByUsername()throws Exception{//獲取sessionSqlSession session = sqlSessionFactory.openSession();//獲限mapper接口實例UserMapper userMapper = session.getMapper(UserMapper.class);//如果使用占位符號則必須人為在傳參數中加%//List<User> list = userMapper.selectUserByName("%管理員%");//如果使用${}原始符號則不用人為在參數中加%List<User> list = userMapper.findUserByUsername("管理員");//關閉sessionsession.close();}這里使用session的selectList方法獲取pojo列表。
輸出hashmap:
輸出pojo對象可以改用hashmap輸出類型,將輸出的字段名稱作為map的key,value為字段值。
resultType總結:
輸出pojo對象和輸出pojo列表在sql中定義的resultType是一樣的。
返回單個pojo對象要保證sql查詢出來的結果集為單條,內部使用session.selectOne方法調用,mapper接口使用pojo對象作為方法返回值。
返回pojo列表表示查詢出來的結果集可能為多條,內部使用session.selectList方法,mapper接口使用List對象作為方法返回值。
2.resultMap(輸出類型)
resultType可以指定pojo將查詢結果映射為pojo,但需要pojo的屬性名和sql查詢的列名一致方可映射成功。
如果sql查詢字段名和pojo的屬性名不一致,可以通過resultMap將字段名和屬性名作一個對應關系 ,resultMap實質上還需要將查詢結果映射到pojo對象中。
resultMap可以實現將查詢結果映射為復雜類型的pojo,比如在查詢結果映射對象中包括pojo和list實現一對一查詢和一對多查詢。
1.映射文件:
說明:
<id />:此屬性表示查詢結果集的唯一標識,非常重要。如果是多個字段為復合唯一約束則定義多個<id />。
Property:表示person類的屬性。
Column:表示sql查詢出來的字段名。
Column和property放在一塊兒表示將sql查詢出來的字段映射到指定的pojo類屬性上。
:普通結果,即pojo的屬性。
2.Mapper接口
public User findUserInfo(int id) throws Exception;3.測試:
@Testpublic void testFindUserInfo() throws Exception{SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = userMapper.findUserInfo(24);System.out.println(user);sqlSession.close();}動態sql
通過mybatis提供的各種標簽方法實現動態拼接sql。
if
<!-- 傳遞pojo綜合查詢用戶信息 --><select id="findUserList" parameterType="user" resultType="user">select * from user where 1=1 <if test="id!=null and id!=''">and id=#{id}</if><if test="username!=null and username!=''">and username like '%${username}%'</if></select>注意要做不等于空字符串校驗。
where
上邊的sql也可以改為:
<select id="findUserList" parameterType="user" resultType="user">select * from user <where><if test="id!=null and id!=''">and id=#{id}</if><if test="username!=null and username!=''">and username like '%${username}%'</if></where></select>可以自動處理第一個and。
sql片段
Sql中可將重復的sql提取出來,使用時用include引用即可,最終達到sql重用的目的,如下:
<!-- 傳遞pojo綜合查詢用戶信息 --><select id="findUserList" parameterType="user" resultType="user">select * from user <where><if test="id!=null and id!=''">and id=#{id}</if><if test="username!=null and username!=''">and username like '%${username}%'</if></where></select>將where條件抽取出來:
<sql id="query_user_where"><if test="id!=null and id!=''">and id=#{id}</if><if test="username!=null and username!=''">and username like '%${username}%'</if> </sql>使用include引用:
<select id="findUserList" parameterType="user" resultType="user">select * from user <where><include refid="query_user_where"/></where></select>注意:如果引用其它mapper.xml的sql片段,則在引用時需要加上namespace,如下:
<include refid="namespace.sql片段”/>經驗:
foreach
向sql傳遞數組或List,mybatis使用foreach解析,如下:
1. 通過pojo傳遞list
需求:
傳入多個id查詢用戶信息,用下邊兩個sql實現:
在pojo中定義list屬性ids存儲多個用戶id,并添加getter/setter方法
public class UserQueryIds {//傳遞多個用戶idprivate List<Integer> ids;public List<Integer> getIds() {return ids;}public void setIds(List<Integer> ids) {this.ids = ids;}}映射文件(mapper.xml):
<select id="findUserByIds" parameterType="com.huihui.pojo.UserQueryIds" resultType="user">select * from user<where><if test="ids!=null and ids.size>0"><foreach collection="ids" item="id" open="and id in (" close=")" separator=",">#{id}</foreach></if></where> </select>說明:
collection:指定輸入對象中集合屬性名(也就是上面pojo中定義的屬性名)
item:定義每次遍歷后生成的對象的對象名
open:開始遍歷時要拼接的字符串
close:結束遍歷時要拼接的字符串
separator:定義遍歷后產生的每個對象之間的字符串
<foreach></foreach>之間的內容:表示每次遍歷需要拼接的字符串
mapper接口:
public List<User> findUserByIds(UserQueryIds ids) throws Exception;測試:
@Testpublic void testFindUserByIds() throws Exception{SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);UserQueryIds ids = new UserQueryIds();List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(10);list.add(28);ids.setIds(list);List<User> users = userMapper.findUserByIds(ids);System.out.println(users.size());sqlSession.close();}2.傳遞單個List
傳遞List類型在編寫mapper.xml沒有區別,唯一不同的是只有一個List參數時它的參數名為list。
映射文件:
mapper接口:
public List<User> findUserBymIds(List<Integer> list) throws Exception;測試:
@Testpublic void testFindUserBymIds() throws Exception{SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(10);list.add(28);List<User> users = userMapper.findUserBymIds(list);System.out.println(users.size());sqlSession.close();}3.傳遞單個數組(數組中時pojo)
映射文件:
說明:
sql只接收一個數組參數,這時sql解析參數的名稱mybatis固定為array,如果數組是通過一個pojo傳遞到sql則參數的名稱為pojo中的屬性名。
index:為數組的下標。
item:為遍歷后生成的數組每個元素的名稱,名稱隨意定義
open:循環開始需要拼接的字符串
close:循環結束需要拼接的字符串
separator:定義遍歷后產生的每個對象之間的字符串
mapper接口:
public List<User> findUserByArray(Object[] objs) throws Exception;測試:
@Testpublic void testFindUserByArray() throws Exception{SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user1 = new User();user1.setId(1);User user2 = new User();user2.setId(10);User user3 = new User();user3.setId(28);User[] users = {user1,user2,user3};List<User> list = userMapper.findUserByArray(users);System.out.println(list.size());sqlSession.close();}4.傳遞單個數組(數組中是字符串類型)
映射文件:
mapper接口:
public List<User> findUserByArray1(Object[] objs) throws Exception;測試:
@Testpublic void testFindUserByArray1() throws Exception{SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);String[] ids = {"1","10","28"};List<User> users = userMapper.findUserByArray1(ids);System.out.println(users.size());sqlSession.close();}總結
以上是生活随笔為你收集整理的Mapper.xml映射文件---Mybatis学习笔记(八)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SqlMapConfig.xml配置文件
- 下一篇: MyEclipse/Eclipse中pr