MyBatis的使用四(查詢詳解)

2023-02-03 21:01:42

本文主要講述如何在mybatis中進行查詢操作【詳解】

一. 查詢User物件

  1.查詢單個物件User

  SelectUser介面宣告如下

// 主要條件是使用id
public interface SelectUser {

    // 查詢單行資料,返回物件User
    User getUserSingleByID(@Param("id") int id);
}

  SelectUser.xml檔案宣告如下

<mapper namespace="com.hspedu.mapper.SelectUser">
<!--User getUserSingleByID(@Param("id") int id)--> <select id="getUserSingleByID" resultType="User"> select * from t_user where id = #{id}; </select> </mapper>

  2. 查詢多個物件User

  SelectUser介面宣告如下

// 主要條件是使用id
public interface SelectUser {

    // 查詢多行資料,返回User類的集合【查詢 >= id 的資料】
    List<User> getUserListByID(@Param("id") int id);
}

  SelectUser.xml檔案宣告如下

<mapper namespace="com.hspedu.mapper.SelectUser">

    <!--List<User> getUserListByID(@Param("id") int id)-->
    <select id="getUserListByID" resultType="User">
        select * from t_user where id >= #{id}
    </select>
</mapper>

  問題:當查詢單個物件時,是否可以用List<User>作為返回型別?

  SelectUser介面宣告如下

// 主要條件是使用id
public interface SelectUser {

    // 查詢單行資料,返回物件User
    List<User> getUserSingleByID(@Param("id") int id);
}

  SelectUser.xml檔案宣告如下

<mapper namespace="com.hspedu.mapper.SelectUser">
    <!--User getUserSingleByID(@Param("id") int id)-->
    <select id="getUserSingleByID" resultType="User">
        select * from t_user where id = #{id};
    </select>
</mapper>

  測試test

    @Test
    // 使用id查詢單個資料User
    public void selectUserByID(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SelectUser mapper = sqlSession.getMapper(SelectUser.class);
        List<User> user = mapper.getUserSingleByID(12);
        System.out.println(user);
        sqlSession.close();
    }

  測試結果如下

   執行結果正常

  總結:當返回的資料物件不清楚有幾個的情況,建議使用List<User>

二. 查詢欄位

  1.查詢單個欄位【單行】

  SelectUser介面宣告如下

// 主要條件是使用id
public interface SelectUser {
    // 查詢單個欄位【單行】
    // 返回型別根據欄位的型別而定,具體問題具體分析
    String getNameByID(@Param("id") int id);
}

  SelectUser.xml檔案宣告如下

<mapper namespace="com.hspedu.mapper.SelectUser">

    <!--String getNameByID(@Param("id") int id)-->
    <select id="getNameByID" resultType="string">
        select username from t_user where id = #{id}
    </select>
</mapper>

  注意:在SelectUser介面定義的方法 getNameByID() 的返回型別需要根據欄位的型別來指明,或者直接使用Object。

  2. 查詢單個欄位【多行】

  SelectUser介面宣告如下

public interface SelectUser {
    // 查詢單個欄位【多行】
    List<String> getNameRowsByID(@Param("id") int id);
}
    

  SelectUser.xml檔案宣告如下

<mapper namespace="com.hspedu.mapper.SelectUser">

    <!--List<String> getNameRowsByID(@Param("id") int id);-->
    <select id="getNameRowsByID" resultType="string">
        select username from t_user where id >= #{id}
    </select>
</mapper>

  與 一中查詢多行資料類似,返回型別是List<欄位型別或者Object>

  3. 查詢多個欄位【單行】

  SelectUser介面宣告如下

// 主要條件是使用id
public interface SelectUser {

    // 查詢多個欄位【單行】
    // Map<String,Object> 中 key是欄位名,value是屬性值
    Map<String,Object> getColsByID(@Param("id") int id);
}

  SelectUser.xml檔案宣告如下

<mapper namespace="com.hspedu.mapper.SelectUser">

    <!--Map<String,Object> getColsByID(@Param("id") int id)-->
    <select id = "getColsByID" resultType="map">
        select username,password,age from t_user where id = #{id}
    </select>
</mapper>

  在SelectUser介面定義的方法返回型別是Map<String,Object>型別,

  Map<String,Object>的key是欄位名,value是屬性值,這裡的Object用的巧妙

  4. 查詢多個欄位【多行】

  SelectUser介面宣告如下

