IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【MyBatis学习笔记 三】结果集映射、日志处理及分页查询 -> 正文阅读

[Java知识库]【MyBatis学习笔记 三】结果集映射、日志处理及分页查询

上一篇Blog了解了基本的MyBatis操作后,我们本篇来学习一下如何实现一些较为高级的操作。分别是返回值的模型映射、日志处理以及分页查询的实现。

模型映射

如果是一个初始化的项目,我们当然尽量的让我们的数据对象,也就是Data Model和数据表中的字段名称保持一致,但是要维护一些老的项目或者说确实有一些我们认为名称应该有所区别的,就需要做一个映射了,类似Hibernate里的Person.hbm.xml文件,我们的Mapper文件也需要做返回结果的映射。

命名不一致的问题

首先我们在上篇【MyBatis学习笔记 二】MyBatis基本操作及配置解析 Blog的基础上继续做处理,我们在库内增加一个字段:hobby,兴趣爱好,并给两个字段设置值:
在这里插入图片描述

同时给我们的类Person增加属性,但是命名为interests

package com.example.MyBatis.dao.model;

import lombok.Data;

/*
 * person表对应对象
 * */
@Data
public class Person {
    private int id;
    private String username;
    private String password;
    private int age;
    private int phone;
    private String email;
    private String interests;
}

接下来在我们的处理方法中进行查询:

  <select id="getPersonList" resultType="com.example.MyBatis.dao.model.Person">
        select * from person
    </select>

通过测试类进行测试:

    @Test
    public void test(){

        //1.获取SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //2.执行SQL
        PersonDao personDao = sqlSession.getMapper(PersonDao.class);
        List<Person> personList = personDao.getPersonList();
        for (Person person : personList) {
            System.out.println(person);
        }
        //关闭sqlSession
        sqlSession.close();
    }

返回结果如下:
在这里插入图片描述
可以看到由于字段名不对称,无法获取,mybatis会根据这些查询的列名(会将列名转化为小写,数据库不区分大小写) , 去对应的实体类中查找相应列名的set方法设值 , 由于找不到interests的set方法, 所以返回null。我们调整查询语句如下:

    <select id="getPersonList" resultType="com.example.MyBatis.dao.model.Person">
        select username,password,age,phone,email,hobby as interests  from person
    </select>

通过hobby as interests 设置别名,确定返回属性为interests,然后再去找对应的set方法就可以了:
在这里插入图片描述

使用ResultMap解决

通过设置别名的方式确实可以解决,但是每个方法都需要设置,如果不一致的字段多还需要写大量冗余的sql代码,所以使用ResultMap手动映射来解决这个问题更好。它相当于数据表字段和模型直接的一个映射关系配置:

 <!-- id确定返回map, type为模型全类名 -->
    <resultMap id="PersonMap" type="com.example.MyBatis.dao.model.Person">
        <!-- id为主键 -->
        <id column="id" property="id"/>
        <!-- column写错会因为查到数据匹配不上,给默认值, type写错会报错,找不到属性-->
        <result column="age" property="age"/>
        <!-- column是数据库表的列名 , property是对应实体类的属性名 -->
        <result column="hobby" property="interests"/>
    </resultMap>
    <select id="getPersonList" resultMap="PersonMap">
        select * from person
    </select>

以上我们可以发现,其实不写所有的属性也可以,也就是优先走配置,如果配置没有,还是会走自动映射去找属性的,所以对于命名一致的数据字段和类的属性就无需再加了
在这里插入图片描述
但是为了规范和不易出错,我们最好把对应关系都写全了,这样也能对全表字段有正确认知:

 <!-- id确定返回map, type为模型全类名 -->
    <resultMap id="PersonMap" type="com.example.MyBatis.dao.model.Person">
        <!-- id为主键 -->
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="password" property="password"/>
        <result column="age" property="age"/>
        <result column="phone" property="phone"/>
        <!-- column写错会因为查到数据匹配不上,给默认值, type写错会报错,找不到属性-->
        <result column="email" property="email"/>
        <!-- column是数据库表的列名 , property是对应实体类的属性名 -->
        <result column="hobby" property="interests"/>
    </resultMap>
     <!--注意返回类型是resultMap而不是resultType -->
    <select id="getPersonList" resultMap="PersonMap">
        select * from person
    </select>

