首页 > 其他分享 >Mybatis(三)

Mybatis(三)

时间:2024-09-28 19:18:37浏览次数:8  
标签:缓存 mybatis Mybatis org 日志 log4j logger

4.9.4 延迟加载

        延迟加载,就是在使用数据时,进行查询操作,不使用时,不提前加载。可以节省内存,提高查询效率。

第一种方式: 局部配置(映射文件)

在<association> 标记里
配置如下属性:
fetchType="lazy"          lazy: 延迟加载   eager: 不延迟加载

如下:
 <association property="dept"  fetchType="eager" .....

第二种方法:全局配置(核心配置文件)

<settings>
    <!--日志开启开关-->
   <setting name="logImpl" value="STDOUT_LOGGING"/>
   <!--全局的延迟加载开关, value设置为true,表示开启全局延迟加载, 不写value属性,默认就是false-->
   <setting name="lazyLoadingEnabled" value="true"/>
</settings>

4.10 分页查询

4.10.1 简介

        在开发过程中,分页查询是一个常见的需求。为了简化分页查询的操作,我们可以使用 Mybatis 的分页插件,如 `PageHelper`。

分页插件的概念

        分页查询时,通常需要传入页数(page)每页条数(pageSize)。返回的数据包括页面数据、总条数、总页数、当前页面、每页条数等。使用分页插件可以快速帮助我们获取这些数据。

分页插件的核心原理

        分页查询的核心原理是通过SQL 语句中的 LIMIT 关键字,根据传入的参数(当前页码、每页显示条数)来控制返回的当前页的内容范围

4.10.2 步骤

1)添加依赖

<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
   <groupId>com.github.pagehelper</groupId>
   <artifactId>pagehelper</artifactId>
   <version>5.2.0</version>
</dependency>

2)在MyBatis的核心配置文件( mybatis-config.xml)中配置插件

<plugins>
    <!--设置分页插件-->
    <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>

4.10.3 分页的应用

1)开启分页功能

        在查询功能之前使用 PageHelper.startPage(int pageNum, int pageSize)开启分页功能,传入当前页码和每页显示的条数:

- pageNum:当前页的页码
- pageSize:每页显示的条数

 2)打印方法的返回值,查看

