Mybatis學習-日誌與分頁

月淺發表於2020-12-15

日誌

為什麼需要日誌
如果一個資料庫操作出現了異常,需要排錯,那麼日誌就是最好的助手

Mybatis通過使用內建的日誌工廠提供日誌功能,有一下幾種實現方式:

  • SLF4J
  • Apache Commons Logging
  • Log4j 2
  • Log4j(官方推薦)
  • JDK Logging

Mybatis會按照上面的順序使用第一個查詢到的實現

有不少的應用伺服器的類路徑下已經包含了Commons Logging,這種情況下,Mybatis會將優先順序高的Commons Logging作為日誌實現,其他的日誌配置將會被忽略。如果想使用其他日誌實現,需要在Mmybatis-config.xml中新增以下配置

<settings>
    <setting name="logImpl" value="LOG4J"/>
</settings>

value的值可以是以下任意一個

在所有的日誌實現中,我們需要掌握LOG4J和STDOUT_LOGGING(標準日誌輸出)

<settings>
    <!--標準的日誌工廠的實現-->
    <setting name="logImpl" value="STDOUT_LOGGING" />
</settings>

Log4J

可以控制日誌資訊輸送的目的地是控制檯、檔案、GUI元件
也可以控制每一條日誌的輸出格式,自定義日誌輸出
通過定義每一條日誌資訊的級別,能夠更加細緻地控制日誌的生成過程
通過一個配置檔案來靈活地進行配置,不需要修改應用的程式碼

使用方式:

  1. 匯入Log4J包
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
  1. 在mybatis-config.xml中配置log4j日誌的實現
<settings>
    <setting name="logImpl" value="LOG4J"/>
</settings>
  1. 新增介面程式碼
package org.luoqing.dao;
public interface TeacherMapper {
  @Select("SELECT * FROM teacher WHERE id = #{id}")
  Blog selectTeacher(int id);
}
  1. 在resource目錄中新增log4j.properties
### 將等級為DEBUG的日誌資訊輸出到console和file兩個目的地 ###
log4j.rootLogger = DEBUG,console,file

### 列印Mapper的日誌(以下配置對於註解和XML配置檔案都可) ###
log4j.logger.org.luoqing.dao.TeacherMapper=TRACE
### 或者也可以列印包中所有的Mapper的日誌
log4j.logger.org.luoqing.dao=TRACE
### 甚至可以列印Mapper中特定語句的日誌
log4j.logger.org.luoqing.dao.TeacherMapper.selectTeacher=TRACE

### 輸出到控制檯 ###
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/log.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
  1. 測試
    測試程式碼此處省略

自定義輸出語句

  1. 在要使用log4j的類中匯入包
import org.apache.log4j.Logger;
  1. 日誌物件,引數為當前類的class
static Logger logger = Logger.getLogger(UserMapperTest.class);
  1. 日誌級別
@Test
public void logTest() {
    logger.info("info:進入了logTest");
    logger.debug("debug:進入了logTest");
    logger.error("error:進入了logTest");
}

分頁

為什麼要分頁
為了減少資料的處理量

使用limit分頁

語法:select * from tableName limit startIndex, pageSize
select * from user limit 0,3		# 從第0條記錄開始,每頁顯示3個

使用Mybatis實現

  1. 介面
public interface UserMapper {
//    分頁實現
    List<User> getUserByLimit(Map<String, Integer> map);
}
  1. Mapper.xml
<select id="getUserByLimit" parameterType="map" resultMap="UserMap">
        select * from learn.user limit #{startIndex}, #{pageSize}
</select>
  1. 測試
@Test
public void limitTest() {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    HashMap<String, Integer> map = new HashMap<String, Integer>();
    map.put("startIndex", 0);
    map.put("pageSize", 2);

    List<User> userByLimit = mapper.getUserByLimit(map);
    for (User user : userByLimit) {
        System.out.println(user);
    }
    sqlSession.close();
}

使用RowBounds分頁

不再使用SQL實現分頁

  1. 介面
public interface UserMapper {
//    RowBounds分頁
    List<User> getUserByRowBounds();
}
  1. Mapper.xml
<select id="getUserByRowBounds" resultMap="UserMap">
    select * from learn.user
</select>
  1. 測試
@Test
public void getUserByRowBoundsTest() {
    SqlSession sqlSession = MybatisUtil.getSqlSession();

    //RowBounds實現
    RowBounds rowBounds = new RowBounds(0, 2);

    List<User> userList = sqlSession.selectList("com.luoqing.dao.UserMapper.getUserByRowBounds", null, rowBounds);

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

    sqlSession.close();
}

分頁外掛-PageHelper

  1. 新增依賴
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.2.0</version>
</dependency>
  1. 在mybatis-config.xml中配置外掛
<plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor">

        <property name="dialect" value="mysql"/>

        <!--
            預設是false
            設定為true,會將RowBounds第一個引數offset當成pageNum使用
            -->
        <property name="offsetAsPageNum" value="true"/>

        <!--
            預設是false
            設定為true時,使用RowBounds分頁會進行count查詢
            -->
        <property name="rowBoundWithCoun" value="true"/>

        <!--
            預設是false
            設定為true,如果pageSize=0或者RowBounds.limit=0就會查詢出所有的結果
            相當於沒有執行分頁查詢,返回結果仍是Page型別
            -->
        <property name="pageSizeZero" value="true"/>

        <!--
            分頁合理化引數,預設是false
            設定為true,pageNum<=0時會查詢第一頁,pageNum>pages(超過總數時)會查詢最後一頁
            -->
        <property name="reasonable" value="true"/>

        <!--
            為了支援startPage(Object params)方法,增加了該引數來配置引數對映,用於從Map或ServletRequest中根據屬性名取值
            -->
        <property name="params" value="pageNum=start;pageSize=limit;"/>

        <!--
            預設是false
            支援通過Mapper介面引數來傳遞分頁引數
            會從查詢方法的引數值中,自動根據上面params配置的欄位中取值,查詢到合適的值時就會自動分頁
            -->
        <property name="supportMethodsArgument" value="true"/>
    </plugin>
</plugins>
  1. 測試

資料庫準備

需要建立對應的POJO、DAO介面、Mapper.xml,此處省略

以下為測試程式碼

@Test
public void test1() {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

    //方式一:
    PageHelper.startPage(1,5);
    List<Student> all = mapper.findAll();
    for (Student student : all) {
        System.out.println(student);
    }

    //方式二:
    Page page = PageHelper.startPage(1,5);
    mapper.findAll();
    for (Object o : page) {
        System.out.println(o);
    }
    
    sqlSession.close();
}

相關文章