日志处理

如果一个数据库相关的操作出现了问题,我们可以根据输出的SQL语句快速排查问题。对于以往的开发过程,我们会经常使用到debug模式来调节,跟踪我们的代码执行过程。但是现在使用Mybatis是基于接口,配置文件的源代码通过反射执行,我们无法debug。因此,我们必须选择日志工具来作为我们开发,调节程序的工具。

日志工具分类

Mybatis内置的日志工厂提供日志功能,具体的日志实现有以下几种工具:

 1. SLF4J
 2. Apache Commons Logging
 3. Log4j-2
 4. Log4j
 5. JDK logging

具体选择哪个日志实现工具由MyBatis的内置日志工厂确定。它会按优先级使用最先找到的,如果一个都未找到,日志功能就会被禁用。我们可以通过核心配置文件mybatis-config.xml进行日志配置【注意settings节点顺序】:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration核心配置文件-->
<configuration>
    <!--导入properties文件-->
    <properties resource="properties/db.properties"/>
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mappers/personMapper.xml"/>
    </mappers>

</configuration>

然后我们再执行单元测试就可以看到打印出日志记录了:
在这里插入图片描述

使用Log4j进行日志处理

什么是Log4j?Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件;可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程;可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

1 导入Log4j的Maven依赖

在pom.xml中导入日志依赖,在maven中搜索到然后选择最新版本号:
在这里插入图片描述
导入方式如下:

       <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

2 配置log4j.properties文件

在resources下配置文件:log4j.properties,只要是该目录下即可:

#将等级为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/tml.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.sq1.PreparedStatement=DEBUG

DEBUG指的是日志输出级别,一共有 7 个级别(OFF、 FATAL、 ERROR、 WARN、 INFO、 DEBUG、 ALL),一般常用的日志输出级别分别为 DEBUG、 INFO、 ERROR 以及 WARN,分别表示 “调试级别”、 “标准信息级别”、 “错误级别”、 “异常级别”

  • 如果需要查看程序运行的详细步骤信息,一般选择 “DEBUG” 级别,因为该级别在程序运行期间,会在控制台才打印出底层的运行信息,以及在程序中使用 Log 对象打印出调试信息。
  • 如果是日常的运行,选择 INFO 级别,该级别会在控制台打印出程序运行的主要步骤信息
  • ERRORWARN级别分别代表 不影响程序运行的错误事件潜在的错误情形

3 测试类查看日志输出

引入org.apache.log4j.Logger日志包,进行测试:

//注意导包:org.apache.log4j.Logger
    static Logger logger = Logger.getLogger(PersonTest.class);
    @Test
    public void test(){
        logger.info("info:进入test方法");
        logger.debug("debug:进入test方法");
        logger.error("error: 进入test方法");
        //1.获取SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //2.执行SQL
        PersonDao personDao = sqlSession.getMapper(PersonDao.class);
        List<Person> personList = personDao.getPersonList();
        for (Person person : personList) {
            System.out.println(person);
        }
        //关闭sqlSession
        sqlSession.close();
    }

实现效果如下:
在这里插入图片描述
在本地日志文件中也可以看到:

在这里插入图片描述

分页查询

在学习mybatis等持久层框架的时候,会经常对数据进行增删改查操作,使用最多的是对数据库进行查询操作,如果查询大量数据的时候,我们往往使用分页进行查询,也就是每次处理小部分数据,这样对数据库压力就在可控范围内。分页语法如下:

#为了检索从某一个偏移量开始的指定条数 
SELECT * FROM table LIMIT stratIndex,pageSize
SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15  

#为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:   
SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.  

#如果只给定一个参数,它表示返回最大的记录行数目,换句话说,LIMIT n 等价于 LIMIT 0,n。   
SELECT * FROM table LIMIT 5; //检索前 5 个记录行  

