MyBatis使用ResultMap及分頁


ResultMap及分頁

查詢為null問題

要解決的問題:屬性名和字段名不一致

1、查看數據庫的字段名

2、Java中的實體類設計

public class User {

   private int id;  //id
   private String name;   //姓名
   private String password;   //密碼和數據庫不一樣!
   
   //構造
   //set/get
   //toString()
}

3、接口

//根據id查詢用戶
User selectUserById(int id);

4、mapper映射文件

<select id="selectUserById" resultType="user">
  select * from user where id = #{id}
</select>

5、測試

@Test
public void testSelectUserById() {
   SqlSession session = MybatisUtils.getSession();  //獲取SqlSession連接
   UserMapper mapper = session.getMapper(UserMapper.class);
   User user = mapper.selectUserById(1);
   System.out.println(user);
   session.close();
}

結果:

  • User{id=1, name='狂神', password='null'}
  • 查詢出來發現 password 為空 . 說明出現了問題!

分析:

  • select * from user where id = #{id} 可以看做

    select id,name,pwd from user where id = #{id}

  • mybatis會根據這些查詢的列名(會將列名轉化為小寫,數據庫不區分大小寫) , 去對應的實體類中查找相應列名的set方法設值 , 由於找不到setPwd() , 所以password返回null ; 【自動映射】

解決方案

方案一:為列名指定別名 , 別名和java實體類的屬性名一致 .

<select id="selectUserById" resultType="User">
  select id , name , pwd as password from user where id = #{id}
</select>

方案二:使用結果集映射->ResultMap 【推薦】

<resultMap id="UserMap" type="User">
   <!-- id為主鍵 -->
   <id column="id" property="id"/>
   <!-- column是數據庫表的列名 , property是對應實體類的屬性名 -->
   <result column="name" property="name"/>
   <result column="pwd" property="password"/>
</resultMap>

<select id="selectUserById" resultMap="UserMap">
  select id , name , pwd from user where id = #{id}
</select>

ResultMap

自動映射

  • resultMap 元素是 MyBatis 中最重要最強大的元素。它可以讓你從 90% 的 JDBC ResultSets 數據提取代碼中解放出來。
  • 實際上,在為一些比如連接的復雜語句編寫映射代碼的時候,一份 resultMap 能夠代替實現同等功能的長達數千行的代碼。
  • ResultMap 的設計思想是,對於簡單的語句根本不需要配置顯式的結果映射,而對於復雜一點的語句只需要描述它們的關系就行了。

你已經見過簡單映射語句的示例了,但並沒有顯式指定 resultMap。比如:

<select id="selectUserById" resultType="map">
select id , name , pwd
  from user
  where id = #{id}
</select>

上述語句只是簡單地將所有的列映射到 HashMap 的鍵上,這由 resultType 屬性指定。雖然在大部分情況下都夠用,但是 HashMap 不是一個很好的模型。你的程序更可能會使用 JavaBean 或 POJO(Plain Old Java Objects,普通老式 Java 對象)作為模型。

ResultMap 最優秀的地方在於,雖然你已經對它相當了解了,但是根本就不需要顯式地用到他們。

手動映射

1、返回值類型為resultMap

<select id="selectUserById" resultMap="UserMap">
  select id , name , pwd from user where id = #{id}
</select>

2、編寫resultMap,實現手動映射!

<resultMap id="UserMap" type="User">
   <!-- id為主鍵 -->
   <id column="id" property="id"/>
   <!-- column是數據庫表的列名 , property是對應實體類的屬性名 -->
   <result column="name" property="name"/>
   <result column="pwd" property="password"/>
</resultMap>

如果世界總是這么簡單就好了。但是肯定不是的,數據庫中,存在一對多,多對一的情況,我們之后會使用到一些高級的結果集映射,association,collection

分頁的幾種方式

limit實現分頁

使用Limit實現分頁

#語法
SELECT * FROM table LIMIT stratIndex,pageSize

SELECT * FROM table LIMIT 5,10; // 檢索記錄行 6-15  

#為了檢索從某一個偏移量到記錄集的結束所有的記錄行,可以指定第二個參數為 -1:   
SELECT * FROM table LIMIT 95,-1; // 檢索記錄行 96-last.  

#如果只給定一個參數,它表示返回最大的記錄行數目:   
SELECT * FROM table LIMIT 5; //檢索前 5 個記錄行  

#換句話說,LIMIT n 等價於 LIMIT 0,n。 

步驟:

1、修改Mapper文件

<select id="selectUser" parameterType="map" resultType="user">
  select * from user limit #{startIndex},#{pageSize}
</select>

2、Mapper接口,參數為map

//選擇全部用戶實現分頁
List<User> selectUser(Map<String,Integer> map);

3、在測試類中傳入參數測試

  • 推斷:起始位置 = (當前頁面 - 1 ) * 頁面大小
//分頁查詢 , 兩個參數startIndex , pageSize
@Test
public void testSelectUser() {
   SqlSession session = MybatisUtils.getSession();
   UserMapper mapper = session.getMapper(UserMapper.class);

   int currentPage = 1;  //第幾頁
   int pageSize = 2;  //每頁顯示幾個
   Map<String,Integer> map = new HashMap<String,Integer>();
   map.put("startIndex",(currentPage-1)*pageSize);
   map.put("pageSize",pageSize);

   List<User> users = mapper.selectUser(map);

   for (User user: users){
       System.out.println(user);
  }

   session.close();
}

RowBounds分頁

我們除了使用Limit在SQL層面實現分頁,也可以使用RowBounds在Java代碼層面實現分頁,當然此種方式並不常用。

步驟:

1、mapper接口

//選擇全部用戶RowBounds實現分頁
List<User> getUserByRowBounds();

2、mapper文件

<select id="getUserByRowBounds" resultType="user">
select * from user
</select>

3、測試類

在這里,我們需要使用RowBounds類

@Test
public void testUserByRowBounds() {
   SqlSession session = MybatisUtils.getSession();

   int currentPage = 2;  //第幾頁
   int pageSize = 2;  //每頁顯示幾個
   RowBounds rowBounds = new RowBounds((currentPage-1)*pageSize,pageSize);

   //通過session.**方法進行傳遞rowBounds,[此種方式現在已經不推薦使用了]
   List<User> users =session.selectList("com.kuang.mapper.UserMapper.getUserByRowBounds", null,rowBounds);

   for (User user: users){
       System.out.println(user);
  }
   session.close();
}

PageHelper

官方文檔:https://pagehelper.github.io/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM