MyBatis学习总结(三)Java日志(Log4j)的实现/使用Limit实现分页/使用RowBounds实现分页/Limit和RowBounds的区别/使用注解开发MyBatis

一、Java日志(Log4j)的实现

(一)Log4j简介

  • Log4j–Log for java(java的日志)
  • Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。

(二)Log4j使用步骤

1.从Maven仓库中导入Log4j的依赖

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

2.在resources目录下存放log4j.properties资源文件

可以手动增删自己需要的日志格式

log4j.properties:

### Log4j配置 ###
#定义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/info.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

3.在mybatis-config.xml(mybatis核心配置文件)中配置:

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

4.测试

在这里插入图片描述

二、分页的实现

(一)MySQL中的分页

语法 : SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset
好处 : (用户体验好、网络传输快、查询压力小)

推导:
第一页 : LIMIT 0,5(显示前五条信息,起始位置为0,等同于LIMIT 5)
第二页 : LIMIT 5,5(显示第二页的五条信息,起始位置为5)
第三页 : LIMIT 10,5(显示第三页的五条信息,起始位置为10)

第N页 : LIMIT (pageNo-1)*pageSzie,pageSzie
其中pageNo:页码,pageSize:单页面显示条数

如何计算出当前起始位置:startIndex = (pageNo-1)* pageSize

例子
从Student表中查询前五个学生的姓名和学号

SELECT studentname,studentno FROM Student LIMIT 0,5

数据库中可以实现将查询的结果分页显示,那么在MyBatis中如何实现呢?

(二)MyBatis中的分页

1.方法一:使用Limit实现分页

(1)编写dao接口

import com.fox.pojo.User;
import java.util.List;
import java.util.Map;

public interface UserDao {
    //查询全部用户实现分页
    List<User> selectUserByLimit(Map<String,Integer> map);
}

(2)编写对应的mapper映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--mapper标签的namespace对应Mapper接口的类,包名+类名-->
<mapper namespace="com.fox.dao.UserDao">
  
    <select id="selectUserByLimit" parameterType="Map" resultType="User">
        select * from mybatis.user limit #{startIndex},#{pageSize}
    </select>

</mapper>

(3)编写测试类

import com.fox.pojo.User;
import com.fox.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UserMapperTest {  
    @Test
    public void selectUserByLimit(){
        //创建sqlSession
        SqlSession sqlSession = MyBatisUtils.getSqlSession();//带自动提交事务

        //准备数据(显示第几页的多少条结果)
        int pageNo = 1;//当前是第几页
        int pageSize = 2; //页面大小

        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("startIndex",(pageNo-1)*pageSize);
        map.put("pageSize",pageSize);

        //测试
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> users = mapper.selectUserByLimit(map);
        for (User user : users) {
            System.out.println(user);
        }

        sqlSession.close();//关闭连接
    }
}

(4)运行测试类

在这里插入图片描述

2.方法一:使用RowBounds实现分页

(1)编写dao接口

import com.fox.pojo.User;
import java.util.List;

public interface UserDao {
    //查询全部用户实现分页使用RowBounds
    List<User> selectUserByRowBounds();
}

(2)编写对应的mapper映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--mapper标签的namespace对应Mapper接口的类,包名+类名-->
<mapper namespace="com.fox.dao.UserDao">
  
    <select id="selectUserByRowBounds" resultType="User">
        select * from mybatis.user
    </select>

</mapper>

(3)编写测试类

import com.fox.pojo.User;
import com.fox.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import java.util.List;