Page<Object> page = PageHelper.startPage(1, 3);
System.out.println(page);

 Page{
count=true, 
pageNum=2, 
pageSize=3, 
startRow=3, 
endRow=6, 
total=19, 
pages=7, 
reasonable=false, 
pageSizeZero=false}[Student{id=1002, name='关羽', gender='m', age=35, address='上海', scores=[Score{sid=1002, cid=1, score=70}, Score{sid=1002, cid=2, score=60}, Score{sid=1002, cid=3, score=80}]', courses=[Course{cid=1, cname='高数', tid=1, academy='信息学院', note='高等数学,微积分', students=null}, Course{cid=2, cname='英语', tid=2, academy='工程学院', note='英语选修', students=null}, Course{cid=3, cname='JAVA', tid=3, academy='信息学院', note='面向对象的编程语言', students=null}]}]

)另外一个API:

PageInfo 这个类型封装的信息更多一些,包括了导航分页的信息。 用于在查询之后。

new PageInfo(List list, int navegatePage);
list:  分页查询的返回数据
navegatePage:  用来定义导航分页的页码显示数量 

PageInfo{
   pageNum=2, 
   pageSize=3, 
   size=1, startRow=4, endRow=4, 
   total=19, 
   pages=7, 
   prePage=1, nextPage=3, 
   isFirstPage=false, 
   isLastPage=false, 
   hasPreviousPage=true, 
   hasNextPage=true, navigatePages=5, navigateFirstPage=1, navigateLastPage=5, navigatepageNums=[1, 2, 3, 4, 5]} 

4.11 注解完成增删改查

使用注解开发会比配置文件开发更方便。

- @Select  查询
- @Insert  添加
- @Update 修改
- @Delete 删除

 案例演示

 mapper接口:

package com.mybatis.mapper;

/*
    Mybatis在编写sql映射文件时,有时候感觉非常麻烦。补房费
    对于简单的增删改查操作,Mybatis提供了注解的方式(复杂的最好还是映射文件)
    @Select
    @Insert
    @Update
    @Delete
 */

import com.mybatis.pojo.Employee;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

public interface EmployeeMapper1 {
    @Select("select empno id,ename name, job,mgr,hiredate,sal,comm bonus,deptno deptId from emp")
    List<Employee> findAll();

    @Select("select empno id,ename name, job,mgr,hiredate,sal,comm bonus,deptno deptI from emp where empno = #{id}")
    Employee findById(Integer id);

    @Insert("insert into emp values (null,#{name},#{job},#{mgr},#{hireDate},#{sal},#{bonus},#{deptId})")
    void addEmployee(Employee employee);

    @Delete("delete from emp where empno = #{id}")
    void deleteEmployee(Integer id);

    @Update("update emp set ename = #{name},job=#{job},mgr=#{mgr},hiredate=#{hireDate},sal=#{sal},comm=#{bonus},deptno=#{deptId} where empno=#{id}")
    void updateEmployee(Employee employee);
}

测试:

package com.mybatis;

import com.mybatis.mapper.EmployeeMapper;
import com.mybatis.mapper.EmployeeMapper1;
import com.mybatis.pojo.Employee;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.sql.Date;

public class EmployeeMapper1Test {
    private SqlSession sqlSession;
    @Before
    public void setUp() throws Exception {
        SqlSessionFactory fac = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config.xml"));
        sqlSession= fac.openSession();
    }
    @After
    public void tearDown() throws Exception {
        sqlSession.close();
    }
    @Test
    public void testFindAll() throws Exception {
        EmployeeMapper1 mapper = sqlSession.getMapper(EmployeeMapper1.class);
        mapper.findAll().forEach(System.out::println);
    }

    @Test
    public void testFindById() throws Exception {
        EmployeeMapper1 mapper = sqlSession.getMapper(EmployeeMapper1.class);java
        Employee emp = mapper.findById(7782);
        System.out.println(emp);
    }
    @Test
    public void testAddEmployee() throws Exception {
        EmployeeMapper1 mapper = sqlSession.getMapper(EmployeeMapper1.class);
        Employee employee = new Employee(null,"小明","SALESMAN",7782, Date.valueOf("2022-02-12"),1500.0,123.0,20);
        mapper.addEmployee(employee);
        sqlSession.commit();
    }
    @Test
    public void testDeleteEmployee() throws Exception {
        EmployeeMapper1 mapper = sqlSession.getMapper(EmployeeMapper1.class);
        mapper.deleteEmployee(7935);
        sqlSession.commit();
    }
    @Test
    public void testUpdateEmployee() throws Exception {
        EmployeeMapper1 mapper = sqlSession.getMapper(EmployeeMapper1.class);
        Employee employee = new Employee(7935,"小明","SALESMAN",7782, Date.valueOf("2022-02-12"),1500.0,123.0,20);
        mapper.updateEmployee(employee);
        sqlSession.commit();
    }

}

        使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让本就复杂的 SQL 语句更加混乱不堪。 因此,如果你需要做一些很复杂的操作,最好用 XML 来映射语句

选择何种方式来配置映射,以及是否应该要统一映射语句定义的形式,完全取决于你和你的团队。 换句话说,永远不要拘泥于一种方式,你可以很轻松地在基于注解和 XML 的语句映射方式间自由移植和切换。

简单来说:

- 注解用于完成简单功能
- 配置文件完成复杂功能
 

五 Mybatis的缓存

5.1 Mybatis缓存简介

        缓存(cache):提前把数据存放到缓存当中,下一次再使用的时候,直接从缓存中拿,而不用再次去数据库中查询一次了。这样的优势在于:通过减少IO的⽅式,来提⾼程序的执⾏效率。    比如浏览器就有缓存功能…..

        MyBatis的缓存:将select语句的查询结果放到缓存(内存)当中,下⼀次还是这条相同select语句的话,直接从缓存中取,不再查数据库。⼀⽅⾯是减少了IO,另⼀⽅⾯不再执⾏繁琐的查找算法;效率⼤⼤提升。

mybatis缓存包括:

  • ⼀级缓存:将查询到的数据存储到SqlSession中。
  • ⼆级缓存:将查询到的数据存储到SqlSessionFactory中。
  • 集成其它第三⽅的缓存:⽐如EhCache【Java语⾔开发的】、Memcache【C语⾔开发的】 等。

缓存只针对于DQL语句,也就是说缓存机制只对应select语句。

5.2 一级缓存

一级缓存的范围是SqlSession

        ⼀级缓存默认是开启的,不需要做任何配置。
        原理:只要使⽤同⼀个SqlSession对象执⾏同⼀条SQL语句,就会⾛缓存。

什么时候不走缓存

        第⼀种:不同的SqlSession对象。
        第⼆种:查询条件变化了。

什么时候缓存失效

        ①第⼀次查询和第⼆次查询之间,执行了clearCache()方法,⼿动清空了⼀级缓存。
        ②第⼀次查询和第⼆次查询之间,执⾏了增、删、改操作。

 5.3 二级缓存

⼆级缓存的范围是SqlSessionFactory对象。使⽤⼆级缓存需要具备以下⼏个条件

①全局性地开启或关闭所有映射器配置⽂件中已配置的任何缓存。默认就是true,⽆需设置(默认二级缓存就是开启的)!

 <setting name="cacheEnabled" value="true">

②在需要使⽤⼆级缓存的SqlMapper.xml⽂件中添加一个标签:<catche />

坑: 测试使用的增删改方法,也要使用同一个配置。

③使⽤⼆级缓存的实体类对象必须是可序列化的,也就是必须实现java.io.Serializable接⼝

④SqlSession对象提交之后,⼀级缓存中的数据才会被写⼊到⼆级缓存当中;此时⼆级缓存才可⽤。(注意,一级缓存还存储数据呢,并没有清空)

⼆级缓存的失效:

只要两次查询之间出现了增、删、改操作,⼆级缓存就会失效。【当然⼀级缓存也会失效】!

二级缓存相关配置

① eviction:指定从缓存中移除某个对象的淘汰算法。(默认采⽤LRU策略)

 LRU:Least Recently Used。最近最少使⽤,优先淘汰在间隔时间内使⽤频率最低的对象。(其实还有⼀种淘汰算法LFU,最不常⽤)
FIFO:First In First Out。⼀种先进先出的数据缓存器,先进⼊⼆级缓存的对象最先被淘汰。
SOFT:软引⽤,淘汰软引⽤指向的对象。具体算法和JVM的垃圾回收算法有关。
WEAK:弱引⽤,淘汰弱引⽤指向的对象。具体算法和JVM的垃圾回收算法有关。

②  flushInterval:⼆级缓存的刷新时间间隔,单位毫秒(刷新了也会使原来的缓存失效)。如果没有设置,就代表不刷新缓存,只要内存⾜够⼤,⼀ 直会向⼆级缓存中缓存数据,除⾮执⾏了增删改。

③size:设置⼆级缓存中最多可存储的java对象数量,默认值1024。

④readOnly

true: 只读缓存,多条相同的sql语句执⾏之后返回的对象是共享的同⼀个,性能好。但是多线程并发可能会存在安全问题。
false:读写缓存,多条相同的sql语句执⾏之后返回的对象是副本,调⽤了clone⽅法。性能⼀般,但安全。

在sql映射xml文件中写 :

 <!--  二级缓存配置-->
    <cache eviction="FIFO" readOnly="true" size="10000" flushInterval="1000"/>

5.4 Mybatis缓存查询顺序

  • 先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用
  • 如果二级缓存没有命中,再查询一级缓存
  • 如果一级缓存也没有命中,则查询数据库
  • SqlSession提交之后,一级缓存中的数据会写入二级缓存

5.5 MyBatis集成第三方缓存EhCache

        mybatis对外提供了接⼝,也可以集成第三⽅的缓存组件;⽐如EhCache、Memcache等。         EhCache是Java写的、Memcache是C语⾔写的,所以mybatis集成EhCache较为常⻅,按照以下步骤操作,就可以完成集成

第⼀步:在pom.xml配置中引⼊MyBatis整合ehcache的依赖

ehcache需要slf4j的⽇志组件,log4j不好使!

<!--mybatis集成ehcache的组件-->
<dependency>
   <groupId>org.mybatis.caches</groupId>
   <artifactId>mybatis-ehcache</artifactId>
   <version>1.2.2</version>
</dependency>


<dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-classic</artifactId>
   <version>1.2.11</version>
   <scope>test</scope>
</dependency>

 第⼆步:在类的根路径下(resources)新建ehcache.xml⽂件,并提供以下配置信息。

<?xml version="1.0" encoding="UTF-8"?>

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false">
   <!--磁盘存储:将缓存中暂时不使⽤的对象,转移到硬盘,类似于Windows系统的虚拟内存-->
   <diskStore path="D:/ehcache"/>

   <defaultCache eternal="false" 
                 maxElementsInMemory="1000" 
                 overflowToDisk="false"
                 diskPersistent="false" 
                 timeToIdleSeconds="0" 
                 timeToLiveSeconds="600"
                 memoryStoreEvictionPolicy="LRU"/>
</ehcache>

 第三步:修改CarMapper.xml⽂件中的标签,添加type属性,引入EhcacheCache

<?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.bjpowernode.mybatis.mapper.CarMapper">
   <!--集成EhcacheCache组件-->
   <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
   <select id="selectById2" resultType="Car">
      select * from t_car where id = #{id}
   </select>
</mapper>

 第四步:编写测试程序使⽤,代码还是和上面使用二级缓存的测试代码相同,效果展示也是相同的,都是第一次命中率是0.0,第二次命中率是0.5

 六 MyBatis的逆向工程

        MyBatis的逆向工程是指根据数据库表结构自动生成对应的Java实体类、Mapper接口和XML映射文件的过程。逆向工程可以帮助开发人员快速生成与数据库表对应的代码,减少手动编写重复代码的工作量。

        我们在MyBatis中通过逆向工具来帮我简化繁琐的搭建框架,减少我们对实体类的创建和mapper接口等,包括生产xml映射文件,不过一般开发中,我们不怎么使用映射文件生成的东西因为生成的xml文件并不符合我们实际开发中使用的,所以我们一般通过逆向工具帮我们创建相关文件之后,然后我们在根据创建的文件进行处理。

逆向工程的好处

1. 提高开发效率:逆向工程可以自动生成实体类、Mapper接口和XML映射文件,减少了手动编写这些代码的时间和工作量。开发人员可以专注于业务逻辑的实现,提高开发效率。
2. 保持代码一致性:逆向工程生成的代码与数据库表结构保持一致,避免了手动编写代码时可能出现的拼写错误、字段类型不匹配等问题。这样可以确保代码的准确性和一致性。

3. 易于维护和更新:当数据库表结构发生变化时,可以通过重新运行逆向工程来更新生成的代码,而不需要手动修改和调整代码。这样可以减少维护工作的复杂性和风险。

4. 提供基础代码框架:逆向工程生成的代码提供了基础的增删改查操作,开发人员可以在此基础上进行扩展和定制,快速构建具体业务功能。

5. 避免重复劳动:逆向工程可以自动生成大量的基础代码,避免了开发人员重复编写相似的代码的劳动,提高了开发效率和代码质量

正向工程:先创建Java实体类,由框架负责根据实体类生成数据库表。Hibernate是支持正向工程的

逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成如下资源:

                Java实体类
                Mapper接口
                Mapper映射文件

6.1 生成基本的CRUD(清新简洁版)

1)添加依赖和插件

 <dependencies>
    <!-- MyBatis核心依赖包 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.9</version>
    </dependency>
    <!-- junit测试 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
    <!-- MySQL驱动 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.31</version>
    </dependency>
    <!-- log4j日志 -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>
  </dependencies>
  <!-- 控制Maven在构建过程中相关配置 -->
  <build>
    <!-- 构建过程中用到的插件 -->
    <plugins>
      <!-- 具体插件,逆向工程的操作是以构建过程中插件形式出现的 -->
      <plugin>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-maven-plugin</artifactId>
        <version>1.4.2</version>
