欢迎您的访问
专注架构,Java,数据结构算法,Python技术分享

SSM第六讲 MyBatis的高级特性

MyBatis的高级特性

1 学习目标

1,理解Mybatis多对多关系

2,掌握Mybatis的延迟加载

3,掌握Mybatis缓存

4,掌握逆向工程生成mapper和实体类

2 Mybatis 延迟加载

2.1 延迟加载介绍

通过前面的学习,我们已经掌握了 Mybatis 中一对一,一对多,多对多关系的配置及实现,可以实现对象的关联查询。实际开发过程中有时候我们并不需要在加载用户信息时,就加载他的账户信息。 而是在使用用户账号的时候,再向数据库查询,此时就是我们所说的延迟加载。

即时加载:

// 条件查询
@Test
public void findAll() throws Exception {
    //  SELECT u.*,a.* FROM USER u LEFT JOIN account a ON a.UID=u.id;
    //  执行userDao.findAll()方法,执行查询用户、账户信息,一次加载所有的数据,这种叫做及时加载。
    List<User> list = userDao.findAll();
    for(User u : list){
        System.out.println(u);
        System.out.println(u.getAccounts());
    }
}

 

2.2 何为延迟加载?

延迟加载:就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载.

好处: 先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。
坏处: 因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时间,所以可能造成用户等待时间变长,造成用户体验下降。

如何实现延迟加载:前面实现多表操作时,我们使用了resultMap 来实现一对一,一对多,多对多关系的操作。主要是通过 association、 collection 实现一对一及一对多映射。 association、 collection 具备延迟加载功能。

思考:什么是及时加载?什么是延时加载?

及时加载:一次加载所有数据。

延迟加载:也叫做懒加载,再需要用到数据时候再查询数据。

2.3 一对一实现延时加载

2.3.1 实现需求

​ 需求:查询Account账户信息时候,也要显示User用户信息,但User用户信息用到的时候再向数据库发送查询语句。

数据库中实现:

-- 一对一延迟加载
-- 需求:查询账户,同时也要显示用户。但用户信息是再用到的时候再查询.
-- 实现过程:
-- 1) 查询账户
SELECT * FROM account
-- 3) 使用用户对象数据时候,查询用户
SELECT * FROM USER WHERE id=46 

 

2.3.2 entity

public class Account {
    private int accountId;
    private int uid;
    private double money;
    // 一个账户对应一个用户
    private User user;
}

 

public class User {
    private int  id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    // 一个用户,对应多个账户
    private List<Account> accounts;
}

 

2.3.3 dao

public interface AccountMapper {
    /**
     * 查询账户
     */
    List<Account> findAll();
}

 

public interface UserMapper {
    /**
     * 根据用户id查询
     */
    User findById(int id);
}

 

2.3.4 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.itdfbz.dao.UserMapper" >
   <select id="findById" resultType="user">
      select * from user where id=#{id}
  </select>
</mapper>

 

2.3.5 AccountMapper.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.itdfbz.dao.AccountMapper">

   <resultMap id="accountResultMap" type="account">
       <!--1. 账户信息映射-->
       <id property="accountId" column="accountId"></id>
       <result property="uid" column="uid"></result>
       <result property="money" column="money"></result>
       <!--2. 延时加载的方式,查询账户的用户-->
       <!--select 延时加载的语句id(名称空间.方法)-->
       <!--column="uid" 表外键字段-->
       <association property="user" javaType="user" column="uid"
                    select="com.itdfbz.dao.UserMapper.findById"></association>
   </resultMap>

   <select id="findAll" resultMap="accountResultMap">
       SELECT * FROM account
   </select>
</mapper>

 

2.3.6 测试,观察问题

@Test
public void test1() {
    AccountMapper accountMapper = session.getMapper(AccountMapper.class);
    List<Account> accountList = accountMapper.findAll();
    for (Account account : accountList) {
        System.out.println(account.getAccountId());
    }
}

 

​ 执行结果:

在这里插入图片描述

​ 发现,我们在测试中,只输出了账户信息,并没有使用用户信息,但还是查询了用户,并没有应用懒加载。如何解决?

2.3.7 解决方案

2.3.7.1 解决1:

查看mybatis官网

http://www.mybatis.org/mybatis-3/zh/configuration.html
  • 1