public class UserMapperTest {  
    @Test
    public void selectUserByRowBounds(){
        //创建sqlSession
        SqlSession sqlSession = MyBatisUtils.getSqlSession();//带自动提交事务

        //准备数据(显示第几页的多少条结果)
        int pageNo = 2;//当前是第几页
        int pageSize = 2; //页面大小

        RowBounds rowBounds = new RowBounds((pageNo-1)*pageSize,pageSize);
        //注意点:使用RowBounds就不能使用getMapper了,而是selectList\selectMap\selectOne等
        //selectList: 接收一个List
        //selectMap: 接收一个Map
        //selectOne : 接收只有一个对象的时候

        //这里是selectList,传入的参数依次是对应的Mapper接口中的抽象方法的全域名、一个指定的Objec对象(一般为null)以及RowBounds对象
        List<User> users = sqlSession.selectList("com.fox.dao.UserDao.selectUserByRowBounds", null, rowBounds);

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

(4)运行测试类

在这里插入图片描述

3.两种方法(Limit和RowBounds)的区别

  • Limit 是在SQL层面实现分页,需要先通过反射拿到Mapper接口,再通过SqlSession获得Mapper接口的实现类,通过实现类传入参数(起始位置,页面大小),实现分页显示。
  • RowBounds 在代码层面实现分页,无需获取Mapper接口的实现类,需要先通过有参构造(传入分页参数)创建RowBounds对象,再通过SqlSession对象调用selectListselectMap或者selectOne方法实现分页。传入的参数依次是对应的Mapper接口中的抽象方法的全域名,一个指定的Objec对象(一般为null),以及RowBounds对象。RowBounds 本质其实就是封装了Limit。

三、使用注解开发MyBatis

早期MyBatis都是使用xml进行配置的,直到注解的出现,注解可以替代一些xml中的配置。

CRUD的注解:

  • @insert()
  • @delete()
  • @update()
  • @select()

(一)使用注解开发MyBatis步骤(增删改查)

1.编写dao接口

import com.fox.pojo.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface UserDao {
    //查询全部用户
    @Select("select * from user")
    List<User> selectAllUsers();

    //通过ID查询用户
    //注意:传入单个参数可以省略@Param ,传入多个参数必须使用@Param并用逗号隔开
    @Select("select * from user where id = #{id}")
    User selectUserById(@Param("id") int id);

    //添加用户
    @Insert("insert into user(id,name,pwd) values (#{id},#{name},#{pwd})")
    int addUser(User user);

    //修改用户
    @Update("update user set name = #{name}, pwd = #{pwd} where id = #{id}")
    int updateUser(User user);

    //删除用户
    @Delete("delete from user where id =#{uid}")
    int deleteUser(@Param("uid") int id);
}

2.配置mybatis-config.xml(MyBatis核心配置文件)

由于注解开发替代了Mapper映射文件,所以本例无Mapper映射文件,因此映射器的写法也有变动:

<mappers>
        <!--class对应的是一个接口类-->
        <!--resource对应的是一个接口类的映射文件-->
		
		<!--使用映射器接口实现类的完全限定类名-->
        <mapper class="com.fox.dao.UserDao"/>
</mappers>

3.编写测试类

import com.fox.pojo.User;
import com.fox.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class UserDaoTest {
    @Test
    public void selectAllUsers(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();//带自动提交事务
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> users = mapper.selectAllUsers();
        for (User user : users) {
            System.out.println(user);
        }
        sqlSession.close();//关闭sqlSession
    }
    @Test
    public void selectUserById(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        User user = mapper.selectUserById(2);
        System.out.println(user);
        sqlSession.close();
    }
    @Test
    public void addUser(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        User user = new User(5, "小黑", "888888");
        int i = mapper.addUser(user);
        if(i>0)
        System.out.println("插入成功!");
        sqlSession.close();
    }
    @Test
    public void updateUser(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        User user = new User(5,"小赵","999999");
        int i = mapper.updateUser(user);
        if(i>0)
        System.out.println("修改成功!");
        sqlSession.close();
    }
    @Test
    public void deleteUser(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        int i = mapper.deleteUser(5);
        if(i>0)
        System.out.println("删除成功!");
        sqlSession.close();
    }
}

4.运行测试类

(1)单元测试selectAllUsers()结果

在这里插入图片描述

(2)单元测试selectUserById()结果

在这里插入图片描述

(3)单元测试addUser()结果

在这里插入图片描述

(4)单元测试updateUser()结果

在这里插入图片描述

(5)单元测试deleteUser()结果

在这里插入图片描述

(二)使用注解开发MyBatis注意事项

  1. @Param参数尽量都写上,如果有多个参数,就必须填写。
  2. 使用注解开发MyBatis的情况一般没有映射文件,因此配置文件中映射器要使用映射器接口实现类的完全限定类名来实现映射。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章