<!--        生产环境中尽量别覆盖写-->
        <configuration>
          <overwrite>true</overwrite>
        </configuration>
        <!-- 插件的依赖 -->
        <dependencies>
          <!-- 逆向工程的核心依赖 -->
          <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.4.2</version>
          </dependency>
          <!-- 数据库连接池 -->
          <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.20</version>
          </dependency>
          <!-- MySQL驱动 -->
          <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.31</version>
          </dependency>
        </dependencies>
      </plugin>
    </plugins>
  </build>x

2)创建逆向工程配置文件

文件名必须是:generatorConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <!--
    targetRuntime: 执行生成的逆向工程的版本
    MyBatis3Simple: 生成基本的CRUD(清新简洁版)
    MyBatis3: 生成带条件的CRUD(奢华尊享版)
    -->
    <context id="DB2Tables" targetRuntime="MyBatis3Simple">
        <!-- 数据库的连接信息 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/mybatis_db?serverTimezone=Asia/Shanghai&amp;useTimezone=true&amp;useSSL=false"
                        userId="root"
                        password="123456">
        </jdbcConnection>
        <!-- javaBean的生成策略-->
        <javaModelGenerator targetPackage="com.mybatis.pojo" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!-- SQL映射文件的生成策略 -->
        <sqlMapGenerator targetPackage="com.mybatis.mapper"
                         targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>
        <!-- Mapper接口的生成策略 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.mybatis.mapper" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>
        <!-- 逆向分析的表 -->
        <!-- tableName设置为*号,可以对应所有表,此时不写domainObjectName -->
        <!-- domainObjectName属性指定生成出来的实体类的类名 -->
        <table tableName="emp" domainObjectName="Emp"/>
        <table tableName="dept" domainObjectName="Dept"/>
    </context>