打开页面,找到settings

在这里插入图片描述

然后在SqlMapConfig.xml中配置开启懒加载支持

在这里插入图片描述

最后,再次执行测试

1.测试类中没有使用Account账户的User信息

@Test
public void find() throws  Exception{
    List<Account> list = accountDao.findAccounts();
    for (Account a : list) { 
        System.out.println(a.getAccountId() + ","+a.getUid() + "," +a.getMoney());
    }
}

 

测试结果

在这里插入图片描述

2.测试类中有使用Account账户的User信息

@Test
public void test1() {
    AccountMapper accountMapper = session.getMapper(AccountMapper.class);
    List<Account> accountList = accountMapper.findAll();
    for (Account account : accountList) {
        System.out.println(account.getAccountId()+"----"+account.getUser());
    }
}

 

测试结果: 可以看到使用对象数据的时候,才向数据库发送查询的SQL
在这里插入图片描述

2.3.7.2 解决2:

(1) 注释SqlMapConfig.xml中全局懒加载的的开启

在这里插入图片描述

(2) 修改映射文件

在这里插入图片描述

通过打印的SQL可以看到,懒加载一样生效:

在这里插入图片描述

2.3.8 小结

通过本示例,我们可以发现 Mybatis 的延迟加载对于提升软件性能这是一个不错的手段。实现的关键: association 的配置

<resultMap id="accountResultMap" type="account">
    <!--1. 账户信息映射-->
    <id property="accountId" column="accountId"></id>
    <result property="uid" column="uid"></result>
    <result property="money" column="money"></result>
    <!--2. 延时加载的方式,查询账户的用户-->
    <!--select 延时加载的语句id(名称空间.方法)-->
    <!--column="uid" 表外键字段(要传入findById方法的参数)-->
    <!--
        fetchType:懒加载设置
            lazy:开启懒加载
            eager:立即加载
    -->
    <association property="user" javaType="user" column="uid" fetchType="lazy"
                 select="com.itdfbz.dao.UserMapper.findById"></association>
</resultMap>

 

2.4 一对多实现延时加载

2.4.1 需求

查询用户信息,再使用用户账户时候再查询账户。

数据库实现:

-- 一对多延迟加载
-- 1) 查询用户
SELECT * FROM USER;
-- 2) 使用用户的账户对象数据时候再查询账户
SELECT * FROM account WHERE uid=46;

 

2.4.2 entity

public class User {
   private Integer id;
   private String username;
   private Date birthday;
   private String sex;
   private String address;
   // 一个用户,对应多个账户
   private List<Account> accounts;
}

 

2.4.3 dao

public interface UserMapper {
    /**
     * 查询所有用户
     */
    List<User> findAll();
}

 

public interface AccountMapper {
    /**
     * 根据用户的id查询
     */
    List<Account> findAccountByUserId(Integer userId);
}

 

2.4.4 AccountMapper.xml

<!--根据用户,查询其下的多个账户-->
<select id="findAccountByUserId" resultType="account">
   select * from account where uid=#{userId}
</select>

 

2.4.5 UserMapper.xml 延时加载关键配置

<resultMap id="userResultMap" type="user">
   <id property="id" column="id"></id>
   <result column="username" property="username"></result>
   <result column="sex" property="sex"></result>
   <result column="address" property="address"></result>

   <!--
       collection:一对多映射
           property:JavaBean中的实体类的多方属性名
           column: 本表的id(要传入findAccountByUserId的参数)
           ofType:属性类型
           select:映射的方法
   -->
   <collection property="accounts" column="id"
               ofType="account"
               select="com.itdfbz.dao.AccountMapper.findAccountByUserId">
   </collection>
</resultMap>
<select id="findAll" resultMap="userResultMap">
   select * from user
</select>

 

2.4.6 开启延时加载支持

在这里插入图片描述

2.4.7 测试

@Test
public void test1() {
    UserMapper userMapper = session.getMapper(UserMapper.class);
    List<User> userList = userMapper.findAll();
    for (User user : userList) {
        System.out.println(user.getSex());
    }
}

 

测试结果:

在这里插入图片描述

// 查询用户
@Test
public void find() throws  Exception{
    List<User> list = userDao.findUsers();
    for (User u : list) {
        System.out.println(u.getId() + "," + u.getUsername());
        System.out.println(u.getAccounts());
    }
}

 

