三、MyBatis(3)

一、动态SQL

中文网

1.1 什么是动态SQL

  • 动态SQL就是根据不同的条件生成不同的SQL语句
  • 利用动态SQL这一特性可以彻底摆脱这种痛苦。

如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。

if
choose (when, otherwise)
trim (where, set)
foreach

1.2 搭建环境

(1)sql:

CREATE TABLE `blog`(
`id` VARCHAR(50) NOT NULL COMMENT '博客id',
`title` VARCHAR(100) NOT NULL COMMENT '博客标题',
`author` VARCHAR(30) NOT NULL COMMENT '博客作者',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`views` INT(30) NOT NULL COMMENT '浏览量'
)ENGINE=INNODB DEFAULT CHARSET=utf8

(2)创建一个基础工程

在这里插入图片描述

  1. 导包
  2. 编写配置文件
  3. 编写实体类
  4. 编写实体类对应Mapper接口和Mapper.xml文件

1.导包

<!--lombok-->
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
        </dependency>
    </dependencies>

    <!--在build中配置resources,来防止我们资源导出失败的问题-->
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>

            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>
        </resources>
    </build>
  1. 编写配置文件

db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?\
  useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username=root
password=root

mybatis-config.xml

(1)开启驼峰命名自动映射知识点

设置名描述有效值默认值
mapUnderscoreToCamelCase是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。true falseFalse

在这里插入图片描述
(2) mybatis-config.xml

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

    <properties resource="db.properties"/>
    
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <setting name="mapUnderscoreToCamelCase" value="true"></setting>
    </settings>

    <typeAliases>
        <package name="com.zql.pojo"></package>
    </typeAliases>

    <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 class="com.zql.mapper.BlogMapper"></mapper>
    </mappers>
</configuration>
  1. 导入工具类

MybatisUtils.java

package com.zql.utils;

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 java.io.InputStream;

public class MybatisUtils {

    private static  SqlSessionFactory sqlSessionFactory;

    static {
        try {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //1.Resources获取加载全局配置文件
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession(true);//true自动提交事务
    }
}

IDutils.java

package com.zql.utils;

import org.junit.Test;

import java.util.UUID;

/**
 * @Author:Daniel
 * @Version 1.0
 */
public class IDutils {

    public static String getId(){

        return  UUID.randomUUID().toString().replaceAll("-","");

    }

    @Test
    public void test(){

        System.out.println(IDutils.getId());
    }
}

  1. 编写实体类

Blog.java

package com.zql.pojo;

import lombok.Data;

import java.io.Serializable;
import java.util.Date;

/**
 * @Author:Daniel
 * @Version 1.0
 */
@Data
public class Blog implements Serializable {

    private String id;
    private String title;
    private String author;
    private Date createTime;
    private int views;
}

  1. 编写实体类对应Mapper接口和Mapper.xml文件

BlogMapper.java

package com.zql.mapper;

import com.zql.pojo.Blog;

/**
 * @Author:Daniel
 * @Version 1.0
 */
public interface BlogMapper {

    int addBlog(Blog blog);
}

BlogMapper.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.zql.mapper.BlogMapper">

    <insert id="addBlog" parameterType="blog">
        insert into blog (id, title, author, create_time, views) values
        (#{id}, #{title}, #{author}, #{createTime}, #{views})
    </insert>
</mapper>

MyTest.java

package com.zql.mapper;

import com.zql.pojo.Blog;
import com.zql.utils.IDutils;
import com.zql.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.Date;

/**
 * @Author:Daniel
 * @Version 1.0
 */
public class MyTest {

    @Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        Blog blog = new Blog();

        blog.setId(IDutils.getId());
        blog.setTitle("Mybatis");
        blog.setAuthor("Daniel");
        blog.setCreateTime(new Date());
        blog.setViews(9999);

        mapper.addBlog(blog);

        blog.setId(IDutils.getId());
        blog.setTitle("Java");
        mapper.addBlog(blog);

        blog.setId(IDutils.getId());
        blog.setTitle("Spring");
        mapper.addBlog(blog);

        blog.setId(IDutils.getId());
        blog.setTitle("微服务");
        mapper.addBlog(blog);

        sqlSession.close();
    }
}

在这里插入图片描述

1.3 if

if

(1)接口 BlogMapper.java

//使用if 查询博客
List<Blog> queryBlogIf(Map map);

(2)BlogMapper.xml

<select id="queryBlogIf" parameterType="map" resultType="blog">
    select * from blog where 1=1
    <if test="title != null">
        and title=#{title}
    </if>

    <if test="author != null">
        and author=#{author}
    </if>
</select>

(3)MyTest.java