</generatorConfiguration>

 3)log4j.properties

log4j.rootLogger=WARN, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

 4)log4j.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
        <param name="Encoding" value="UTF-8" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS}%m (%F:%L) \n" />
        </layout>
    </appender>
    <logger name="java.sql">
        <level value="debug" />
    </logger>
    <logger name="org.apache.ibatis">
        <level value="info" />
    </logger>
    <root>
        <level value="debug" />
        <appender-ref ref="STDOUT" />
    </root>
</log4j:configuration>

 5)接下来我们就通过MBG插件的generate构建我们的相关文件 双击运行

 然后我们就可以等待看到我们的目录下,出现了相关生成的文件了。

 

 6.2 生成带条件的CRUD(奢华尊享版)

targetRuntime: 执行生成的逆向工程的版本

MyBatis3Simple: 生成基本的CRUD(清新简洁版)

MyBatis3: 生成带条件的CRUD(奢华尊享版)

将targetRuntime的MybatisSimple换成Mybatis3 

<context id="DB2Tables" targetRuntime="MyBatis3">

生成的类更加复杂, sql语句更加复杂。

七 Mybatis日志组件

7.1 日志概念

假如,你开了一家火锅店,每天的营业额、顾客的反馈、商品的进出、库存等等,你都会记录下来。这就像是程序的日志。不管是C端,还是B端,还是移动端的的应用程序(Application),日志这个东西都是非常重要的。

