日志
為什么需要日志
如果一個數據庫操作出現了異常,需要排錯,那么日志就是最好的助手
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組件
也可以控制每一條日志的輸出格式,自定義日志輸出
通過定義每一條日志信息的級別,能夠更加細致地控制日志的生成過程
通過一個配置文件來靈活地進行配置,不需要修改應用的代碼
使用方式:
- 導入Log4J包
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
- 在mybatis-config.xml中配置log4j日志的實現
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
- 添加接口代碼
package org.luoqing.dao;
public interface TeacherMapper {
@Select("SELECT * FROM teacher WHERE id = #{id}")
Blog selectTeacher(int id);
}
- 在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
- 測試
測試代碼此處省略
自定義輸出語句
- 在要使用log4j的類中導入包
import org.apache.log4j.Logger;
- 日志對象,參數為當前類的class
static Logger logger = Logger.getLogger(UserMapperTest.class);
- 日志級別
@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實現
- 接口
public interface UserMapper {
// 分頁實現
List<User> getUserByLimit(Map<String, Integer> map);
}
- Mapper.xml
<select id="getUserByLimit" parameterType="map" resultMap="UserMap">
select * from learn.user limit #{startIndex}, #{pageSize}
</select>
- 測試
@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實現分頁
- 接口
public interface UserMapper {
// RowBounds分頁
List<User> getUserByRowBounds();
}
- Mapper.xml
<select id="getUserByRowBounds" resultMap="UserMap">
select * from learn.user
</select>
- 測試
@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
- 添加依賴
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
- 在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>
- 測試
數據庫准備
需要創建對應的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();
}