 @Test
 public void queryBlog(){

     SqlSession sqlSession = MybatisUtils.getSqlSession();

     BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

     HashMap<Object, Object> map = new HashMap<>();

     map.put("title","Spring");
     //map.put("author","Daniel");

     List<Blog> blogs = mapper.queryBlogIf(map);

     for (Blog blog : blogs) {

         System.out.println(blog);

     }
     sqlSession.close();
 }

在这里插入图片描述

1.4 choose、when、otherwise

choose、when、otherwise

有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

(1)接口 BlogMapper.java

//choose、when、otherwise
List<Blog> queryBlogChoose(Map map);

(2)BlogMapper.xml

<select id="queryBlogChoose" parameterType="map" resultType="blog">
    select * from blog
      <where>
          <choose>
              <when test="title != null">
                    title=#{title}
              </when>
              <when test="author != null">
                  and author=#{author}
              </when>
              <otherwise>
                  and views=#{views}
              </otherwise>
          </choose>
      </where>
</select>

(3)MyTest.java

@Test
public void queryBlogChoose(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();

    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

    HashMap<Object, Object> map = new HashMap<>();

    map.put("title","Java");
    map.put("author","Daniell");
    map.put("views",9999);

    List<Blog> blogs = mapper.queryBlogChoose(map);

    for (Blog blog : blogs) {

        System.out.println(blog);

    }
    sqlSession.close();
}

在这里插入图片描述

1.5 trim、where、set

trim、where、set

1.5.1 where

(1)接口 BlogMapper.java

//where if  查询博客
List<Blog> queryBlogWhereIf(Map map);

(2)BlogMapper.xml

 <select id="queryBlogWhereIf" parameterType="map" resultType="blog">
     select * from blog
     <where>
         <if test="title != null">
             title=#{title}
         </if>

         <if test="author != null">
            and author=#{author}
         </if>
     </where>
 </select>

(3)MyTest.java

 @Test
 public void queryBlogWhereIf(){
     SqlSession sqlSession = MybatisUtils.getSqlSession();

     BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

     HashMap<Object, Object> map = new HashMap<>();

     map.put("title","Mybatis");
     map.put("author","Daniel");

     List<Blog> blogs = mapper.queryBlogWhereIf(map);

     for (Blog blog : blogs) {

         System.out.println(blog);

     }
     sqlSession.close();
 }

在这里插入图片描述

1.5.2 set

(1) BlogMapper.java

 //set
 int updateBlogSet(Map map);

(2)BlogMapper.xml

<update id="updateBlogSet" parameterType="map">
    update blog
    <set>
        <if test="title != null">
            title =#{title},
        </if>
        <if test="author != null">
            author =#{author}
        </if>
    </set>
    where id=#{id}
</update>

(3)MyTest.java

 @Test
 public void updateBlogSet(){
     SqlSession sqlSession = MybatisUtils.getSqlSession();

     BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

     HashMap<Object, Object> map = new HashMap<>();

     map.put("title","Spring22");

     map.put("id","f5dc243d171c42319a57bcd44ff66cb1");

     int i = mapper.updateBlogSet(map);

     if(i > 0){
         System.out.println("更新成功");
     }
     sqlSession.close();
 }

在这里插入图片描述

  • 所谓的动态SQL,本质还是SQL语句,只是我们可以在SQL层面,去执行一个逻辑代码
if
where,set,choose,when

1.6 sql片段

有的时候,我们可能会将一些功能的部分抽取出来,方便复用!

(1)BlogMapper.java

//where if  查询博客  SQL片段
List<Blog> queryBlogWhereIf(Map map);

(2)BlogMapper.xml

(2.1) 使用SQL标签抽取公共的部分

    <sql id="id-title-author">
        <if test="title != null">
            title=#{title}
        </if>

        <if test="author != null">
            and author=#{author}
        </if>
    </sql>

(2.2) 在需要使用的地方使用include标签引用即可

    <select id="queryBlogWhereIf" parameterType="map" resultType="blog">
        select * from blog
        <where>
            <include refid="id-title-author"></include>
        </where>
    </select>

(3)MyTest.java

@Test
public void queryBlogWhereIf(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();

    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

    HashMap<Object, Object> map = new HashMap<>();

    map.put("title","Mybatis");
    map.put("author","Daniel");

    List<Blog> blogs = mapper.queryBlogWhereIf(map);

    for (Blog blog : blogs) {

        System.out.println(blog);

    }
    sqlSession.close();
}

在这里插入图片描述

注意事项:

  1. 最好基于单表来定义SQL片段!
  2. 不要存在where标签

1.7 foreach

foreach

在这里插入图片描述

(1)BlogMapper.java

//foreach
List<Blog> queryBlogForeach(Map map);

(2)BlogMapper.xml

<!--select * from blog where 1=1 and (id=1 or id=2 or id=3)-->
<select id="queryBlogForeach" parameterType="map" resultType="blog">
    select * from blog
    <where>
        <foreach collection="ids" index="id" open="and (" close=")" separator="or">
            id=#{id}
        </foreach>
    </where>
</select>

(3)MyTest.java

    @Test
    public void queryBlogForeach(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        HashMap<Object, Object> map = new HashMap<>();

        ArrayList<Integer> ids = new ArrayList<Integer>();

        ids.add(1);
        ids.add(2);
        ids.add(3);

        map.put("ids",ids);


        List<Blog> blogs = mapper.queryBlogForeach(map);

        for (Blog blog : blogs) {

            System.out.println(blog);

        }
        sqlSession.close();
    }

在这里插入图片描述

  • 动态SQL就是在拼接SQL语句,我们只要保证SQL的正确性,按照SQL的格式,去排列组合就可以了

建议:

现在Mysql中写出完整的SQL,再对应的去修改成为我们的动态SQL实现通用即可!

二、缓存

缓存中文文档

2.1 缓存简介

  • 查询:连接数据库,耗资源
  • 一次查询的结果,给他暂存在一个可以直接取到的地方!——>内存:缓存
  • 我们再次查询相同数据的时候,直接走缓存,就不用走数据库了

2.1.1 什么是缓存[Cache]?

  • 存在内存中的临时数据。
  • 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。

2.1.2 为什么使用缓存?

减少和数据库的交互次数,减少系统开销,提高系统效率。

2.1.3 什么样的数据能使用缓存?

经常查询并且不经常改变的数据。【可以使用缓存】

2.2 缓存分类

  • MyBatis包含了一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。
  • MyBatis系统中默认定义了两级缓存:一级缓存二级缓存
    – 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
    – 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
    – 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存

2.2.1 一级缓存

  • 一级缓存也叫本地缓存:
    – 与数据库同一次会话期间查询到的数据会放在本地缓存中。
    – 以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库;
2.2.1.1 测试查看

(1)创建子工程
(2)引入依赖
pom.xml

<!--lombok-->
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
        </dependency>
    </dependencies>

    <!--在build中配置resources,来防止我们资源导出失败的问题-->
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>

            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>
        </resources>
    </build>

(3)导入resources文件(db.propertis,mybatis-config.xml)

db.propertis

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?\
  useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username=root
password=root

mybatis-config.xml

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

    <properties resource="db.properties"/>
    
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <typeAliases>
        <package name="com.zql.pojo"></package>
    </typeAliases>

    <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 class="com.zql.mapper.UserMapper"></mapper>
    </mappers>
</configuration>

(4)工具类

MybatisUtils.java

package com.zql.utils;

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 java.io.InputStream;

public class MybatisUtils {

    private static  SqlSessionFactory sqlSessionFactory;

    static {
        try {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //1.Resources获取加载全局配置文件
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession(true);//true自动提交事务
    }
}

(5)实体类
User.java

在这里插入代码片

(6) 接口
UserMapper.java

package com.zql.mapper;

import com.zql.pojo.User;
import org.apache.ibatis.annotations.Param;

/**
 * @Author:Daniel
 * @Version 1.0
 */
public interface UserMapper {

    User getUserById(@Param("id") int id);
}

(7)Mapper.xml 文件
UserMapper.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.zql.mapper.UserMapper">

    <select id="getUserById" resultType="user">
        select * from user where id=#{id}
    </select>

</mapper>

(8)MyTest.java

package com.zql.mapper;

import com.zql.pojo.User;
import com.zql.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

/**
 * @Author:Daniel
 * @Version 1.0
 */
public class MyTest {

    @Test
    public void getUserById(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User userById = mapper.getUserById(1);

        System.out.println(userById);
        System.out.println("===================================");
        User userById2 = mapper.getUserById(1);

        System.out.println(userById2);

        sqlSession.close();
    }
}

测试步骤:

  1. 开启日志!
  2. 测试在一个Session中查询两次相同的记录
  3. 查看日志输出👇🏾👇🏾

在这里插入图片描述

缓存失效的情况:

  1. 查询不同的东西
  2. 增删改操作,可能会改变原来的数据,所以必定会刷新缓存!

在这里插入图片描述