在这里插入图片描述

2.5. 注解实现延迟加载开发

2.5.1 注解实现一对一映射及延迟加载

在这里插入图片描述

2.5.1.1 entity

(1) 账户与用户,一对一

public class Account implements Serializable {
    private int accountId;
    
    private int uid;
    
    private double money;
    
    //一个账号对应一个账户
    private User user;
}

 

(2) 用户与账户,一对多

public class User implements Serializable {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    
    //一个用户对应多个账号
    private List<Account> accountList;
}

 

2.5.1.2 dao

public interface UserMapper {

    // 根据用户id查询
    @Select("select * from user where id=#{id}")
    User findById(int id);
}

 

package com.itdfbz.dao;

import com.itdfbz.entity.Account;
import com.itdfbz.entity.User;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;

public interface AccountMapper {

    /*
    *
    * @One:代表一对一
    * select:要映射到本表属性的数据提供方法
    * user:本类中要映射的属性名
    * uid:外键,要传入findById方法的参数
    * fetchType: 配置懒加载
    *   LAZY:懒加载
    *   EAGER:立即加载
    *
    * */
    @Select("select * from account where accountId=#{id}")
    @Results({
            @Result(id=true,property = "accountId",column = "accountId"),
            @Result(property = "uid",column = "uid"),
            @Result(property = "money",column = "money"),
            @Result(property = "user",column = "uid",javaType = User.class,
                one = @One(select = "com.itdfbz.dao.UserMapper.findById",fetchType = FetchType.EAGER )

            )
    })
    Account findById(Integer id);
}

 

2.5.1.3 测试

@Test
public void test1(){
    AccountMapper mapper = session.getMapper(AccountMapper.class);
    Account account = mapper.findById(1);
    System.out.println(account.getAccountId());
    System.out.println(account.getUser());
}

 

2.5.2 注解实现一对多映射及延迟加载

2.5.1.1 dao 接口

/**
 * many:代表一对多
 * accountList:代表本类中的多方属性名
 * id:要传入findByUserId的参数
 * List.class:多方集合类型
 * FetchType.LAZY:懒加载
 * 
 */
@Select("select * from user where id=#{id}")
@Results({
        @Result(id = true,property = "id",column = "id"),
        @Result(property = "username",column = "username"),
        @Result(property = "birthday",column = "birthday"),
        @Result(property = "sex",column = "sex"),
        @Result(property = "address",column = "address"),
        @Result(property = "accountList",column = "id",javaType = List.class,
                many=@Many(select = "com.itdfbz.dao.AccountMapper.findByUserId",fetchType = FetchType.LAZY)
        )
})

 

2.5.1.2 测试

@Test
public void test2() {
    UserMapper userMapper = session.getMapper(UserMapper.class);

    User user = userMapper.findById(46);
    System.out.println(user.getUsername());
    List<Account> accountList = user.getAccountList();
    for (Account account : accountList) {
        System.out.println(account);
    }

}

 

3 Mybatis 缓存机制

3.1 缓存介绍

像大多数的持久化框架一样, Mybatis 也提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提高性能。Mybatis 中缓存分为一级缓存,二级缓存。

在这里插入图片描述

从图中可以看出什么 ? 一级缓存是基于SqlSessoion的缓存,一级缓存的内容不能跨sqlsession。由mybatis自动维护。二级缓存是基于映射文件的缓存,缓存范围比一级缓存更大。不同的sqlsession可以访问二级缓存的内容。哪些数据放入二级缓存需要自己指定。

3.2 一级缓存测试

同一个SqlSession的一级缓存的测试:

@Test
public void test1() {
    SqlSession session = factory.openSession();

    UserMapper userMapper1 = session.getMapper(UserMapper.class);

    User user1 = userMapper1.findById(41);   //发送sql查询出来,放入一级缓存
    System.out.println(user1.getUsername());
    
    User user2 = userMapper1.findById(41);       //直接从一级缓存中查询(不发送sql)
    System.out.println(user2.getUsername());

    session.close();            //session关闭(此session的一级缓存销毁)

    SqlSession session2 = factory.openSession();
    UserMapper userMapper2 = session2.getMapper(UserMapper.class);
    User user3 = userMapper2.findById(41);          //发送sql查询一级缓存

    System.out.println(user3.getUsername());

}

 