日志,用来记录程序运行时发生的事情。比如,程序启动了、执行了某个操作、遇到了问题等等,这些都可以通过日志记录下来。

再比如:

  • 电商网站:记录用户的登录、浏览、购买行为,监控交易过程,及时发现异常交易;通过日志分析你的浏览记录,实现精准推送等等

  • 服务器:记录服务器的启动、运行、关闭状态,以及发生的各种错误,帮助管理员及时发现并解决问题

日志的其他作用:

  • 调试帮助:当程序出现问题时,通过查看日志,可以快速定位问题发生的地方和原因。

  • 监控运行状态:通过日志可以了解程序的运行状态,比如用户的操作、系统的性能等。

  • 安全审计:在需要记录用户行为或系统操作的场合,日志可以作为审计的依据。

public class TEst(){
   public static void main(String[] args){
      System.out.println("程序启动");
      Scanner sc = new Scanner(System.in);
      // 假设这里是用户输入数据
      String userInput = sc.nextInt();
      System.out.println("用户输入了: " + userInput);
      // 处理数据
      String result = processInput(userInput);
      System.out.println("处理结果: " + result);
      try {
         //可能异常的逻辑代码
      }catch(Exception e){
         e.printStackTrace()
      }
      // 程序结束
      System.out.println("程序结束");
   }
   private static String processInput(String input) {
      // 这里是处理逻辑
      return "Processed: " + input;
   }
}

        上面的案例,我们使用输出语句来打印程序的运行状态,使用e.printStackTrace()来打印异常信息,这是最简单的日志打印方法。

这种方式简单直接,但也有一些缺点:

  • 灵活性差:不能方便地控制日志的输出格式、级别等。

  • 性能问题:大量日志输出可能会影响程序性能。

  • 不易管理:日志信息混在标准输出中,不易于查找和分析。

所以我们要引入各种功能强大的日志框架进行日志管理。Mybatis常用的日志组件。

  • STDOUT_LOGGING 标准日志,Mybatis框架本身已经实现了这种日志,我们只需要使用<setting>标签开启日志即可。

  • SLF4J

  • LOG4J

  • LOG4J2

7.2 MyBatis内置的日志组件:

<!--设置日志输出组件-->
<settings>
   <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
  •  STDOUT_LOGGING我们可以直接使用,但是如果想使用SLF4J等第三方日志组件,需要引入相应jar包。
  • 注意:这个标签必须在<properties></properties>后<typeAliases></typeAliases>前,这是dtd对xml文件的约束规范。

7.3 SLF4J日志组件

 第一步:引入相应jar包logback

<dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-classic</artifactId>
   <version>1.2.11</version>
   <scope>test</scope>
</dependency>

 第二步:引入logback所必须的xml配置文件。这个xml文件必须在类的根路径下,文件名必须是logback.xml。

<?xml version="1.0" encoding="UTF-8"?>

