mybatis学习笔记总结(代码片段)

IT_Holmes IT_Holmes     2023-03-09     733

关键词:

文章目录

1. Mybatis 生命周期和作用域



上面的SQL Mapper就是sqlSession通过getMapper来获取内容,sqlSession.getMapper(xxx.class)


生命周期 和 作用域,是至关重要的,因为错误的使用会导致非常严重的并发问题

SqlSessionFactoryBuilder:

  • 一旦创建SqlSessionFactory,就不需要SqlSessionFactoryBuilder了。
  • 因此,SqlSessionFactoryBuilder的作用域最佳是方法作用域也就是局部变量

SqlSessionFactory:

  • sqlSessionfactory一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。该对象表现的效果就和数据库连接池一样!
  • 因此,SqlSessionFactory的作用域最佳是应用作用域。
  • 最简单的就是就用单例模式或者静态单例模式。

SqlSession:

  • sqlSession是连接到连接池的一个请求。每个线程都应该有它自己的SqlSession实例。
  • SqlSession的实例不是线程安全的,因此是不能被共享的,所以它的最佳作用域是请求或方法作用域
  • 每个SqlSession的实例用完之后,需要赶紧调用close()方法进行关闭,否则资源被占用!


上面的每一个Mapper,就代表一个具体的业务!

2. 解决实体类的属性名 和 数据库的字段名不一致的问题


如何解决实体类的属性名 和 数据库的字段名不一致的问题?

数据库中的表结构:


解决上面的问题,就要理解类型处理器(typeHandlers)的作用效果。

MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型

大体上的流程就是:

-- 我们去数据库中要运行的语句。
select * from mybatis.`user` where id = #id;
-- 经过类型处理器,从而拿到一些列对应的字段和字段值等。
select id,name,pwd from mybatis.`user` where id = #id;

-- 而我们这里在数据库中提取的是pwd字段,而我们的实体类中定义的是password属性。
-- 简而言之,就是让password属性和pwd字段对应起来就解决问题了。

解决方法:

  • 在mybatis中配置的xml文件,我们可以给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">

<mapper namespace="com.itholmes.dao.UserMapper">
    <select id="getUserById" resultType="User" parameterType="int">
        select id,name,pwd as password from mybatis.user where id = #id;
    </select>
</mapper>
  • 还有一种方法就是使用resultMap结果集映射的方法,如下一节。

3. resultMap结果集映射


通过使用resultMap结果集映射来解决上面的问题:

我们在UserMapper.xml文件中,设置了resultMap标签。

resultMap标签中声明了result标签它的column属性和property属性分别对应的就是数据库中的字段和实体类中的属性。通过这种方式一一对应起来。

<?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="com.itholmes.dao.UserDao">

    <!--
        结果集映射:
            id属性:就是当前resultMap的标识。
            type属性:定义映射后的结果类型。
    -->
    <resultMap id="UserMap" type="User">
        <!--
            column数据库中的字段,property实体类中的属性。
            这就意思就是让column数据库字段和property实体类属性对应起来。
        -->
        <result property="id" column="id"></result>
        <result property="name" column="name"></result>
        <result property="password" column="pwd"></result>
    </resultMap>

    <select id="selectById" resultMap="UserMap">
        select * from `user` where id = #id;
    </select>
</mapper>

其实,我们不设置resultMap,MyBatis会在幕后自动创建一个resultMap,再基于属性名来映射到JavaBean(Java实体类)的属性上面。

4. 日志

4.1 日志工程


如果一个数据库sql操作,出现了异常,我们需要排错,日志就是最好的助手!

对于这样的异常,以前使用sout,debug。来进行排查找错。

现在,使用日志会更加方便!


在mybatis-config.xml核心配置文件的setting标签中,有个logImpl配置。


(后面的未设置,是没有设置默认值的意思。)

  • SLF4J
  • LOG4J(重点)
  • LOG4J2:LOG4J的升级版本。
  • JDK_LOGGING:Java自带的日志输出。
  • COMMONS_LOGGING:工具包(像之前的commons_io一样的工具包)。
  • STDOUT_LOGGING(重点):标准日志输出。
  • NO_LOGGING:没有日志输出。