​ 测试结果分析:

在这里插入图片描述

小结

在这里插入图片描述

tips:如果更改了一级缓存中的任何数据那么一级缓存会被清空

3.3 二级缓存

3.3.1 介绍

二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession 的。

二级缓存结构图:

在这里插入图片描述

首先开启 mybatis的二级缓存。
sqlSession1去查询用户信息,查询到用户信息会将查询数据存储到二级缓存中。sqlSession2去查询与 sqlSession1 相同的用户信息, 首先会去缓存中找是否存在数据,如果存在直接从缓存中取出数据。如果 SqlSession3 去执行相同 mapper 映射下 sql,执行 commit 提交, 将会清空该 mapper映射下的二级缓存区域的数据。

3.3.2 测试二级缓存

3.3.2.1 第一步:开启二级缓存

在这里插入图片描述

因为 cacheEnabled 的取值默认就为 true,所以这一步可以省略不配置。为 true代表开启二级缓存;为 false 代表不开启二级缓存。

官网介绍:

在这里插入图片描述

3.3.2.2 第二步:配置mapper

<mapper namespace="com.itdfbz.dao.UserMapper">

    <!--
        cache: 表示当前这个mapper对象的查询结果会放入二级缓存
        userCache: 表示当前sql语句查询结果是否被存入二级缓存(首先应该配置<cache>标签)
            true:存入二级缓存(默认值)
            false:不存入二级缓存
    -->
    <cache></cache>
    <select id="findById" parameterType="int" resultType="user" useCache="true">
        select * from user where id=#{id}
    </select>
</mapper>

 

将 UserMapper.xml 映射文件中的标签中设置 useCache=”true”代表当前这个 statement 要使用二级缓存,如果不使用二级缓存可以设置为 false。
注意: 针对每次查询都需要最新的数据 sql,要设置成useCache=false,禁用二级缓存。

3.3.2.3 第三步:实体类实现Serializable

当我们在使用二级缓存时,所缓存的类一定要实现 java.io.Serializable 接口:
在这里插入图片描述

3.3.2.4 测试

public void test1() throws IOException {

    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");

    SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = builder.build(is);

    SqlSession session1 = factory.openSession();

    UserMapper mapper1 = session1.getMapper(UserMapper.class);

    User user1 = mapper1.findById(41);          //发送sql查询,放入一级缓存
    System.out.println(user1);

    session1.close();           //关闭一级缓存,并将一级缓存的内容写入二级缓存

    SqlSession session2 = factory.openSession();
    UserMapper mapper2 = session2.getMapper(UserMapper.class);

    User user2 = mapper2.findById(41);          //从二级缓存查询(反序列化)直接返回(此时一级缓存还是空的)
    User user3 = mapper2.findById(41);      //查询二级缓存(反序列化)

    System.out.println(user3==user2);       //false

    session2.close();
    is.close();
}

 

测试结果

在这里插入图片描述

二级缓存执行原理:

在这里插入图片描述

tips:如果更改了任何数据那么二级缓存和一级缓存都将被清空

3.4 MyBatis缓存深入

一级缓存测试:

@Test
public void test2() throws IOException {
    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");

    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = builder.build(is);

    SqlSession session1 = factory.openSession();

    UserMapper mapper1 = session1.getMapper(UserMapper.class);

    User user1 = mapper1.findById(41);          //发送sql查询,放入一级缓存
    user1.setAddress("NanChang");
    mapper1.update(user1);              //清空一级缓存 update delete 

    User user2 = mapper1.findById(41);          //再次发送sql

    session1.close();           //关闭一级缓存,并将一级缓存的内容写入二级缓存
}

 

二级缓存测试:

@Test
public void test3() throws IOException {
    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");

    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = builder.build(is);

    SqlSession session1 = factory.openSession();

    UserMapper mapper1 = session1.getMapper(UserMapper.class);

    User user1 = mapper1.findById(41);          //发送sql查询,放入一级缓存
    System.out.println(user1);

    session1.close();           //关闭一级缓存,并将一级缓存的内容写入二级缓存

    SqlSession session2 = factory.openSession();
    UserMapper mapper2 = session2.getMapper(UserMapper.class);

    User user2 = mapper2.findById(41);          //从二级缓存查询(反序列化)直接返回(此时一级缓存还是空的)
    mapper2.update(user2);                      //清空二级缓存、一级缓存

    User user3 = mapper2.findById(41);      //查询二级缓存--->一级缓存--->数据库
    User user4 = mapper2.findById(41);      //查询二级缓存(空的)---->查询一级缓存---返回结果
    System.out.println(user3 == user4);       //true

    session2.close();
    is.close();
}

 

3.5 MyBatis缓存总结

一级缓存和二级缓存的执行顺序为:二级缓存—->一级缓存—->数据库

查询语句始终是由一级缓存发送的

一级缓存默认由MyBatis维护,我们只需了解使用即可

二级缓存需要我们开启:

1、在SqlMapConfig.xml中开启二级缓存(默认开启)

<settings>
    <!--开启二级缓存,默认是开启状态 false为关闭二级缓存-->
    <setting name="cacheEnabled" value="true"/>
</settings>

 

2、在mapper文件中加入标签代表本mapper文件的所有查询结果放入二级缓存,并保证useCache不为false(默认为true)

<cache></cache>
<select id="findById" parameterType="int" resultType="user" useCache="true">
    select * from user where id=#{id}
</select>

 

3、MyBatis的二级缓存默认采用序列化/反序列化来保证对象的存取,所以所有的entity对象都应该实现serializable接口

3.6 mybatis自身缓存的弊

A. 分布式的项目架构下,也就是最少使用两个服务器,如果使用两个服务器mybatis的缓存技术就无法在两个服务器通用就是,也就是两个服务器无法达到数据通用,比如我在一个服务器存储了我的信息,但是我转跳到另一个服务器那使用mybatis数据就是需要从新加载,这里就是一个非常大的问题。

B. mybatis无法实现细粒度的缓存管理,当你查询大量数据的时候而且将数据存储到mybatis二级缓存中的时候,但是一旦队一个数据操作增加,删除,修改,这里二级缓存就全部清空,而mybatis无法实现对这里单个信息的修改

问题:如何解决这个缺陷?

答:使用第三方的缓存如:ehcache、redis

在这里插入图片描述

3.7.ehcache的整合配置

ehcache需要slf4j这个日志包支持

3.7.1.导入包

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

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.25</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.35</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis.caches</groupId>
        <artifactId>mybatis-ehcache</artifactId>
        <version>1.1.0</version>
    </dependency>

 

3.7.2.引入缓存配置文件

classpath下添加:ehcache.xml(EhcacheCache实现类的默认配置文件)

<?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:缓存数据持久化的目录 地址  -->
<diskStore path="F:\temp\cache"/>
<!--
maxElementsInMemory:内存中最大缓存对象数  
    maxElementsOnDisk:磁盘中最大缓存对象数,若是0表示无穷大  
    eternal:Element是否永久有效,一但设置了,timeout将不起作用  
    overflowToDisk:配置此属性,当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中  
    diskPersistent:是否缓存虚拟机重启期数据
    timeToIdleSeconds:设置Element在失效前的允许闲置时间。仅当element不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大  
    timeToLiveSeconds:设置Element在失效前允许存活时间。最大时间介于创建时间和失效时间之间。仅当element不是永久有效时使用,默认是0.,
    也就是element存活时间无穷大   
    memoryStoreEvictionPolicy - 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),
    可选的有LFU(最不常使用)和FIFO(先进先出)
 -->
<defaultCache 
maxElementsInMemory="1000" 
maxElementsOnDisk="10000000" 
eternal="false" 
overflowToDisk="true" 
diskPersistent="false" 
timeToIdleSeconds="120" 
timeToLiveSeconds="120" 
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>

 

3.7.3.开启ehcache缓存

EhcacheCache 是ehcache对Cache接口的实现;修改mapper.xml文件,在cache标签的type属性中指定EhcacheCache。覆盖其默认实现