  1. 查询不同的Mapper.xml
  2. 手动清理缓存!

在这里插入图片描述
总结:

一级缓存默认是开启的,只在第一次SqlSession中有效,也就是拿到连接到关闭连接这个区间段!
一级缓存就是一个Map。

2.2.2 二级缓存

2.2.2.1 概述
  • 二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存
  • 基于namespace级别的缓存,一个名称空间,对应一个二级缓存;
  • 工作机制
    – 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
    – 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;
    – 新的会话查询信息,就可以从二级缓存中获取内容;
    – 不同的mapper查出的数据会放在自己对应的缓存(map)中;
2.2.2.1 应用
  1. 开启全局缓存
设置名描述有效值默认值
cacheEnabled全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。true falsetrue

mybatis-config.xml

<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/><!--日志-->
    <setting name="cacheEnabled" value="true"></setting><!--显示的开启全局缓存-->
</settings>
  1. 在要使用二级缓存的Mapper中开启
<!--在当前Mapper.xml中使用二级缓存-->
<cache/>

也可以自定义参数:👇🏾👇🏾

    <!--在当前Mapper.xml中使用二级缓存-->
    <cache
            eviction="FIFO"
            flushInterval="60000"
            size="512"
            readOnly="true"/>

总结:

  1. 只要开启了二级缓存,在同一个Mapper下就有效
  2. 所有的数据都会先放在一级缓存中;
  3. 只有当会话提交,或者关闭的时候,才会提交到二级缓存中!

2.3 缓存原理

缓存原理

在这里插入图片描述

2.4 自定义缓存 - ehcache(拓展)

2.4.1 什么是ehcache?

在这里插入图片描述

2.4.2 ehcache的应用

Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存。

(1)要在程序中使用Ehcache,先要导依赖

<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.1.0</version>
</dependency>

(2)在mapper中指定使用我们的ehcache实现

<!--在当前Mapper.xml中使用二级缓存-->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

(3) 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">

    <diskStore path="./tmpdir/Tmp_EhCache"/>
    <defaultCache
      eternal="false"
      maxElementsInMemory="10000"
      overflowToDisk="false"
      diskPersistent="false"
      timeToIdleSeconds="1800"
      timeToLiveSeconds="259200"
      memoryStoreEvictionPolicy="LRU"/>
    <cache
      name="cloud_user"
      eternal="false"
      maxElementsInMemory="5000"
      overflowToDisk="false"
      diskPersistent="false"
      timeToIdleSeconds="1800"
      timeToLiveSeconds="1800"
      memoryStoreEvictionPolicy="LRU"/>
</ehcache>

(4) 创建一个 public class MyCache implements Ehcache {} 就OK

在这里插入图片描述

文章Mybatis所有源代码

更新进来的,与前面内容无衔接👇👇

三、MyBatis的逆向工程

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

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

准备数据库及表:ssm——> t_emp,t_dept

在这里插入图片描述

在这里插入图片描述

3.1 创建逆向工程的步骤

创建项目:

(1)

在这里插入图片描述

(2)

在这里插入图片描述

  • ① 添加依赖和插件

在这里插入图片描述

<packaging>jar</packaging>

<!-- 依赖MyBatis核心包 -->
<dependencies>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
    </dependency>
    <!-- junit测试 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <!-- log4j日志 -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.16</version>
    </dependency>
</dependencies>
<!-- 控制Maven在构建过程中相关配置 -->
<build>
    <!-- 构建过程中用到的插件 -->
    <plugins>
        <!-- 具体插件,逆向工程的操作是以构建过程中插件形式出现的 -->
        <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.3.0</version>
            <!-- 插件的依赖 -->
            <dependencies>
                <!-- 逆向工程的核心依赖 -->
                <dependency>
                    <groupId>org.mybatis.generator</groupId>
                    <artifactId>mybatis-generator-core</artifactId>
                    <version>1.3.2</version>
                </dependency>
                <!-- MySQL驱动 -->
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>8.0.16</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>
  • ②创建MyBatis的核心配置文件

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<!--properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,
reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?-->
<configuration>