<configuration debug="false">
	 <!--定义⽇志⽂件的存储地址-->
	 <property name="LOG_HOME" value="D:/home"/>
	 
	 <!-- 控制台输出 -->
	 <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		 <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			 <!--格式化输出:%d表示⽇期,%thread表示线程名,%-5level:级别从左显示5 个字符宽度%msg:⽇志消息,%n是换⾏符-->
			 <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
		 </encoder>
	 </appender>
	
	 <!-- 按照每天⽣成⽇志⽂件 -->
	 <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
	 
		 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			 <!--⽇志⽂件输出的⽂件名-->
			 <FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern>
			 <!--⽇志⽂件保留天数-->
			 <MaxHistory>30</MaxHistory>
		 </rollingPolicy>
		 
		 <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			 <!--格式化输出:%d表示⽇期,%thread表示线程名,%-5level:级别从左显示5 个字符宽度%msg:⽇志消息,%n是换⾏符-->
			 <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
		 </encoder>
		 
		 <!--⽇志⽂件最⼤的⼤⼩-->
		 <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
			 <MaxFileSize>100MB</MaxFileSize>
		 </triggeringPolicy>
		 
	 </appender>
	 
	 <!--mybatis log configure-->
	 <logger name="com.apache.ibatis" level="TRACE"/>
	 <logger name="java.sql.Connection" level="DEBUG"/>
	 <logger name="java.sql.Statement" level="DEBUG"/>
	 <logger name="java.sql.PreparedStatement" level="DEBUG"/>
	 <!-- ⽇志输出级别,logback⽇志级别包括五个:TRACE < DEBUG < INFO < WARN < ER
	ROR -->
	 <root level="DEBUG">
		 <appender-ref ref="STDOUT"/>
		 <appender-ref ref="FILE"/>
	 </root>
</configuration>

 第三步:开启日志输出

<!--设置日志输出组件-->
<settings>
   <setting name="logImpl" value="SLF4J"/>
</settings>

7.4 Log4J日志组件

        Log4j 是Apache软件基金组织旗下的一款开源日志框架,是一款非常老牌的日志框架,功能非常强大,可以自定义很多日志的细节,比如日志级别、输出格式、输出目的地等。

        目前已出log4j2,它在log4j上做了很大改动,性能提升了不少。但是有些老项目还会在使用,所以我们也来用一用

 日志的级别:

  • TRACE:追踪级别,通常用来记录程序运行的详细轨迹,比如方法调用的顺序等。这个级别非常详细,一般在开发阶段或者调试时用得比较多。
  • DEBUG调试级别,用来记录程序的运行状态,比如变量的值、程序的流程等。当你需要深入了解程序的内部工作时,DEBUG级别就非常有用。
  • INFO:信息级别,用来记录程序的正常运行状态,比如程序启动、配置信息、正常结束等。INFO级别的日志对用户和开发者了解程序的运行情况很有帮助。
  • WARN:警告级别,用来记录一些可能引起问题的情况,但程序仍然可以继续运行。比如,程序遇到了一个不常见的情况,或者某个操作失败了但不影响大局。
  • ERROR:错误级别,用来记录程序运行中的错误,这些错误通常会影响程序的正常功能,但程序可能还能继续运行。
  • FATAL:致命级别,用来记录非常严重的错误,这些错误会导致程序完全无法继续运行。比如,程序的某个关键部分失败了,整个应用可能需要重启。

TRACE(追踪) < DEBUG(调试) < INFO(信息) < WARN(警告) < ERROR(错误)  <  FATAL(致命)  从左到右打印的内容越来少

<!--设置日志输出组件-->
<settings>
   <setting name="logImpl" value="LOG4J"/>
</settings>

 第一步:引入依赖

<!--log4j依赖的jar包    -->
<dependency>
   <groupId>log4j</groupId>
   <artifactId>log4j</artifactId>
   <version>1.2.17</version>
</dependency>

第二步:编写LOG4J配置文件。 log4j.properties 和 log4j.xml 这两种配置文件最常用。选择其中一种即可。存放的位置是src/main/resources目录下。

log4j.properties

#    %m 输出代码中指定的消息 
#    %p 输出日志级别,即DEBUG,INFO,WARN,ERROR,FATAL 
#    %r 输出自应用启动到输出该log信息耗费的毫秒数 
#    %c 输出所属的类目,通常就是所在类的全名 
#    %t 输出产生该日志事件的线程名 
#    %n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n” 
#    %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 :10:28,921
#    %l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。
# Log4j一个关键设置,用于定义日志的全局级别和输出目的地。该设置的基本语法如下
# log4j.rootLogger = [level], appenderName1, appenderName2, ...
log4j.rootLogger=DEBUG,console,file