public interface SelectUser {
    // 查詢多個欄位【多行】
    // 此時不能使用 Map<String,Object> 作為返回型別,資料不止一條
    // 方式1:使用List<Map<>>
    List<Map<String,Object>> getClosRowsByID(@Param("id") int id);
    // 方式2:使用@MapKey("欄位名") 查出的結果 Map<Map<>>
    //      @MapKey("欄位名"),key是欄位名【唯一標誌該行資料】value是該行資料
    //      此時在xml檔案,查詢欄位必須要包含唯一標識id
    @MapKey("id")
    // Map<String,Object> getMapsByID(@Param("id") int id);
    Map<Integer,Object> getMapsByID(@Param("id") int id);
}

  SelectUser.xml檔案宣告如下

<mapper namespace="com.hspedu.mapper.SelectUser">
  <!--方式1:使用List<Map<>> -->
    <!--Map<String,Object> getClosRowsByID(@Param("id") int id);-->
    <select id="getClosRowsByID" resultType="map">
        select username,password,age from t_user where id >= #{id}
    </select>

  <!--方式2:使用@MapKey註解 -->
    <!--@MapKey("id")
    Map<String,Object> getMapsByID(@Param("id") int id);-->
    <select id="getMapsByID" resultType="map">
        select id,username,password,age from t_user where id >= #{id}
    </select>

</mapper>

  方式1:測試test

    @Test
    // 根據id查詢多個欄位【多行】方式一:
    public void selectColsRowsByID(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SelectUser mapper = sqlSession.getMapper(SelectUser.class);
        List<Map<String, Object>> mapList = mapper.getClosRowsByID(6);
        // 遍歷集合
        for (Map<String, Object> map : mapList) {
            System.out.println(map);
        }
        sqlSession.close();
    }

  測試結果如下

{password=tom123, age=20, username=Tom}
{password=tom123, age=20, username=Tom}
{password=tom123, age=20, username=Tom}
{password=tom12345, age=20, username=jack}
{password=hsp12345, age=25, username=hsp}
{password=tom123, age=20, username=Tom}
{password=tom123, age=20, username=Tom}
{password=tom123, age=20, username=Tom}
{password=hsp12345, age=25, username=hsp}

  方式2:測試test

    @Test
    // 根據id查詢多個欄位【多行】方式二:
    public void selectMapsByID(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SelectUser mapper = sqlSession.getMapper(SelectUser.class);
        Map<Integer, Object> maps = mapper.getMapsByID(6);
        // 遍歷map,注意此時map的結構 Map<id=Map,id=Map...>
        Set<Integer> keySet = maps.keySet();
        //  java.lang.Integer cannot be cast to java.lang.String
        // [16, 6, 9, 10, 11, 12, 13, 14, 15]
        // id的欄位型別: class java.lang.Integer.
        // 因此需要將Map<String,Object> 變成Map<Integer,Object>
        for (Integer s : keySet) {
            System.out.println(maps.get(s));
        }
        sqlSession.close();
    }

  測試結果如下

{password=hsp12345, id=16, age=25, username=hsp}
{password=tom123, id=6, age=20, username=Tom}
{password=tom123, id=9, age=20, username=Tom}
{password=tom123, id=10, age=20, username=Tom}
{password=tom12345, id=11, age=20, username=jack}
{password=hsp12345, id=12, age=25, username=hsp}
{password=tom123, id=13, age=20, username=Tom}
{password=tom123, id=14, age=20, username=Tom}
{password=tom123, id=15, age=20, username=Tom}

  注意方式1和方式2的區別

  方式1的返回型別是List<Map>,即 將查詢到的每行結果 --存放-->Map<String,Object> ---封裝--> List<Map<String,Object>>。

    List<Map<>>的結構如下

[{password=tom123, age=20, username=Tom},{password=tom123, age=20, username=Tom}, 
{password=tom123, age=20, username=Tom}, 
{password=tom12345, age=20, username=jack}, 
{password=hsp12345, age=25, username=hsp}, 
{password=tom123, age=20, username=Tom}, 
{password=tom123, age=20, username=Tom}, 
{password=tom123, age=20, username=Tom}, 
{password=hsp12345, age=25, username=hsp}]

  方式2是通過註解@MapKey("欄位名"),注意這裡的欄位名是作為每行資料value的key【因此應該選擇能夠唯一標識某一行資料的欄位名作為每行資料的key】。

    Map< " 欄位名的值 " = Map<>>的結構如下

{16={password=hsp12345, id=16, age=25, username=hsp},
 6={password=tom123, id=6, age=20, username=Tom}, 
9={password=tom123, id=9, age=20, username=Tom}, 
10={password=tom123, id=10, age=20, username=Tom},
 11={password=tom12345, id=11, age=20, username=jack},
 12={password=hsp12345, id=12, age=25, username=hsp},
 13={password=tom123, id=13, age=20, username=Tom}, 
14={password=tom123, id=14, age=20, username=Tom}, 
15={password=tom123, id=15, age=20, username=Tom}}