1. 程式人生 > >Mybatis中輸入輸出映射和動態Sql

Mybatis中輸入輸出映射和動態Sql

list stat map 單表 .get 行動 ets 一個 from

一、輸入映射

  我們通過配置parameterType的值來指定輸入參數的類型,這些類型可以是簡單數據類型、POJO、HashMap等數據類型

  1、簡單類型

技術分享圖片

  2、POJO包裝類型

  ①這是單表查詢的時候傳入的POJO包裝類型,即可以直接傳入實體類,但是當多表查詢的時候,就需要自定義POJO類型

技術分享圖片

  ②我們使用自定義POJO類型來具體的了解一下

  先設計 包裝類型如下,其中UserPOJO是除了User本身之外的添加的其他跟User相關的屬性的包裝類,UserVo是用於視圖層面的包裝類型,同樣也是作為Mapper配置文件的輸入類型

技術分享圖片

  其中User文件同上一篇Mybatis簡單入門中的User,包括數據表部分也一樣。這裏給出UserPoJO和UserVo文件

技術分享圖片
 1 package cn.mybatis.po;
 2 
 3 public class UserPoJo extends User{
 4     private User user;
 5 
 6     public void setUser(User user) {
 7         this.user = user;
 8     }
 9 
10     public User getUser() {
11         return user;
12     }
13 }
UserPOJO

技術分享圖片
 1 package cn.mybatis.po;
 2 
 3 public
class UserVo { 4 private UserPoJo userPoJo; 5 6 public UserPoJo getUserPoJo() { 7 return userPoJo; 8 } 9 10 public void setUserPoJo(UserPoJo userPoJo) { 11 this.userPoJo = userPoJo; 12 } 13 }
UserVo

  然後我們配置UserMapper.xml文件

技術分享圖片

  然後在UserMapper接口文件中添加

    //
測試包裝類型的查詢 public List<UserPoJo> findUserList(UserVo userVo) throws Exception;

  使用Junit測試剛剛做的配置

 1     @Test
 2     public void testFindUserList() throws Exception {
 3         SqlSession sqlSession = sqlSessionFactory.openSession();
 4         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
 5 
 6         UserPoJo userPoJo = new UserPoJo();
 7         UserVo userVo = new UserVo();
 8         userPoJo.setSex("男");
 9         userPoJo.setUsername("u");
10         userVo.setUserPoJo(userPoJo);
11 
12         List<UserPoJo> userPoJoList = userMapper.findUserList(userVo);
13 
14         System.out.println(userPoJoList);
15     }

  最後結果如下

技術分享圖片

二、輸出映射

1、resultType

①在使用resultType進行映射的時候,只有查詢出來的列名和包裝類型中的屬性名一致的時候,才會映射成功

②當使用簡單類型作為輸出映射的時候,我們需要保證Sql查詢的結果只有一行一列,這樣就可以使用簡單類型

如下所示示例

SELECT COUNT(*) FROM t_user

SELECT username FROM t_user WHERE id = 2

2、resultMap  

  查詢出來的列名和包裝類型的屬性名不一致的時候,可以使用resultMap來進行相應的映射(具體在使用中來說就是:定義resultMap中和屬性的映射關系,然後將輸出結果設置為resultMap的類型)  

  下面我們使用一個例子來進行具體的測試

  ①首先編寫mapper配置文件,其中需要加上resultMap的配置

 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.mybatis.mapper.UserMapper">
 6 
 7     <!--定義resultMap
 8         type:resultMap最終映射的Java對象類型
 9         id:對resultMap的標識