###第一个目的地的相关配置
### 目的地的实现类
log4j.appender.console = org.apache.log4j.ConsoleAppender
### 输出目标:System.out表示控制台输出,默认值, 也可以是System.err
log4j.appender.console.Target = System.out
### 日志级别,局部设置
log4j.appender.console.Threshold = DEBUG
### 布局,即输出的外观样式,使用自定义格式化布局
log4j.appender.console.layout = org.apache.log4j.PatternLayout
### 具体的格式,使用站位符来布局
##log4j.appender.console.layout.ConversionPattern= %5p %d{yyyy-MM-dd HH:mm:ss} %c %m %n
log4j.appender.console.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}] %l %t %m %n
log4j.appender.console.encoding=UTF-8

###第二个目的地file的配置
#将日志输出到文件中,并且指定文件的大小,当文件大于指定大小,会生成一个新的日志文件
log4j.appender.file=org.apache.log4j.RollingFileAppender
#路径
log4j.appender.file.File=D:/applog/logs/log.txt
#日志最大限制
log4j.appender.file.MaxFileSize=1024KB
#最多只保存1000个备份文件
log4j.appender.file.MaxBackupIndex=1000
log4j.appender.file.Threshold=debug
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
log4j.appender.file.encoding=UTF-8

# 显示mybatis的部分
log4j.logger.com.mybatis=DEBUG
log4j.logger.com.mybatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.mybatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.mybatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG、
log4j.logger.java.sql=DEBUG  
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG  

 log4j.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
   <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
      <param name="Encoding" value="UTF-8" />
      <layout class="org.apache.log4j.PatternLayout">
         <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
      </layout>
   </appender>
   <logger name="java.sql">
      <level value="debug" />
   </logger>
   <logger name="org.apache.ibatis">
      <level value="info" />
   </logger>
   <root>
      <level value="debug" />
      <appender-ref ref="STDOUT" />
   </root>
</log4j:configuration>

第三步: 编写日志代码

  • 在你的 Java 代码中,通过获取 Logger 实例来记录日志信息。
  • 使用不同的日志级别来记录不同重要性的信息。
import org.apache.logging.log4j.LogManager;  
import org.apache.logging.log4j.Logger;  
  
public class LogExample {  
    private static final Logger logger = LogManager.getLogger(LogExample.class);  
  
    public static void main(String[] args) {  
        logger.debug("This is a debug message");  
        logger.info("This is an info message");  
        logger.warn("This is a warn message");  
        logger.error("This is an error message");  
        logger.fatal("This is a fatal message");  
    }  
}

7.5 Log4J2日志组件

<!--设置日志输出组件-->
<settings>
   <setting name="logImpl" value="LOG4j2"/>
</settings>

 第一步:

<properties>
   <logging.log4j.version>2.17.1</logging.log4j.version>
</properties>

<!-- log4j2 -->
<dependency>
   <groupId>org.apache.logging.log4j</groupId>
   <artifactId>log4j-api</artifactId>
   <version>${logging.log4j.version}</version>
</dependency>
<dependency>
   <groupId>org.apache.logging.log4j</groupId>
   <artifactId>log4j-core</artifactId>
   <version>${logging.log4j.version}</version>
</dependency>
<dependency>
   <groupId>org.apache.logging.log4j</groupId>
   <artifactId>log4j-slf4j-impl</artifactId>
   <version>${logging.log4j.version}</version>
</dependency>

第二步:log4j2.xml  

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="debug">
    <properties>
        <!-- 基本的文件的输出信息的配置 -->
        <property name="LOG_HOME">D:\logs</property>
        <!-- 日志备份目录 -->
        <property name="SERVER_NAME">web-font</property>
    </properties>
    <appenders>
        <!-- 定义控制台输出 -->
        <CONSOLE name="CONSOLE" target="SYSTEM_OUT" follow="true">
            <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss,SSS}] %p [%t] %l - %m%n"/>
        </CONSOLE>
        <!-- 文件日志 -->
        <RollingRandomAccessFile name="DAILY-ROLL-FILE" fileName="${LOG_HOME}/${SERVER_NAME}.log"
                                 filePattern="${LOG_HOME}/${SERVER_NAME}.%d{yyyy-MM-dd-HH}.log">
            <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss,SSS}] %p [%t] %l - %m%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
        </RollingRandomAccessFile>

    </appenders>
    <loggers>
        <logger name="org.springframework" level="info" additivity="false">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="DAILY-ROLL-FILE"/>
        </logger>
        <logger name="org.apache.ibatis" level="debug" additivity="false">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="DAILY-ROLL-FILE"/>
        </logger>
        <root level="debug">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="DAILY-ROLL-FILE"/>
        </root>
    </loggers>
</configuration>

使用方法 

import org.apache.logging.log4j.LogManager;  
import org.apache.logging.log4j.Logger;  
  