1 调整PersonDao接口定义

首先我们可以在PersonDao接口中增加一个方法getPersonListPage用来分页查找数据:

package com.example.MyBatis.dao.mapper;

import com.example.MyBatis.dao.model.Person;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

public interface PersonDao {
    List<Person> getPersonList();
    Person getPersonByUsername(@Param("username")String username, @Param("password")String password);
    Person getPersonByMap(Map<String,Object> map);
    int addPerson(Person person);
    int updatePerson(Person person);
    int deletePerson(@Param("id")int id);
    List<Person> getPersonListLike(String username);
    List<Person> getPersonListPage(Map<String,Integer> map);
}

2 编写personMapper.xml

其次依据PersonDao接口中增加的方法我们可以在personMapper中进行sql语句编写来实现:

<?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">

<!--namespace=绑定一个指定的Dao/Mapper接口-->
<mapper namespace="com.example.MyBatis.dao.mapper.PersonDao">
    <!-- id确定返回map, type为模型全类名 -->
    <resultMap id="PersonMap" type="com.example.MyBatis.dao.model.Person">
        <!-- id为主键 -->
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="password" property="password"/>
        <result column="age" property="age"/>
        <result column="phone" property="phone"/>
        <!-- column写错会因为查到数据匹配不上,给默认值, type写错会报错,找不到属性-->
        <result column="email" property="email"/>
        <!-- column是数据库表的列名 , property是对应实体类的属性名 -->
        <result column="hobby" property="interests"/>
    </resultMap>
    <select id="getPersonList" resultMap="PersonMap">
        select * from person
    </select>
    <select id="getPersonByUsername" resultMap="PersonMap" >
        select * from person where   password=#{password} and username = #{username}
    </select>
    <select id="getPersonByMap" resultMap="PersonMap"  parameterType="map">
        select * from person where   password=#{password} and username = #{username}
    </select>
    <insert id="addPerson" parameterType="com.example.MyBatis.dao.model.Person" >
        insert into person (id,username,password,age,phone,email) values (#{id},#{username},#{password},#{age},#{phone},#{email})
    </insert>
    <update id="updatePerson" parameterType="com.example.MyBatis.dao.model.Person" >
        update person set username=#{username},phone=#{phone} where id=#{id}
    </update>
    <delete id="deletePerson" parameterType="int" >
        delete from person where id = #{id}
    </delete>
    <select id="getPersonListLike" resultMap="PersonMap" >
        select * from person where username like "%"#{username}"%"
    </select>
    <select id="getPersonListPage" parameterType="map" resultMap="PersonMap">
        select * from person limit #{startIndex},#{pageSize}
    </select>

</mapper>

3 编写单元测试实现

最后我们编写单元测试查看实现效果:

 @Test
    public void testGetPersonListPage(){

        //1.获取SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //2.执行SQL
        PersonDao personDao = sqlSession.getMapper(PersonDao.class);

        int currentPage = 1;  //第几页
        int pageSize = 1;  //每页显示几个
        Map<String,Integer> map = new HashMap<>();
        map.put("startIndex",(currentPage-1)*pageSize);
        map.put("pageSize",pageSize);

        List<Person> personList = personDao.getPersonListPage(map);
        for (Person person : personList) {
            System.out.println(person);
        }
        //关闭sqlSession
        sqlSession.close();
    }

实现效果如下,获取到了第一页共一条数据:
在这里插入图片描述

总结一下

本篇Blog比较杂,主要了解了三部分内容:结果集的映射模型、日志处理以及分页查询这三种我们日常使用时的Mybatis实现方式,看来映射模型也是需要的,和Hibernate类似,现在看来最大的不同就是,Mybatis既运用了SQL的灵活又实现了对象的封装,而Hibernate则是对数据库语法SQL做了完全的封装,自己实现了HQL语句,那么其实比起自己封装的,使用原生的SQL语法更能降低理解难度。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章           查看所有文章
加:2021-08-12 16:28:00  更:2021-08-12 16:30:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年3日历 -2025/3/4 6:28:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码