1. ResultMap
查詢結果為null:要解決屬性和欄位名不一致的問題
我們先來看下步驟:
-
資料庫中的欄位名
-
Java中的實體類
public class User { private int id; //id private String name; //姓名 private String password; //密碼和資料庫不一樣! //構造 //set/get //toString() }
-
mapper介面方法
//根據id查詢使用者 User selectUserById(int id);
-
mapper配置檔案
<select id="selectUserById" resultType="user"> select * from user where id = #{id} </select>
-
這樣子我們得到的結果是password為空,MyBatis會根據這些查詢的列名(會將列名自動轉化為小寫,資料庫不區分大小寫),去對應的實體類中查詢相應列名的set方法設值,由於找不到setPwd,所以password返回null(自動對映)
-
解決方法:
-
為列名指定別名,別名和Java實體類的屬性名一致
<select id="selectUserById" resultType="User"> select id , name , pwd as password from user where id = #{id} </select>
-
使用結果集對映(推薦)
<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
元素是 MyBatis 中最重要最強大的元素。它可以讓你從 90% 的 JDBCResultSets
資料提取程式碼中解放出來 -
實際上,在為一些比如連線的複雜語句編寫對映程式碼的時候,一份
resultMap
能夠代替實現同等功能的長達數千行的程式碼 -
ResultMap 的設計思想是,對於簡單的語句根本不需要配置顯式的結果對映,而對於複雜一點的語句只需要描述它們的關係就行了
<select id="selectUserById" resultType="map"> select id , name , pwd from user where id = #{id} </select>
手動對映:
-
返回值型別為resultMap
<select id="selectUserById" resultMap="UserMap"> select id , name , pwd 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>
-
但是在資料庫中,存在一對多、多對一的情況,我們之後會使用到一些高階的結果集對映,association,collection等
2. 日誌工廠
2.1 概念
Mybatis內建的日誌工廠提供日誌功能,具體的日誌實現有以下幾種工具:
- SLF4J
- Apache Commons Logging
- Log4j2
- Log4j
- JDK logging
- 具體選擇哪個日誌實現工具由MyBatis的內建日誌工廠確定。它會使用最先找到的(按上文列舉的順序查詢)。如果一個都未找到,日誌功能就會被禁用
標準的日誌實現:
-
指定 MyBatis 應該使用哪個日誌記錄實現。如果此設定不存在,則會自動發現日誌記錄實現
<settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
2.2 Log4j
關於Log4j的簡介:
- Log4j是Apache的一個開源專案
- 通過使用Log4j,我們可以控制日誌資訊輸送的目的地:控制檯,文字,GUI元件等
- 我們也可以控制每一條日誌的輸出格式
- 通過定義每一條日誌資訊的級別,我們能夠更加細緻地控制日誌的生成過程。最令人感興趣的就是,這些可以通過一個配置檔案來靈活地進行配置,而不需要修改應用的程式碼
使用步驟:
-
導包
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
-
配置檔案的編寫
#將等級為DEBUG的日誌資訊輸出到console和file這兩個目的地,console和file的定義在下面的程式碼 log4j.rootLogger=DEBUG,console,file #控制檯輸出的相關設定 log4j.appender.console = org.apache.log4j.ConsoleAppender log4j.appender.console.Target = System.out log4j.appender.console.Threshold=DEBUG log4j.appender.console.layout = org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=[%c]-%m%n #檔案輸出的相關設定 log4j.appender.file = org.apache.log4j.RollingFileAppender log4j.appender.file.File=./log/kuang.log log4j.appender.file.MaxFileSize=10mb log4j.appender.file.Threshold=DEBUG log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n #日誌輸出級別 log4j.logger.org.mybatis=DEBUG log4j.logger.java.sql=DEBUG log4j.logger.java.sql.Statement=DEBUG log4j.logger.java.sql.ResultSet=DEBUG log4j.logger.java.sql.PreparedStatement=DEBUG
-
setting設定日誌的實現
<settings> <setting name="logImpl" value="LOG4J"/> </settings>
-
在程式中使用Log4j進行輸出
//注意導包:org.apache.log4j.Logger static Logger logger = Logger.getLogger(MyTest.class); @Test public void selectUser() { logger.info("info:進入selectUser方法"); logger.debug("debug:進入selectUser方法"); logger.error("error: 進入selectUser方法"); SqlSession session = MybatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); List<User> users = mapper.selectUser(); for (User user: users){ System.out.println(user); } session.close(); }
-
進行測試
3. 分頁
3.1 limit實現分頁
為什麼要使用分頁?
- 在學習mybatis等持久層框架的時候,會經常對資料進行增刪改查操作,使用最多的是對資料庫進行查詢操作,如果查詢大量資料的時候,我們往往使用分頁進行查詢,也就是每次處理小部分資料,這樣對資料庫壓力就在可控範圍內
使用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。
步驟:
-
修改Mapper配置檔案
<select id="selectUser" parameterType="map" resultType="user"> select * from user limit #{startIndex}, #{pageSize} </select>
-
修改Mapper介面,引數為map
//選擇全部使用者實現分頁 List<User> selectUser(Map<String,Integer> map);
-
進行測試(推斷:起始位置 = (當前頁面 - 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(); }
3.2 RowBounds分頁
我們除了使用Limit在SQL層面實現分頁,也可以使用RowBounds在Java程式碼層面實現分頁,當然此種方式作為了解即可,使用步驟如下:
-
新增Mapper介面方法
//選擇全部使用者RowBounds實現分頁 List<User> getUserByRowBounds();
-
邊界Mapper配置檔案
<select id="getUserByRowBounds" resultType="user"> select * from user </select>
-
進行測試(需要用到RowBonds類)
@Test public void testUserByRowBounds() { SqlSession session = MybatisUtils.getSession(); // 頁數 int currentPage = 2; // 每頁記錄數 int pageSize = 2; RowBounds rowBounds = new RowBounds((currentPage - 1) * pageSize, pageSize); //通過session.xxx方法進行傳遞rowBounds,(此種方式現在已經不推薦使用了) List<User> users = session.selectList("top.linzelaing.mapper.UserMapper.getUserByRowBounds", null, rowBounds); for (User user: users){ System.out.println(user); } session.close(); }
- 這種方法其實也就是先把資料全部查詢出來,然後再篩選,這樣子會導致伺服器的壓力增大,不推薦使用
3.3 PageHelper實現分頁
- 瞭解即可
- 點選檢視官網