public class LogExample {  
    private static final Logger logger = LogManager.getLogger(LogExample.class);  
  
    public static void main(String[] args) {  
        logger.trace("This is a trace message");  
        logger.debug("This is a debug message");  
        logger.info("This is an info message");  
        logger.warn("This is a warn message");  
        logger.error("This is an error message");  
        logger.fatal("This is a fatal message");  
    }  
}

标签:缓存,mybatis,Mybatis,org,日志,log4j,logger
From: https://blog.csdn.net/zhaogodzero/article/details/142532456

相关文章

  • SpringBoot与MyBatis-Plus的整合与综合实例
    MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程、以及高级映射。MyBatis3提供的注解可以取代XML。例如,使用注解@Select直接编写SQL完成数据查询。MyBatis-Plus是一个对MyBatis进行增强的工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生......
  • MyBatis-Plus分页查询
    在实际开发中,对于大量数据的查询,可以通过分页查询的方式来减少查询量和提高查询效率。在MyBatis-Plus中,分页查询可以通过使用Page对象和IService接口提供的分页方法来实现。MyBatis-Plus的分页插件PaginationInnerInterceptor提供了强大的分页功能,支持多种数据库,使得......
  • 轻松上手MyBatis反向工程:从零到一的自动化代码生成
    前言反向工程概念:反向工程是从已有的具体实现(如数据库表结构)中推导出高层次的信息(如Java代码)的过程。在MyBatis中,它特指根据数据库表结构自动生成Java实体类、Mapper接口和XML映射文件。原理:MyBatis反向工程通过读取数据库表结构的元数据(如表名、字段名、字段类型等),然后利......
  • 深入剖析 MyBatis-Plus:操作总结、对比与实践案例(CRUD 操作、分页、条件构造器、自动填
    MyBatis-Plus是MyBatis的增强工具,它极大简化了MyBatis的配置和操作,提高了开发效率。本文从基本操作到高阶用法,详细介绍了MyBatis-Plus的常见功能及与MyBatis的区别,并通过实际案例展示其强大的扩展能力。MyBatis-Plus基于MyBatis,但旨在减少开发者的代码量,增强可......
  • Mybatis详细教程 (万字详解)
    Mybatis3.5.14来自于B站‘天气预报’,一名宝藏up,跟着他可以培养起独立解决编程问题的能力!!!01.简介1.1官网官方中文网:MyBatis中文网中文网参考手册1.2概念MyBatis是一款优秀的持久层框架,支持自定义SQL,存储过程,高级映射官方解释必要前置技术Mys......
  • 【2024计算机毕业设计】基于jsp+mysql+Spring+mybatis的SSM汽车维修预约平台
    运行环境:最好是javajdk1.8,我在这个平台上运行的。其他版本理论上也可以。IDE环境:Eclipse,Myeclipse,IDEA或者SpringToolSuite都可以,如果编译器的版本太低,需要升级下编译器,不要弄太低的版本tomcat服务器环境:Tomcat7.x,8.x,9.x版本均可操作系统环境:WindowsXP/7......
  • MyBatis 动态语句
    一、if和where语句<!--List<Employee>selectEmployeeByCondition(Employeeemployee);--><selectid="selectEmployeeByCondition"resultType="employee">selectemp_id,emp_name,emp_salaryfromt_emp<!--where标签会......
  • MyBatis框架02
    一、Mybatis完成CURD1.1CURD的R1.1.1CRUD的R11)在Mapper接口里添加findAll方法publicinterfaceEmployeeMapper{List<Employee>findAll();}2)在SQL映射文件中添加对应的配置<selectid="findAll"resultType="student">select*fromemp</selec......
  • 【2024计算机毕业设计】基于jsp+mysql+Spring+mybatis的SSM在线装潢家装材料进销存管
    运行环境:最好是javajdk1.8,我在这个平台上运行的。其他版本理论上也可以。IDE环境:Eclipse,Myeclipse,IDEA或者SpringToolSuite都可以,如果编译器的版本太低,需要升级下编译器,不要弄太低的版本tomcat服务器环境:Tomcat7.x,8.x,9.x版本均可操作系统环境:WindowsXP/7......
  • 【Java】【SpringBoot】SpringBoot整合MybatisPlus(快速入门)
    较早之前,写了SpringBoot整合Mybatis:https://www.cnblogs.com/luyj00436/p/16701894.html。这个数据库的链接有过时。Mybatisplus是mybatis的增强工具。对比Mybatis功能强大、易于使用。对于复杂业务,需要连接多张表单,Mybatisplus不够灵活,隐藏了代码,也不能更好地调试;对于简单业务......