根据需求调整缓存参数:(根据条件对EhcacheCache实现类的参数调整,可选)

    <cache type="org.mybatis.caches.ehcache.EhcacheCache" >
       <!--最大的空闲时间  -->
       <property name="timeToIdleSeconds" value="10000"/>
       <!-- 最大的在线时间 -->
       <property name="timeToLiveSeconds" value="20000"/>
       <!-- 内存的大小 b字节 m1 =1024k 1k=1024b -->
       <property name="maxEntriesLocalHeap" value="2000000"/>
       <!-- 文件的大小 b字节-->
       <property name="maxEntriesLocalDisk" value="20000000"/>
       <!-- 算法 LRU:最少使用优先, "LFU" or "FIFO:先进先出 -->
       <property name="memoryStoreEvictionPolicy" value="LRU"/>
    </cache> 

 

结果:观察缓存命中,且在写入磁盘配置路径处可以看到生成文件

在这里插入图片描述

4 逆向工程

idea的逆向工程,通过maven的插件来实现

4.1.创建maven项目

在这里插入图片描述

在这里插入图片描述

4.2. 引入插件mybatis-generator-maven-plugin

在maven项目的pom.xml 添加mybatis-generator-maven-plugin 插件

<build>

    <plugins>
        <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.3.2</version>
        </plugin>
    </plugins>
</build>

 

更新下载依赖包

在这里插入图片描述

4.3. generatorConfig.xml

在maven项目下的src/main/resources 目录下建立名为 generatorConfig.xml的配置文件,作为mybatis-generator-maven-plugin 插件的执行目标,模板如下:

<?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>
    <!--引入数据库配置文件以解耦-->
    <properties resource="mybatis.properties"/>
    <!-- mysql jar 文件位置 -->
    <classPathEntry location="D:\.m2\repository\mysql\mysql-connector-java\5.1.35\mysql-connector-java-5.1.35.jar" />
    
    <context id="testTables" targetRuntime="MyBatis3">
        <commentGenerator>
            <!-- 是否去除自动生成的注释,true:是;false:否 -->
            <property name="suppressAllComments" value="true" />
        </commentGenerator>
        <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
        <jdbcConnection driverClass="${jdbc.driver}"
                        connectionURL="${jdbc.url}" userId="${jdbc.username}"
                        password="${jdbc.password}">
        </jdbcConnection>
        <!--Oracle数据库的连接信息-->
        <!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
            connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg"
            userId="yycg"
            password="yycg">
        </jdbcConnection> -->

        <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
            NUMERIC 类型解析为java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!-- targetProject:生成PO类的位置 -->
        <javaModelGenerator targetPackage="cn.nyse.entity"
                            targetProject="src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!-- targetProject:mapper映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="cn.nyse.mapper"
                         targetProject="src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
        </sqlMapGenerator>
        <!--
        targetPackage:mapper接口生成的位置,遵循MyBatis规范,让mapper.xml
        和mapper.java在同一目录下
        ANNOTATEDMAPPER:注解方式
        XMLMAPPER:xml方式
         -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="cn.nyse.mapper"
                             targetProject="src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
        </javaClientGenerator>
        <!-- 指定数据库表 -->
        <table tableName="${jdbc.table.items}"></table>

      

        <!-- 有些表的字段需要指定java类型
         <table schema="" tableName="">
            <columnOverride column="" javaType="" />
        </table> -->
    </context>
</generatorConfiguration>

 

mybatis.properties:

<!--jdbc连接数据库配置信息-->
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/mybatis
jdbc.username = root
jdbc.password = 123456

#数据库中要生成的表
jdbc.table.items = student

 

项目目录如下

在这里插入图片描述

4.4. 使用maven运行mybatis-generator-maven-plugin插件

在这里插入图片描述

观察控制台输出结果:

在这里插入图片描述

生成的文件:

在这里插入图片描述

    <!-- 有些表的字段需要指定java类型
     <table schema="" tableName="">
        <columnOverride column="" javaType="" />
    </table> -->
</context>

 




mybatis.properties:

```properties
<!--jdbc连接数据库配置信息-->
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/mybatis
jdbc.username = root
jdbc.password = 123456

#数据库中要生成的表
jdbc.table.items = student

 

项目目录如下

在这里插入图片描述

4.4. 使用maven运行mybatis-generator-maven-plugin插件

在这里插入图片描述

观察控制台输出结果:

在这里插入图片描述

生成的文件:

在这里插入图片描述

作者:易兮科技 | 来源:https://blog.csdn.net/m0_47157676

赞(0) 打赏
版权归原创作者所有,任何形式转载请联系作者;码农code之路 博客站点 » SSM第六讲 MyBatis的高级特性

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