Mybatis学习(三)—Java日志(log4j)的实现/分页的实现/Mybatis的优化使用(事务/别名/注解)
01 Java日志的实现
Mybatis 的内置日志工厂提供日志功能,内置日志工厂将日志交给以下其中一种工具作代理:
- SLF4J
- Apache Commons Logging
- Log4j 2
- Log4j
- JDK logging
准备步骤:
- Maven仓库下载log4j的依赖
<!--log4j依赖-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
- 在resources目录下存放log4j.properties文件
### Log4j配置 ###
### 与Spring结合需要在web.xml中指定此文件位置,并添加监听器 ###
#定义log4j的输出级别和输出目的地(目的地可以自定义名称,和后面的对应)
#[ level ] , appenderName1 , appenderName2
log4j.rootLogger=DEBUG,console,file
#-----------------------------------#
#1 定义日志输出目的地为控制台
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
####可以灵活地指定日志输出格式,下面一行是指定具体的格式 ###
#%c: 输出日志信息所属的类目,通常就是所在类的全名
#%m: 输出代码中指定的消息,产生的日志具体信息
#%n: 输出一个回车换行符,Windows平台为"/r/n",Unix平台为"/n"输出日志信息换行
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
#-----------------------------------#
#2 文件大小到达指定尺寸的时候产生一个新的文件
log4j.appender.file = org.apache.log4j.RollingFileAppender
#日志文件输出目录
log4j.appender.file.File=log/tibet.log
#定义文件最大大小
log4j.appender.file.MaxFileSize=10mb
###输出日志信息###
#最低级别
log4j.appender.file.Threshold=ERROR
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#-----------------------------------#
#3 druid
log4j.logger.druid.sql=INFO
log4j.logger.druid.sql.DataSource=info
log4j.logger.druid.sql.Connection=info
log4j.logger.druid.sql.Statement=info
log4j.logger.druid.sql.ResultSet=info
#4 mybatis 显示SQL语句部分
log4j.logger.org.mybatis=DEBUG
#log4j.logger.cn.tibet.cas.dao=DEBUG
#log4j.logger.org.mybatis.common.jdbc.SimpleDataSource=DEBUG
#log4j.logger.org.mybatis.common.jdbc.ScriptRunner=DEBUG
#log4j.logger.org.mybatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
#log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
- mybatis-config.xml配置
<!--设置日志实现 注意属性的设置严格遵守大小写 mybatis的 Commons Logging 为:STDOUT_LOGGING-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--设置日志实现 注意属性的设置严格遵守大小写 logj实现方式:LOG4J-->
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
- 测试代码
@Test
public void selectUser(){
SqlSessionFactory sqlSessionFactory = MybatisUtil.getSqlSessionFactory();
SqlSession session = sqlSessionFactory.openSession();
List<User> users = mapper.selectUser();
for (User user : users) {
System.out.println(user);
}
}
测试结果:
Commons Logging实现日志
[org.apache.ibatis.logging.LogFactory]-Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
Class not found: org.jboss.vfs.VFS
JBoss 6 VFS API is not available in this environment.
Class not found: org.jboss.vfs.VirtualFile
VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment.
Using VFS adapter org.apache.ibatis.io.DefaultVFS
Find JAR URL: file:/G:/IDEA%20Project/Mybatis/target/classes/com/hooi/pojo
Not a JAR: file:/G:/IDEA%20Project/Mybatis/target/classes/com/hooi/pojo
Reader entry: User.class
Listing file:/G:/IDEA%20Project/Mybatis/target/classes/com/hooi/pojo
Find JAR URL: file:/G:/IDEA%20Project/Mybatis/target/classes/com/hooi/pojo/User.class
Not a JAR: file:/G:/IDEA%20Project/Mybatis/target/classes/com/hooi/pojo/User.class
Reader entry: ���� 3 <
Checking to see if class com.hooi.pojo.User matches criteria [is assignable to Object]
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 183284570.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@aecb35a]
==> Preparing: select * from user
==> Parameters:
<== Columns: id, name, pwd
<== Row: 1, HooiShieh, 123456
<== Row: 2, 张三, abcdef
<== Row: 3, 李四, 987654
<== Total: 3
User{id=1, name='HooiShieh', password='123456'}
User{id=2, name='张三', password='abcdef'}
User{id=3, name='李四', password='987654'}
log4j实现日志
[org.apache.ibatis.logging.LogFactory]-Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
[org.apache.ibatis.logging.LogFactory]-Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
[org.apache.ibatis.io.VFS]-Class not found: org.jboss.vfs.VFS
[org.apache.ibatis.io.JBoss6VFS]-JBoss 6 VFS API is not available in this environment.
[org.apache.ibatis.io.VFS]-Class not found: org.jboss.vfs.VirtualFile
[org.apache.ibatis.io.VFS]-VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment.
[org.apache.ibatis.io.VFS]-Using VFS adapter org.apache.ibatis.io.DefaultVFS
[org.apache.ibatis.io.DefaultVFS]-Find JAR URL: file:/G:/IDEA%20Project/Mybatis/target/classes/com/hooi/pojo
[org.apache.ibatis.io.DefaultVFS]-Not a JAR: file:/G:/IDEA%20Project/Mybatis/target/classes/com/hooi/pojo
[org.apache.ibatis.io.DefaultVFS]-Reader entry: User.class
[org.apache.ibatis.io.DefaultVFS]-Listing file:/G:/IDEA%20Project/Mybatis/target/classes/com/hooi/pojo
[org.apache.ibatis.io.DefaultVFS]-Find JAR URL: file:/G:/IDEA%20Project/Mybatis/target/classes/com/hooi/pojo/User.class
[org.apache.ibatis.io.DefaultVFS]-Not a JAR: file:/G:/IDEA%20Project/Mybatis/target/classes/com/hooi/pojo/User.class
[org.apache.ibatis.io.DefaultVFS]-Reader entry: ���� 3 <
[org.apache.ibatis.io.ResolverUtil]-Checking to see if class com.hooi.pojo.User matches criteria [is assignable to Object]
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Opening JDBC Connection
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Created connection 183284570.
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@aecb35a]
[com.hooi.dao.UserMapper.selectUser]-==> Preparing: select * from user
[com.hooi.dao.UserMapper.selectUser]-==> Parameters:
[com.hooi.dao.UserMapper.selectUser]-<== Total: 3
User{id=1, name='HooiShieh', password='123456'}
User{id=2, name='张三', password='abcdef'}
User{id=3, name='李四', password='987654'}
02 Mybatis实现分页显示查询结果
通过limit实现分页显示查询结果
- mapper接口
//通过limit实现分页显示查询结果
public abstract List<User> selectUserByLimit(Map<String,Integer> map);
- mapper映射文件
<select id="selectUserByLimit" parameterType="Map" resultMap="UserMap" >
select * from user limit #{startIndex},#{pageSize}
</select>
- Junit测试代码
@Test
public void selectUserByLimit(){
SqlSessionFactory sqlSessionFactory = MybatisUtil.getSqlSessionFactory();
SqlSession session = sqlSessionFactory.openSession();
//模拟获取用户传入的数据,一般情况下,用户只会传入当前页面currentPage和页面大小pageSize
//当前位置可以根据startIndex =(currentPage -1)*pageSize计算
int currentPage = 2;
int pageSize = 2;
//将用户传入的数据重新封装
Map<String, Integer> map = new HashMap<>();
map.put("startIndex",(currentPage-1)*pageSize);
map.put("pageSize",pageSize);
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> users = mapper.selectUserByLimit(map);
for (User user : users) {
System.out.println(user);
}
}
- 测试结果
通过RowBounds实现分页显示查询结果
- mapper接口
//通过mybatis提供的rowBounds实现分页显示查询结果
public abstract List<User> selectUserByRowBounds(Map<String,Integer> map);
- mapper映射文件
<select id="selectUserByRowBounds" resultMap="UserMap" >
select * from user
</select>
- Junit测试代码
@Test
public void selectUserByRowBounds(){
SqlSessionFactory sqlSessionFactory = MybatisUtil.getSqlSessionFactory();
SqlSession session = sqlSessionFactory.openSession();
//模拟传入的数据
int currentPage = 1;
int pageSize = 3;
//计算起始位置
int startIndex = (currentPage-1)*pageSize;
//创建一个RowBounds对象
RowBounds rowBounds = new RowBounds(startIndex, pageSize);
//注意点;使用RowBounds实现分页,就不能使用getMapper了
//selectList: 接收一个List 需要传入的参数
//selectMap: 接收一个Map
//selectOne : 接收只有一个对象的时候
List<User> users = session.selectList("com.hooi.dao.UserMapper.selectUserByRowBounds", null, rowBounds);
for (User user : users) {
System.out.println(user);
}
}
- 测试结果
limit 和 rowBounds区别
- limit 是在SQL层面实现分页,需要先通过反射拿到Mapper接口,再通过SqlSession获得Mapper接口的实现类,通过实现类传入参数(起始位置,页面大小),实现分页显示。
- rowBounds 在代码层面实现分页,无需获取Mapper接口的实现类,需要先通过有参构造(传入分页参数)创建RowBounds对象,再通过SqlSession对象调用
selectList
,selectMap
或者selectOne
方法实现分页。传入的参数依次是对应的mapper接口中的抽象方法的全域名,一个指定的Objec对象(一般为null),以及RowBounds对象,如selectList(“com.hooi.dao.UserMapper.selectUserByRowBounds”,null,rowBounds)。RowBounds 本质其实就是封装了limit。
03 Mybatis的优化使用
事务的优化使用
public static SqlSession getSqlSession(){
//开启事务自动提交,openSession构造器如果参数为true,则事务会自动提交。
return sqlSessionFactory.openSession(true);
}
别名的优化使用
自动设置别名
<typeAliases>
<!--为pojo整个包下的类自动取别名-->
<package name="com.hooi.pojo"/>
</typeAliases>
使用注解开发的思想
早期的Mybatis
都是使用xml进行配置,后来,注解的出现开始替代一些xml的配置。
CRUD的注解:@insert() @delete() @update() @select()
使用注解开发实质上就是面向接口的开发
AnnotationDao.interface
package com.hooi.dao;
import com.hooi.pojo.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface AnnotationDao {
//查询全部用户
@Select("select * from user")
public abstract List<User> getAllUsers();
//通过id和name查询用户
//注意:传入单个参数可以省略@Param 传入多个参数必须使用@Param并用逗号隔开
@Select("select * from user where id = #{id}")
public abstract User getUserById(@Param("id") int id );
//通过id删除用户
@Delete("delete from user where id = #{id}")
public abstract int delUserById(@Param("id") int id);
//更新用户
@Update("update user set name = #{name}, pwd = #{password} where id = #{id}")
public abstract int updateUser(User user);
//添加用户
@Insert("insert into user (id,name,pwd) values (#{id},#{name},#{password})")
public abstract int addUser(User user);
}
使用注解进行开发无需配置mapper映射文件,但是需要配置mybatis的配置文件
<mappers>
<mapper class="com.hooi.dao.AnnotationDao"/>
</mappers>
Junit测试代码:
package com.hooi.dao;
import com.hooi.pojo.User;
import com.hooi.utils.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class AnnotationDaoTest {
@Test
public void getAllUsers(){
SqlSession session = MybatisUtil.getSqlSession();
AnnotationDao mapper = session.getMapper(AnnotationDao.class);
List<User> users = mapper.getAllUsers();
for (User user : users) {
System.out.println(user);
}
}
@Test
public void getUserById(){
SqlSession session = MybatisUtil.getSqlSession();
AnnotationDao mapper = session.getMapper(AnnotationDao.class);
User user = mapper.getUserById(3);
System.out.println(user);
}
@Test
public void delUserById(){
SqlSession session = MybatisUtil.getSqlSession();
AnnotationDao mapper = session.getMapper(AnnotationDao.class);
int updateRows = mapper.delUserById(6);
if (updateRows>0){
System.out.println("delete successfully");
}
}
@Test
public void updateUser(){
SqlSession session = MybatisUtil.getSqlSession();
AnnotationDao mapper = session.getMapper(AnnotationDao.class);
int updateRows = mapper.updateUser(new User(5,"lily","000000"));
if (updateRows>0){
System.out.println("update successfully");
}
}
@Test
public void addUser(){
SqlSession session = MybatisUtil.getSqlSession();
AnnotationDao mapper = session.getMapper(AnnotationDao.class);
int updateRows = mapper.addUser(new User(6,"Jackson","000000"));
if (updateRows>0){
System.out.println("add successfully");
}
}
}
测试结果:
getAllUsers()
测试结果
getUserById()
测试结果
delUserById()
测试结果
updateUser()
测试结果
addUser()
测试结果