    <properties resource="db.properties">
    </properties>

    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <typeAliases>
        <package name="com.gansu.pojo"></package>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
         <package name="com.gansu.mapper"></package>
    </mappers>
</configuration>
  • ③创建逆向工程的配置文件

文件名必须是: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="MyBatis3">
        <!-- 数据库的连接信息 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/ssm?
serverTimezone=UTC"
                        userId="root"
                        password="root">
        </jdbcConnection>
        <!-- javaBean的生成策略-->
        <javaModelGenerator targetPackage="com.gansu.pojo"
                            targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!-- SQL映射文件的生成策略 -->
        <sqlMapGenerator targetPackage="com.gansu.mapper"
                         targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>
        <!-- Mapper接口的生成策略 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.gansu.mapper" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>
        <!-- 逆向分析的表 -->
        <!-- tableName设置为*号,可以对应所有表,此时不写domainObjectName -->
        <!-- domainObjectName属性指定生成出来的实体类的类名 -->
        <table tableName="t_emp" domainObjectName="Emp"/>
        <table tableName="t_dept" domainObjectName="Dept"/>
    </context>
</generatorConfiguration>

导入xml需要修改的地方:

在这里插入图片描述
在这里插入图片描述

上面报红参考 👉👉一、导入mybatis文件mybatis-config.xml报红

  • ④执行MBG插件的generate目标

在这里插入图片描述

  • ⑤效果

在这里插入图片描述

导入:工具类,日志 👇👇

在这里插入图片描述

SqlSessionUtils

package com.gansu.utils;

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 java.io.IOException;
import java.io.InputStream;

public class SqlSessionUtils {

    public static SqlSession getSqlSession(){

        SqlSession sqlSession = null;
        try {
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");

            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();

            SqlSessionFactory build = sqlSessionFactoryBuilder.build(is);

            sqlSession = build.openSession(true);


        } catch (IOException e) {
            e.printStackTrace();
        }
        return sqlSession;
    }
}

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>

3.2 测试

创建测试类:MbgTest

在这里插入图片描述

import com.gansu.mapper.EmpMapper;
import com.gansu.pojo.Emp;
import com.gansu.pojo.EmpExample;
import com.gansu.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class MbgTest {

    @Test
    public void selectEmpTest(){

        SqlSession sqlSession = SqlSessionUtils.getSqlSession();

        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);

        /*null默认查询全部*/
        /* List<Emp> emps = mapper.selectByExample(null);

        emps.forEach(System.out::println);*/

        //查询带条件的:姓名为张三且年龄大于等于10
        EmpExample empExample = new EmpExample();

        empExample.createCriteria().andEmpNameEqualTo("张三").andEmpAgeGreaterThanOrEqualTo(10);

        empExample.or().andEmpGenderNotEqualTo("女");

        List<Emp> emps = mapper.selectByExample(empExample);

        emps.forEach(System.out::println);
    }
}

四、分页插件

分析:

limit index,pageSize
pageSize:每页显示的条数
pageNum:当前页的页码
index:当前页的起始索引,index=(pageNum-1)*pageSize
count:总记录数
totalPage:总页数
totalPage = count / pageSize;
if(count % pageSize != 0){
totalPage += 1;
}
pageSize=4,pageNum=1,index=0 limit 0,4
pageSize=4,pageNum=3,index=8 limit 8,4
pageSize=4,pageNum=6,index=20 limit 8,4

首页 上一页 2 3 4 5 6 下一页 末页

4.1 分页插件的使用步骤

  • ①添加依赖
    在这里插入图片描述
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.2.0</version>
</dependency>
  • ②配置分页插件

在MyBatis的核心配置文件中配置插件

在这里插入图片描述

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

4.2 分页插件的使用

  • a>在查询功能之前使用PageHelper.startPage(int pageNum, int pageSize)开启分页功能
pageNum:当前页的页码
pageSize:每页显示的条数
  • b>在查询获取list集合之后,使用PageInfo pageInfo = new PageInfo<>(List list, int navigatePages)获取分页相关数据
list:分页之后的数据
navigatePages:导航分页的页码数

在这里插入图片描述

import com.gansu.mapper.EmpMapper;
import com.gansu.pojo.Emp;
import com.gansu.utils.SqlSessionUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.Collections;
import java.util.List;

public class PageTest {

    @Test
    public void pageTestp(){

        SqlSession sqlSession = SqlSessionUtils.getSqlSession();

        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        //开启分页功能
        Page<Object> page = PageHelper.startPage(1, 4);

        List<Emp> emps = mapper.selectByExample(null);

       PageInfo<Emp> pageInfo = new PageInfo<>(5);

      System.out.println(pageInfo);

    }
}
  • c>分页相关数据

pageNum:当前页的页码
pageSize:每页显示的条数
size:当前页显示的真实条数
total:总记录数
pages:总页数
prePage:上一页的页码
nextPage:下一页的页码
isFirstPage/isLastPage:是否为第一页/最后一页
hasPreviousPage/hasNextPage:是否存在上一页/下一页
navigatePages:导航分页的页码数
navigatepageNums:导航分页的页码,[1,2,3,4,5]

源码获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Daniel521-Spark

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值