在Mybatis中具体使用那个日志实现,都在setting设置中设定。


STDOUT_LOGGING标准日志输出:
在mybatis-config.xml核心配置文件中,配置我们的日志:(注意顺序问题)

<settings>
    <!--
        name就对应logImpl , value对应官方给定的值。
        注意这里不是我们自己设定的,而是官方给出来让我们用的,这些名字和value值我们不能随便改。
    -->
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

4.2 LOG4J日志输出


什么是Log4j?

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

第一步:导入log4j的包,一般我们在maven仓库加依赖。

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

第二步:创建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/itholmes.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][%dyy-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

第三步:在mybatis核心配置文件中,配置log4j日志的实现(logImpl)。

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

第四步:log4j的测试,直接运行测试类来进行测试。


简单实用:

  • 1.在要使用Log4j的类中,导入Logger的包,注意这里Logger系统有自带的,我们要使用log4j里面的那个包,import org.apache.log4j.Logger;

  • 2.定义好的Logger日志对象,参数为当前类的class。

在我们的测试类中,Logger对象一般我们放到上面(提升作用域),并且设置为staitc,方便使用。

package com.itholmes.dao;

import com.itholmes.pojo.User;
import com.itholmes.utils.MybatisSqlSession;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.junit.jupiter.api.Test;

public class test 

    //这里导入Logger是我们要之前导入import org.apache.log4j.Logger;的包,不要导错了。
    static Logger logger = Logger.getLogger(test.class);

    @Test
    public void test01()
        SqlSession sqlSession = MybatisSqlSession.getMybatisSqlSession();

        logger.info("测试,进入test01方法进行查询操作。");

        UserDao mapper = sqlSession.getMapper(UserDao.class);
        if (false)
            //一般使用在try-catch中。
            logger.error("发现异常");
        
        User user = mapper.selectById(1);

        System.out.println(user.toString());

        logger.info("测试结束。");
    

    @Test
    public void testLog4j()

        //我们可以根据不同级别信息,给日志追加一些信息等等。
        logger.info("info:进入了testLog4j");
        logger.debug("debug:进入了testLog4j");
        logger.error("error:进入testLog4j");

    

5. 分页

5.1 limit分页


为什么要分页?

  • 减少数据的处理量。

使用Limit分页

-- 语法:
select * from `表名` limit startIndex,pageSize;

使用Mybatis实现分页效果:

  • 1.接口里的分页方法。

UserDao类:

package com.itholmes.dao;

import com.itholmes.pojo.User;

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

public interface UserDao 
    //分页查询的效果
    List<User> getUserByLimit(Map<String,Integer> map);

  • 2.Mapper.xml配置。
<?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="com.itholmes.dao.UserDao">

    <!--分页查询的结果集映射-->
    <resultMap id="UserMap2" type="User">
        <result property="password" column="pwd"/>
    </resultMap>
    <!--分页查询-->
    <select id="getUserByLimit" parameterType="map" resultMap="UserMap2">
        select * from mybatis.user limit #startIndex,#pageSize;
    </select>

</mapper>
  • 3.测试类。
package com.itholmes.dao;

import com.itholmes.pojo.User;
import com.itholmes.utils.MybatisSqlSession;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.junit.jupiter.api.Test;

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

public class test 

    static Logger logger = Logger.getLogger(test.class);

    @Test
    public void getUserByLimit()
        SqlSession sqlSession = MybatisSqlSession.getMybatisSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        Map<String, Integer> map = new HashMap<>();
        map.put("startIndex",0);
        map.put("pageSize",2);
        List<User> list = mapper.getUserByLimit(map);
        for (User user : list) 
            System.out.println(user);
        
        sqlSession.close();
    

5.2 RowBounds分页(了解)



RowBounds就是不通过使用sql语句进行分页,而是通过java代码层面进行分页。

  • 1.设置的接口中的方法。
package com.itholmes.dao;

import com.itholmes.pojo.User;

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

public interface UserDao 
    //分页通过RowBounds实现
    List<User> getUserByRowBounds();

  • 2.配置mapper.xml文件。
<?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="com.itholmes.dao.UserDao">

    <!--分页查询的结果集映射-->
    <resultMap id="UserMap2" type="User">
        <result property="password" column="pwd"/>
    </resultMap>

    <!--limit分页-->
    <select id="getUserByLimit" parameterType="map" resultMap="UserMap2">
        select * from mybatis.user limit #startIndex,#pageSize;
    </select>

    <!--RowBounds分页-->
    <select id="getUserByRowBounds" resultMap="UserMap2">
        select * from mybatis.user;
    </select>

</mapper>
  • 3.测试。
package com.itholmes.dao;

import com.itholmes.pojo.User;
import com.itholmes.utils.MybatisSqlSession;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.junit.jupiter.api.Test;

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

public class test 

	//limit sql分页方式
    @Test
    public void getUserByLimit()
        SqlSession sqlSession = MybatisSqlSession.getMybatisSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        Map<String, Integer> map = new HashMap<>();
        map.put("startIndex",0);
        map.put("pageSize",2);
        List<User> list = mapper.getUserByLimit(map);
        for (User user : list) 
            System.out.println(user);
        
        sqlSession.close();
    

	//RowBounds java代码分页
    @Test
    public void getUserByRowBounds()
        SqlSession sqlSession = MybatisSqlSession.getMybatisSqlSession();

        //RowBounds实现,两个参数分别对应偏移量(从第几行读取),限制条数。
        RowBounds rowBounds = new RowBounds(1, 2);

        //通过Java代码层面实现分页效果
        List<User> list = sqlSession.selectList("com.itholmes.dao.UserDao.getUserByRowBounds",null,rowBounds);
        for (User user : list) 
            System.out.println(user);
        
        sqlSession.close();
    

5.3 分页插件



想使用,直接点文档看看就可以了。

6. 使用注解开发

6.1 面向接口编程


理解好面向对象编程和面向接口编程:


6.2 Mybatis的注解开发


什么时候用注解,什么时候用xml?


注解开发的实现:

  • 1.注解在接口上实现。
package com.itholmes.dao;

import com.itholmes.pojo.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;

public interface mybatis框架学习笔记(代码片段)

本篇Mybatis框架学习笔记;紧跟之前的学习Mybatis框架学习笔记(2)—>在mybatis框架核心配置文件中需要学习的配置configuration(配置)properties(属性)settings(设置)typeAliases(类型别名)typeHandlers 查看详情

mybatis框架学习笔记(代码片段)

本篇Mybatis框架学习笔记;紧跟之前的学习Mybatis框架学习笔记(1)—>小智RE0在mybatis框架核心配置文件中需要学习的配置configuration(配置)properties(属性)settings(设置)typeAliases(类型别名)typeHandl... 查看详情

mybatis学习总结(代码片段)

 根据bilibili https://www.bilibili.com/video/av17774929/ 视频学习总结 1.mybatis学习线路 2.元素JDBC存在的问题原生JDBC代码packagedal;importjava.io.File;importjava.io.FileInputStream;importjava.sql.Con 查看详情

mybatis学习总结---基本使用(代码片段)

孤傲苍狼:mybatis学习总结系列1.新建Maven项目  maven依赖:<!--https://mvnrepository.com/artifact/org.mybatis/mybatis--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</arti 查看详情

mybatis学习笔记(代码片段)

Mybatis学习笔记本篇文章是观看B站UP主狂神说关于Mybatis讲解的视频,借鉴Mybatis官方文档以及CSDN博主黑心白莲相关文章整理的个人Mybatis笔记。因笔者能力有限,文章难免有错误之处,欢迎各位评论勘误,共同探讨&#... 查看详情

mybatis学习总结(代码片段)

1Mybatis入门1.1单独使用jdbc编程问题总结1.1.1jdbc程序publicstaticvoidmain(String[]args)Connectionconnection=null;PreparedStatementpreparedStatement=null;ResultSetresultSet=null;try//加载数据库驱动Class.forName("com.mysql 查看详情

mybatis学习笔记11:解决字段名和属性的映射关系(代码片段)

解决字段名和属性的映射关系【Mybatis】学习笔记01:连接数据库,实现增删改【Mybatis】学习笔记02:实现简单的查【MyBatis】学习笔记03:配置文件进一步解读(非常重要)【MyBatis】学习笔记04:配置文件模板【MyBatis】学习笔记05... 查看详情

mybatis学习笔记-01(代码片段)

mybatis学习笔记-01认识mybatis安装mybatis准备工作我的第一个mybatis程序工具类MybatisUtil类(工具类)mybatis-config.xml(对应配置文件)实体类Dao层Dao接口UserMappr.xml测试UserMapprTest测试结果开启自学mybatis的时光。认识mybatis... 查看详情

mybatis学习笔记-01(代码片段)

mybatis学习笔记-01认识mybatis安装mybatis准备工作我的第一个mybatis程序工具类MybatisUtil类(工具类)mybatis-config.xml(对应配置文件)实体类Dao层Dao接口UserMappr.xml测试UserMapprTest测试结果开启自学mybatis的时光。认识mybatis... 查看详情

学习笔记mybatis学习笔记(代码片段)

本文是动力节点MyBatis教程的学习笔记。第一章1.三层架构(1)三层的功能表示层(UserInterfaceLayer):接受用户数据,显示请求的处理结果,包括jsp、html、servlet等。对应controller包;业务逻辑层(BusinessLogic... 查看详情

学习笔记mybatis学习笔记(代码片段)

本文是动力节点MyBatis教程的学习笔记。第一章1.三层架构(1)三层的功能表示层(UserInterfaceLayer):接受用户数据,显示请求的处理结果,包括jsp、html、servlet等。对应controller包;业务逻辑层(BusinessLogic... 查看详情

mybatis-plus-自动填充功能(学习笔记)(代码片段)

...充功能原理原理:实现元对象处理器接口:com.baomidou.mybatisplus.core.handlers.MetaObjectHandler二、使用步骤此处举自动注入时间的例子(但不止 查看详情

mybatis框架学习笔记(代码片段)

官方中文文档–>https://mybatis.org/mybatis-3/zh/getting-started.html或点击–>mybatis文档mybatis3版本的源码–>https://github.com/mybatis/mybatis-3/releases或点击–>mybatis3源码文章目录1.什么是mybatis2.基础搭建使用(1)添加相关maven依赖 查看详情

mybatis学习笔记(代码片段)

一、Mybatis简介1、MyBatis历史MyBatis最初是Apache的一个开源项目iBatis,2010年6月这个项目由ApacheSoftwareFoundation迁移到了GoogleCode。随着开发团队转投GoogleCode旗下,iBatis3.x正式更名为MyBatis。代码于2013年11月迁移到GithubiBatis一词来源于... 查看详情

mybatis框架学习笔记(代码片段)

本篇Mybatis框架学习笔记;紧跟之前的学习Mybatis框架学习笔记(3)–>文章目录1.当出现数据库的列字段与实体类的不一致时;需要手动配置字段映射;2.两张表以上的多表映射;完成查询所有的员工(附带地查到员工对应的部门);注意有... 查看详情

mybatis学习笔记-02(代码片段)

mybatis学习笔记-02增删改查功能实现1.通过id查询用户Dao接口:UserMapperUserMapper.xmlUserMapperTest2.插入用户Dao接口:UserMapperUserMapper.xmlUserMapperTest3.更新用户Dao接口:UserMapperUserMapper.xmlUserMapperTest4.删 查看详情

mybatis学习笔记(代码片段)

文章目录1.MyBatis简介1.1MyBatis历史1.2MyBatis特性1.3和其它持久化层技术对比2.搭建MyBatis2.1开发环境2.2创建maven工程2.3创建MyBatis的核心配置文件2.4创建mapper接口2.5创建MyBatis的映射文件2.6通过junit测试功能2.7加入log4j日志功能3.核心配置... 查看详情

mybatis系统性详解(学习笔记)(代码片段)

目录mybatis知识传统JDBC不足mybatis基础mybatis核心应用配置与原理解析mybatis核心概念整体认识mybatis源码包mybatis基本流程类调用mybatis流程记录mybatis处理流程图mybatis*之sessionmybatis之mappermybatis之sqlmybatis之executormybatis之Cache一级缓存二... 查看详情