10     -->
11     <resultMap id="userResultMap" type="user">
12         <!--id:標識查詢結果集中的唯一標識-->
13         <id column="_id" property="id"></id>
14         <!--result:標識查詢結果集中其他列的標識-->
15         <result column="_username" property="username"></result>
16         <result column="_password" property="password"></result>
17         <result column="_sex" property="sex"></result>
18         <result column="_address" property="address"></result>
19     </resultMap>
20 
21     <select id="findUserById_resultMap" parameterType="int" resultMap="userResultMap">
22         SELECT id _id, username _username, PASSWORD _password, address _address, sex _sex FROM t_user WHERE id = #{id}
23     </select>
24 </mapper>

  ②然後在Mapper接口中添加方法

    //測試resultMap
    public User findUserById_resultMap(int id) throws Exception;

  ③ 測試方法

1     @Test
2     public void testFindUserById_resultMap() throws Exception {
3         SqlSession sqlSession = sqlSessionFactory.openSession();
4         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
5 
6         User user = userMapper.findUserById_resultMap(2);
7 
8         System.out.println(user);
9     }

  ④可以發現,使用resultMap的方式跟直接查詢的結果是一致的

技術分享圖片

三、動態Sql

1、if判斷

我們在上面使用包裝類查詢的用例的時候,考慮到可能出現userPoJo會是null的情況,以及其相應的屬性也可能是null的情況,這樣的話,如果我們直接在Sql中進行拼接而不做判斷的話,可能會出現一些錯誤,所以我們使用if來進行動態的拼接。

    <select id="findUserList" parameterType="cn.mybatis.po.UserVo" resultType="cn.mybatis.po.UserPoJo">
        SELECT * FROM t_user
        <where>
            <if test="userPoJo != null">
                <if test="userPoJo.sex != null and userPoJo.sex != ‘‘">
                    AND sex = #{userPoJo.sex}
                </if>
                <if test="userPoJo.username != null and userPoJo.username != ‘‘">
                    AND username LIKE ‘%${userPoJo.username}%‘
                </if>
            </if>
        </where>
    </select>

技術分享圖片

2.Sql片段

上面的例子中,我們可以將if判斷抽取出來作為一個Sql片段,這樣做的好處是,可能再進行別的單表查詢User信息的時候可以重復使用這些Sql。

 1     <!--定義Sql片段-->
 2     <sql id="query_user_info">
 3         <if test="userPoJo != null">
 4             <if test="userPoJo.sex != null and userPoJo.sex != ‘‘">
 5                 AND sex = #{userPoJo.sex}
 6             </if>
 7             <if test="userPoJo.username != null and userPoJo.username != ‘‘">
 8                 AND username LIKE ‘%${userPoJo.username}%‘
 9             </if>
10         </if>
11     </sql>

然後在別的Sql中將上面的Sql片段引入拼接即可

1     <select id="findUserList" parameterType="cn.mybatis.po.UserVo" resultType="cn.mybatis.po.UserPoJo">
2         SELECT * FROM t_user
3         <where>
4             <include refid="query_user_info"></include>
5         </where>
6     </select>

3.foreach

當我們需要一種同樣的查詢方式只是參數不同的時候:SELECT * FROM t_user WHERE 1=1 AND (id = 1 OR id =2 OR id = 3),可以使用foreach來記性sql拼接

    <sql id="query_ids">
        <if test="ids != null">
            <!--
                SELECT * FROM t_user WHERE 1=1 AND (id = 1 OR id =2 OR id = 3)
                cilleation: 指定的是輸入參數集合的屬性名
                item:每次遍歷的名稱
                open:開始遍歷時拼接串
                close:結束遍歷時候拼接的串
                separator:遍歷的兩個對象中間需要拼接的串
            -->
            <foreach collection="ids" item="item_id" open="AND (" close=")" separator=" OR ">
                id=#{item_id}
            </foreach>
        </if>
    </sql>

然後將上面的Sql片段加入響應的statment中

    <select id="findUserByIds" parameterType="userVo" resultType="userPoJo">
        SELECT * FROM t_user
        <where>
            <include refid="query_ids"></include>
        </where>
    </select>

測試結果如下

技術分享圖片

Mybatis中輸入輸出映射和動態Sql