whatshotmybatis plus优雅的倔强 数据库操作如此简单

Hik
@Ta 2019-07-06 1447点击

Java目前很多都是ssm框架,m即为mybatis,mybatis plus是国人对歪果的mybatis的加强的一个框架,导入依赖配好配置文件后开箱即用,基础增删改查都封装好了,原mybatis内容无需改变,加强而不侵入。

MyBatis Plus教程

1 Mybatis Plus简介

1.1 Mybatis Plus介绍

Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

我们的愿景是成为 Mybatis 最好的搭档,就像 魂斗罗 中的1P、2P,基友搭配,效率翻倍。

1.2 MP特性

  • 无侵入:Mybatis-Plus 在 Mybatis 的基础上进行扩展,只做增强不做改变,引入 Mybatis-Plus 不会对您现有的 Mybatis 构架产生任何影响,而且 MP 支持所有 Mybatis 原生的特性
  • 依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 预防Sql注入:内置 Sql 注入剥离器,有效预防Sql注入攻击
  • 通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题
  • 支持热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动
  • 支持ActiveRecord:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作
  • 支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用(P.S. 比 Mybatis 官方的 Generator 更加强大!)
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 支持关键词自动转义:支持数据库关键词(order、key......)自动转义,还可自定义关键词
  • 内置分页插件:基于 Mybatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作

1.3 代码托管

官方网站:http://mp.baomidou.com/

Gitee | Github

2 MP快速入门【spring】

2.1 开发环境准备

2.1.1 创建数据库表
DROP TABLE IF EXISTS `tb_customer`;
CREATE TABLE `tb_customer` (
  `id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
  `gender` char(1) DEFAULT NULL,
  `age` int(11) DEFAULT '0',
  `cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
  `cust_phone` varchar(64) DEFAULT NULL COMMENT '固定电话',
  `cust_address` varchar(100) DEFAULT NULL,
  `cust_createtime` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `key_id` (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

INSERT INTO `tb_customer` VALUES ('1', '1', '25', '老黎', '0108888887', '北京三里桥', '2016-04-08 16:32:01');
INSERT INTO `tb_customer` VALUES ('2', '1', '25', '老毕', '0108888887', '北京三里桥', '2016-04-08 16:32:01');
INSERT INTO `tb_customer` VALUES ('3', '1', '25', '刘备', '0108888887', '北京三里桥', '2016-04-08 16:32:01');
INSERT INTO `tb_customer` VALUES ('4', '0', '25', '风清扬', '0108888887', '北京三里桥', '2016-04-08 16:32:02');
INSERT INTO `tb_customer` VALUES ('5', '0', '25', '马化腾', '0108888887', '北京三里桥', '2016-04-08 16:32:03');
INSERT INTO `tb_customer` VALUES ('6', '0', '25', '马云', '0108888887', '北京三里桥', '2016-04-08 16:32:03');
INSERT INTO `tb_customer` VALUES ('7', '0', '25', '马云', '0108888887', '北京三里桥', '2016-04-08 16:32:03');
INSERT INTO `tb_customer` VALUES ('8', '0', '25', '马云', '0108888887', '北京三里桥', '2016-04-08 16:32:03');
INSERT INTO `tb_customer` VALUES ('9', '0', '25', '马云', '0108888887', '北京三里桥', '2016-04-08 16:32:04');
INSERT INTO `tb_customer` VALUES ('10', '1', '25', '令狐冲', '0108888886', '北京三里桥6', '2016-04-08 16:32:04');
2.1.2 创建Maven项目映入依赖
 <dependencies>
        <!-- mp依赖 mybatisPlus 会自动的维护Mybatis 以及MyBatis-spring相关的依赖 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <!--<version>3.0-RELEASE</version>-->
            <version>2.3</version>
        </dependency>
        <!--junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.9</version>
        </dependency>
        <!-- log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- c3p0 -->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>
        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.37</version>
        </dependency>
        <!-- spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.3.10.RELEASE</version>
        </dependency>
    </dependencies>

注意:Mybatis及Mybatis-Spring依赖请勿加入项目配置,以免引起版本冲突Mybatis-Plus会自动帮你维护!

2.1.3 创建实体类
public class Customer {

    private Integer id;
    private Integer gender;
    private Integer age;
    private String custName;
    private String custPhone;
    private String custAddress;
    private Date createtime;
    // get set methods
}
2.1.4 修改配置文件

需要引入数据库的配置文件、spring配置文件、日志文件、mybatis配置文件

Mybatis-Plus 的集成非常简单,对于 Spring,我们仅仅需要把 Mybatis 自带的MybatisSqlSessionFactoryBean替换为 MP 自带的即可。

   <!--  配置SqlSessionFactoryBean 
        Mybatis提供的: org.mybatis.spring.SqlSessionFactoryBean
        MP提供的:com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean
     -->
    <bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
        <!-- 数据源 -->
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        <!-- 别名处理 -->
        <property name="typeAliasesPackage" value="com.itheima.mp.domain"></property>
    </bean>

详细在资料中

2.2 CRUD入门案例

案例入门:以数据库中的 tb_customer表为例,使用MP对数据库进行CRUD的操作。

回忆:原先使用Mybatis的代理模式的操作。

MP:只要在编写一个接口,然后在接口上继承 BaseMapper<T> 即可

/**
 * @author NQ
 * @create 2018-02-30 14:11
 */
public interface CustomerMapper extends BaseMapper<Customer> {

}
2.2.1 插入数据
/**
 * @author NQ
 * @create 2018-02-30 14:14
 */
public class testMapper1 {

    ApplicationContext context =
            new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

    @Test
    public void testInsert(){
        CustomerMapper mapper = context.getBean(CustomerMapper.class);

        Customer customer = new Customer();
        customer.setAge(18);
        customer.setCreatetime(new Date());
        customer.setCustAddress("北京金燕龙");
        customer.setCustPhone("13245678564");
        customer.setCustName("小黑");
        customer.setGender(1);

        int res = mapper.insert(customer);
        System.out.println(res);
    }
}

测试运行后出现以下异常:

分析原因: 当MP对当前记录新增后,不知道当前数据库的ID的主键策略是什么样子的,MP默认会给你生成一个ID,但是它不知道当前生成的ID要封装到实体类中的哪一个属性上。所以出现异常。

解决方案:

MP提供一个注解 @TableId(value = "id",type = IdType.AUTO)

value:如果属性名称和数据库的不一致,可以在此写数据库对应的字段名称

type:标识数据主键生成策略,是一个枚举类型的参数

public enum IdType {
    AUTO(0, "数据库ID自增"),
    INPUT(1, "用户输入ID"),
    ID_WORKER(2, "全局唯一ID"),
    UUID(3, "全局唯一ID"),
    NONE(4, "该类型为未设置主键类型"),
    ID_WORKER_STR(5, "字符串全局唯一ID");
    // .....
}

测试运行,你会发现又报错了,我的天学个东西这么难,还要不要学了啊,不是说比Mybatis简单的吗?强哥你是骗人的吧!!!!

其实没关系,我是故意的 哈哈哈!!

分析原因:报错的是找不到,数据库中的表,通过打印的SQL语句,我们发现他要找 数据库的中的Customer表,我想问 能不能找到,我们数据库的中的表叫做 tb_customer, 所以就报错啦。

解决方案:对咯, 还是注解: @TableName("tb_customer")

/**
 * 数据库表相关
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TableName {

    /**
     * 实体对应的表名
     */
    String value() default "";

    /**
     * 实体映射结果集
     */
    String resultMap() default "";
}

现在先不运行,你想一想现在是不是可以举一反三了呢,也就是说 当数据库的表字段和实体类不一致的情况下我们可以添加注解来解决,所以我们来看一下我们的实体类。所以我们还要在加上一个普通属性的注解 @TableField(value="")

添加后运行测试,哇终于绿了 。。。。心累!

你以为结束了吗? 还没有,大家想一下,我如果要是有100个类,我这样写的话是不是会累死,一天就在写这个配置,工作效率太低了。怎么办呢?? MP提供了一个全局的配置如下:

<!-- 定义MybatisPlus的全局策略配置-->
    <bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
        <!-- 在2.3版本以后,dbColumnUnderline 默认值就是true -->
        <property name="dbColumnUnderline" value="true"></property>

        <!-- 全局的主键策略 -->
        <property name="idType" value="0"></property>

        <!-- 全局的表前缀策略配置 -->
        <property name="tablePrefix" value="tb_"></property>
    </bean>

这样是不是就很完美了呢。

int res = mapper.insertAllColumn(customer);   // 插入所有

2.2.2 更新数据
@Test
public void testUpdate(){
    CustomerMapper mapper = context.getBean(CustomerMapper.class);

    Customer customer = new Customer();
    customer.setAge(38);
    customer.setCreatetime(new Date());
    customer.setCustAddress("北京海淀");
    customer.setCustPhone("13288888888");
    customer.setCustName("小黑");
    customer.setGender(0);

    customer.setId(14);

    int res = mapper.updateById(customer);
    System.out.println(res);
}

以下是MP的update的所有的方法:自己测试

2.2.3 删除数据
@Test
public void  testDele(){
    CustomerMapper mapper = context.getBean(CustomerMapper.class);

    List<Integer> IdList = new ArrayList<Integer>();
    IdList.add(12);
    IdList.add(13);

    Integer res = mapper.deleteBatchIds(IdList);
    System.out.println(res);
}

运行结果如下:

以下是删除所有的方法:其中条件对象稍后去讲解

2.2.4 查询数据

查询一条记录

@Test
public void testFindOne(){
    CustomerMapper mapper = context.getBean(CustomerMapper.class);
    Customer customer = new Customer();
    customer.setId(14);
    customer = mapper.selectOne(customer);   // 接收对象类型
    System.out.println(customer);
}

@Test
public void testFindById(){
    CustomerMapper mapper = context.getBean(CustomerMapper.class);
    Customer customer = mapper.selectById(14);   // 接收id属性
    System.out.println(customer);
}

查询列表

@Test
public void testFindListByMap(){
    CustomerMapper mapper = context.getBean(CustomerMapper.class);
    Map<String, Object> map = new HashMap<String, Object>();

    // 封装条件   必须是数据的字段名称
    map.put("age",25);
    map.put("gender",0);
    map.put("cust_name","马云");

    List<Customer> list = mapper.selectByMap(map);
    for (Customer customer : list) {
        System.out.println(customer);
    }
}

分页查询

@Test
public void testFindListByPage(){
    CustomerMapper mapper = context.getBean(CustomerMapper.class);

    Page<Customer> page = new Page<Customer>(1,3);   // 参数1:当前页  参数2: 一页显示记录数  
    List<Customer> list = mapper.selectPage(page, null);
    for (Customer customer : list) {
        System.out.println(customer);
    }
}

运行结果如下:

注意:当前的分页是基于内存的分页,不是真正的分页。也就是说我们查看sql语句没有看到limit关键字。所以这种分页不推荐使用

以上是基本的 CRUD 操作,如您所见,我们仅仅需要继承一个 BaseMapper 即可实现大部分单表 CRUD 操作。BaseMapper 提供了多达 17 个方法给大家使用, 可以极其方便的实现单一、批量、分页等操作。极大的减少开发负担,难道这就是 MP 的强大之处了吗? 还远远不够。。。

来我们提出一个新的问题:

我们需要分页查询 tb_customer 表中,年龄在 18~50 之间性别为男且姓名为 xx 的所有用户

这时候我们该如何实现上述需求呢?

MyBatis : 需要在 SQL 映射文件中编写带条件查询的 SQL,并基于 PageHelper 插件完成分页. 实现以上一个简单的需求,往往需要我们做很多重复单调的工作。普通的 Mapper能够解决这类痛点吗?
MP: 依旧不用编写 SQL 语句, MP 提供了功能强大的条件构造器 EntityWrapper,下一章我们会独立感受他的强大。

2.2.5 自定义SQL

在接口中写一个findCustByCondition查询方法:

public interface CustomerMapper extends BaseMapper<Customer> {

    List<Customer> findCustByCondition(Customer customer);

}

在对应的扫描包中添加sql语句

<mapper namespace="com.itheima.mp.mapper.CustomerMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.itheima.mp.domain.Customer">
        <id column="id" property="id" />
        <result column="gender" property="gender" />
        <result column="age" property="age" />
        <result column="cust_name" property="custName" />
        <result column="cust_phone" property="custPhone" />
        <result column="cust_address" property="custAddress" />
        <result column="cust_createtime" property="createtime" />
    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, gender, age, cust_name, cust_phone, cust_address, cust_createtime
    </sql>
    
    <select id="findCustByCondition" parameterType="com.itheima.mp.domain.Customer" resultType="com.itheima.mp.domain.Customer">
       SELECT * from tb_customer WHERE id = #{id} or cust_name like '%${custName}%'
    </select>

</mapper>

代码测试:

/**
     * 自定义sql
     */
@Test
public void testSelect() {
    CustomerMapper mapper = context.getBean(CustomerMapper.class);
    Customer customer = new Customer();
    customer.setId(1);
    customer.setCustName("马");
    List<Customer> list = mapper.findCustByCondition(customer);

    for (Customer customer1 : list) {
        System.out.println(customer1);
    }
}

运行结果:

3 EntityWrapper 条件构造器

3.1 EntityWrapper 简介

Mybatis-Plus 通过 EntityWrapper(简称 EW,MP 封装的一个查询条件构造器)或者Condition(与 EW 类似) 来让用户自由的构建查询条件,简单便捷,没有额外的负担,能够有效提高开发效率

实体包装器,主要用于处理 sql 拼接,排序,实体参数查询等

注意: 使用的是数据库的字段,不是java的属性名称

条件参数说明:

查询方式 说明
setSqlSelect 设置 SELECT 查询字段
where WHERE 语句,拼接 + WHERE 条件
and AND 语句,拼接 + AND 字段=值
andNew AND 语句,拼接 + AND (字段=值)
or OR 语句,拼接 + OR 字段=值
orNew OR 语句,拼接 + OR (字段=值)
eq 等于=
allEq 基于 map 内容等于=
ne 不等于<>
gt 大于>
ge 大于等于>=
lt 小于<
le 小于等于<=
like 模糊查询 LIKE
notLike 模糊查询 NOT LIKE
in IN 查询
notIn NOT IN 查询
isNull NULL 值查询
isNotNull IS NOT NULL
groupBy 分组 GROUP BY
having HAVING 关键词
orderBy 排序 ORDER BY
orderAsc ASC 排序 ORDER BY
orderDesc DESC 排序 ORDER BY
exists EXISTS 条件语句
notExists NOT EXISTS 条件语句
between BETWEEN 条件语句
notBetween NOT BETWEEN 条件语句
addFilter 自由拼接 SQL
last 拼接在最后,例如:last("LIMIT 1")

3.2 EntityWrapper 使用

问题:年龄在 18~50 之间性别为男且姓名为 马 的所有用户

/**
 * 年龄在 18~25 之间性别为男且姓名为 马 的所有用户
 */
@Test
public void testFindListEntityWrapper(){
    CustomerMapper mapper = context.getBean(CustomerMapper.class);

    EntityWrapper<Customer> entityWrapper = new EntityWrapper<Customer>();
    entityWrapper.between("age",18,25)
            .eq("gender",0)
            .like("cust_name","马");
    Page<Customer> page = new Page<Customer>(1,30);
    List<Customer> list = mapper.selectPage(page, entityWrapper);
    for (Customer customer : list) {
        System.out.println(customer);
    }
}

运行结果,观察SQL语句:

方式2: 年龄在 18~50 之间性别为男 或者 姓名为 黑 的所有用户

/**
     * 年龄在 18~50 之间性别为男  或者 姓名为 黑 的所有用户
     */
@Test
public void testFindListEntityWrapper2() {
    CustomerMapper mapper = context.getBean(CustomerMapper.class);

    Page<Customer> page = new Page<Customer>(1, 30);

    List<Customer> list = mapper.selectPage(page,
                                            Condition.create()
                                            .between("age",18,25)
                                            .eq("gender",0)
                                            .or()   // .orNew()
                                            .like("cust_name","黑"));
    for (Customer customer : list) {
        System.out.println(customer);
    }
}

EntityWrapper 对象 除可以查询操作外,还可以按照条件 修改和删除, 此处不做扩展,自己可以尝试编写代码测试

4 ActiveRecord【活动记录】

1562087025819

Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。ActiveRecord 一直广受动态语言( PHP 、 Ruby 等)的喜爱,而 Java 作为准静态语言,对于 ActiveRecord 往往只能感叹其优雅,所以 MP 也在 AR 道路上进行了一定的探索

4.1 插入数据

4.2 更新数据

4.3 删除数据

4.4 查询数据

5 代码生成器使用

在代码生成之前,首先进行配置,MP提供了大量的自定义设置,生成的代码完全能够满足各类型的需求,如果你发现配置不能满足你的需求,欢迎提交issue和pull-request,有兴趣的也可以查看源码进行了解。

默认配置,懒人直达电梯

MP 的代码生成器 和 Mybatis MBG 代码生成器区别:
MP 的代码生成器都是基于 java 代码来生成。MBG 基于 xml 文件进行代码生成
MyBatis 的代码生成器可生成: 实体类、Mapper 接口、Mapper 映射文件
MP 的代码生成器可生成: 实体类(可以选择是否支持 AR)、Mapper 接口、Mapper 映射文件、 Service 层、 Controller 层.

MP支持以下4中主键策略,可根据需求自行选用:

描述
IdType.AUTO 数据库ID自增
IdType.INPUT 用户输入ID
IdType.ID_WORKER 全局唯一ID,内容为空自动填充(默认配置)
IdType.UUID 全局唯一ID,内容为空自动填充

IdType.ID_WORKER简单来说就是一个分布式高效有序ID生产黑科技工具,思路主要是来源于Twitter-Snowflake算法

在MP中,我们建议数据库表名表字段名采用驼峰命名方式, 如果采用下划线命名方式 请开启全局下划线开关,如果表名字段名命名方式不一致请注解指定,我们建议最好保持一致。

这么做的原因是为了避免在对应实体类时产生的性能损耗,这样字段不用做映射就能直接和实体类对应。当然如果项目里不用考虑这点性能损耗,那么你采用下滑线也是没问题的,只需要在生成代码时配置dbColumnUnderline属性就可以。

5.1 添加依赖

<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.0</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.7</version>
 </dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.7</version>
</dependency>

5.2 官网代码:

package com.itheima.mp;

import com.baomidou.mybatisplus.enums.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.DbType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

/**
 * @author NQ
 * @create 2018-03-30 19:07
 */
public class GeneratorMP {

    public static void main(String[] args) {
        String packageName = "com.itheima.mp";   // 生成的包名
        boolean serviceNameStartWithI = false;//user -> UserService, 设置成true: user -> IUserService

        String dir = "D:\\develop\\work\\workspace-ssm\\mybatis_plus\\mp_generator\\src\\main\\java";

        generateByTables(serviceNameStartWithI,
                packageName,
                dir, "user", "tb_customer","orders");
    }

    private static void generateByTables(boolean serviceNameStartWithI, String packageName, String dir, String... tableNames) {
        GlobalConfig config = new GlobalConfig();

        // 数据库相关信息
        String dbUrl = "jdbc:mysql://localhost:3306/mybatis";
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL)
                .setUrl(dbUrl)
                .setUsername("root")
                .setPassword("root")
                .setDriverName("com.mysql.jdbc.Driver");

        // 策略配置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig
                .setCapitalMode(true)   // 全局大写命名
                .setEntityLombokModel(false)   // Lomnok
                .setDbColumnUnderline(true)   // 表名 字段名 是否使用下滑线命名
                .setTablePrefix("tb_") // 去除表前缀
                .setRestControllerStyle(true)
                .setNaming(NamingStrategy.underline_to_camel) //// underline_to_camel数据库表映射到实体的命名策略
                .setInclude(tableNames);//修改替换成你需要的表名,多个表名传数组

        // 全局配置
        config.setActiveRecord(false)   //是否支持AR模式
                .setAuthor("NQ")   // 设置作者
                .setOutputDir(dir)   // 设置生成的目标路径(绝对路径)
                .setIdType(IdType.AUTO) //主键策略
                .setBaseColumnList(true)  // 设置sql片段
                .setBaseResultMap(true)  // resultMap
                .setEnableCache(false)   // 不开缓存
                .setMapperName("%sMapper")
                .setXmlName("%sMapper")
                .setFileOverride(true);  // 每一次生成需要覆盖
        if (!serviceNameStartWithI) {
            config.setServiceName("%sService");
        }
        new AutoGenerator().setGlobalConfig(config)
                .setDataSource(dataSourceConfig)
                .setStrategy(strategyConfig)
                .setPackageInfo(
                        new PackageConfig()
                                .setParent(packageName)
                                .setController("controller")
                                .setEntity("entity")
                ).execute();
    }

    private void generateByTables(String packageName, String dir,String... tableNames) {
        generateByTables(true, packageName, dir, tableNames);
    }
}

5.3 生成代码说明

EmployeeServiceImpl 继承了 ServiceImpl 类,mybatis-plus 通过这种方式为我们注入了 EmployeeMapper,这样可以使用 service 层默认为我们提供的很多方法,也可以调用我们自己在 dao 层编写的操作数据库的方法.

官方还提供Maven插件的形式地址:https://gitee.com/baomidou/mybatisplus-maven-plugin

6 常用插件扩展

6.1 分页插件

原先我们操作mybatis的分页是有以下几种解决方案:

  • 自定义查询语句分页(自己写sql/mapper)
  • spring 注入 mybatis 配置分页插件Pagehelper

在MP中也给我们提供了一个强大的分页操作的插件,没有任何代码的侵入,直接配置即可。

在applicationContext.xml配置文件中的sqlSessionFactoryBean添加一个plugins属性

       <!--配置分页插件-->
        <property name="plugins">
            <array>
                <!--分页插件-->
                <bean id="paginationInterceptor" class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></bean>
            </array>
        </property>

代码测试

@Test
public void testPage() {
    CustomerMapper mapper = context.getBean(CustomerMapper.class);
    List<Customer> customers = mapper.selectPage(new Page<Customer>(3, 2), null);
    for (Customer customer : customers) {
        System.out.println(customer);
    }
}

运行测试:可以看到原先做过方法分页是不带Limit的现在就已经出现了分页的SQL

6.2 执行分析插件

SQL 执行分析拦截器【 目前只支持 MYSQL-5.6.3 以上版本 】,作用是分析 处理 DELETE UPDATE 语句, 防止小白或者恶意 delete update 全表操作! 如果当前配置了这个插件,那么删除所有的操作将会失效

<!--配置分页插件-->
<property name="plugins">
    <array>
        <!--分页插件-->
        <bean id="paginationInterceptor" class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></bean>
        
          <!--执行分析插件-->
        <bean id="sqlExplainInterceptor" class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
         <!-- SQL 执行分析拦截器 stopProceed 发现全表执行 delete update 是否停止运行 -->
         <property name="stopProceed" value="true" />
        </bean>
    </array>
</property>

注意:

  • 参数:stopProceed 发现执行全表 delete update 语句是否停止执行
  • 注意!该插件只用于开发环境,不建议生产环境使用

6.3 性能分析插件

性能分析拦截器,用于输出每条 SQL 语句及其执行时间 , 如果执行时间超过预设的时间后,当前执行的方法的SQL就不会被执行。可以作为检测慢查询SQL使用。

<!--配置分页插件-->
<property name="plugins">
    <array>
        <bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
              <property name="maxTime" value="100" />
              <!--SQL是否格式化 默认false-->
             <property name="format" value="true" />
          </bean>
    </array>
</property>

代码测试

@Test
public void testPage() {
    CustomerMapper mapper = context.getBean(CustomerMapper.class);
    List<Customer> customers = mapper.selectPage(new Page<Customer>(3, 2), null);
    for (Customer customer : customers) {
        System.out.println(customer);
    }
}

结果

6.4 乐观锁插件

意图:

当要更新一条记录的时候,希望这条记录没有被别人更新

乐观锁实现方式:

  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执行更新时, set version = yourVersion+1 where version = yourVersion
  • 如果version不对,就更新失败

乐观锁配置需要2步 记得两步

第一步:配置插件

<!--配置分页插件-->
<property name="plugins">
    <array>
        <bean class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor"/>
    </array>
</property>

第二步:在实体类中添加一个新的字段 如 version属性

public class User {

    @Version
    private Integer version;
    // set get
    ...
}

注意:仅支持int,Integer,long,Long,Date,Timestamp

其他相关插件,请查询官网,按照这种学习方式,自己自学。

7 自定义全局配置

根据 MybatisPlus 的 AutoSqlInjector 可以自定义各种你想要的 sql ,注入到全局中,相当于自定义 Mybatisplus 自动注入的方法。
之前需要在 xml 中进行配置的 SQL 语句,现在通过扩展 AutoSqlInjector 在加载 mybatis 环境时就注入。

8 MP集成SpringBoot

spring boot 项目集成mp可以使用starter

8.1 引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>mp_springboot</artifactId>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <mybatis-plus-boot-starter.version>2.3</mybatis-plus-boot-starter.version>
        <HikariCP.version>3.2.0</HikariCP.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>
        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>${HikariCP.version}</version>
        </dependency>

        <!-- mybatis-plus begin -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus-boot-starter.version}</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
        <!-- mybatis-plus end -->
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

8.2 application.yml配置文件

mybatis-plus:
  # 如果是放在src/main/java目录下 classpath:/com/yourpackage/*/mapper/*Mapper.xml
  # 如果是放在resource目录 classpath:/mapper/*Mapper.xml
  mapper-locations: classpath:com/itheima/mp/mapper/*Mapper.xml
  #实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: com.itheima.mp.entity
  global-config:
    #主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
    id-type: 0
    #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
    field-strategy: 2
    #驼峰下划线转换
    db-column-underline: true
    #mp2.3+ 全局表前缀 mp_
    #table-prefix: mp_
    #刷新mapper 调试神器
    #refresh-mapper: true
    #数据库大写下划线转换
    capital-mode: true
    # Sequence序列接口实现类配置
#    key-generator: com.baomidou.mybatisplus.incrementer.OracleKeyGenerator
    #逻辑删除配置(下面3个配置)
#    logic-delete-value: 1
#    logic-not-delete-value: 0
#    sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
    #自定义填充策略接口实现
#    meta-object-handler: com.baomidou.springboot.MyMetaObjectHandler
  configuration:
    #配置返回数据库(column下划线命名&&返回java实体是驼峰命名),自动匹配无需as(没开启这个,SQL需要写as: select user_id as userId)
    map-underscore-to-camel-case: true
    cache-enabled: false
    #配置JdbcTypeForNull, oracle数据库必须配置
    jdbc-type-for-null: 'null'
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: root
##logging
logging:
  com.level: debug

springboot2.0之后必须开启log日志

使用代码生成器生成Pojo、mapper、service、controller 等

8.3 编写启动类Application

@EnableTransactionManagement
@SpringBootApplication
//@ComponentScan(basePackages = {
//        "com.baomidou.springboot.config",
//        "com.baomidou.springboot.controller",
//        "com.baomidou.springboot.service"})
public class Application {

    protected final static Logger logger = LoggerFactory.getLogger(Application.class);

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Application.class);
        app.setBannerMode(Banner.Mode.OFF);
        app.run(args);
        logger.info("PortalApplication is success!");
        System.err.println("sample started. http://localhost:8080/user/");
    }

}

8.4 加入相关插件配置

package com.itheima.mp.config;

import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
//@MapperScan("com.baomidou.springboot.mapper*")//这个注解,作用相当于下面的@Bean MapperScannerConfigurer,2者配置1份即可
public class MybatisPlusConfig {

    /**
     * mybatis-plus分页插件<br>
     * 文档:http://mp.baomidou.com<br>
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        return paginationInterceptor;
    }

    /**
     * 相当于顶部的:
     * {@code @MapperScan("com.baomidou.springboot.mapper*")}
     * 这里可以扩展,比如使用配置文件来配置扫描Mapper的路径
     */
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer scannerConfigurer = new MapperScannerConfigurer();
        scannerConfigurer.setBasePackage("com.itheima.mp.mapper*");
        return scannerConfigurer;
    }

//    @Bean
//    public H2KeyGenerator getH2KeyGenerator() {
//        return new H2KeyGenerator();
//    }

    /**
     * 性能分析拦截器,不建议生产使用
     */
    @Bean
    public PerformanceInterceptor performanceInterceptor(){
        PerformanceInterceptor interceptor = new PerformanceInterceptor();
        interceptor.setFormat(true);
        interceptor.setMaxTime(10000);

        return interceptor;
    }

//    public SqlExplainInterceptor sqlExplainInterceptor(){
//        return new SqlExplainInterceptor();
//    }
    
}

注意:代码生成器中没有在mapper上加注解,导致无法完成注入操作。所以需要我们自己去加上注解 @Mapper

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author NQ
 * @since 2018-08-30
 */
@Mapper
public interface UserMapper extends BaseMapper<User> {

}

8.5 编写Controller

/**
 *  前端控制器
 *
 * @author NQ
 * @since 2018-08-30
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 代码生成器测试查询全部
     * @return
     */
    @GetMapping("findAll")
    public List<User> findAll(){
        return userService.selectList(null);
    }

    @GetMapping("findOne")
    public User findOne(Integer id){
        return userService.selectById(id);
    }

    /**
     * 分页测试
     * @param page
     * @param size
     * @return
     */
    @GetMapping("findPage")
    public Page<User> findPage(Integer page,Integer size){
        Page<User> userPage = userService.selectPage(new Page<>(page, size));
        long total = userPage.getTotal();
        System.out.println(total);
        return userPage;
    }

    /**
     * mybatis注解使用测试
     * @return
     */
    @GetMapping("findByQuery")
    public List<User> findByQuery(){
        return userService.findByQuery();
    }

}

启动引导类测试。

9 Idea快速开发插件

  • 官方安装: File -> Settings -> Plugins -> Browse Repositories.. 输入 mybatisx 安装下载

    网络问题可能会下载失败

  • Jar 安装: File -> Settings -> Plugins -> Install plugin from disk.. 选中 mybatisx..jar 安装

MybatisX 源码

回复列表(11)
  • 1
    @Ta / 2019-07-06

    Java目前很多都是ssm框架,m即为mybatis,mybatis plus是国人对歪果的mybatis的加强的一个框架,导入依赖配好配置文件后开箱即用,基础增删改查都封装好了,原mybatis内容无需改变,加强而不侵入。

    MyBatis Plus教程

    1 Mybatis Plus简介

    1.1 Mybatis Plus介绍

    Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

    我们的愿景是成为 Mybatis 最好的搭档,就像 魂斗罗 中的1P、2P,基友搭配,效率翻倍。

    1.2 MP特性

    • 无侵入:Mybatis-Plus 在 Mybatis 的基础上进行扩展,只做增强不做改变,引入 Mybatis-Plus 不会对您现有的 Mybatis 构架产生任何影响,而且 MP 支持所有 Mybatis 原生的特性
    • 依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring
    • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
    • 预防Sql注入:内置 Sql 注入剥离器,有效预防Sql注入攻击
    • 通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
    • 多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题
    • 支持热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动
    • 支持ActiveRecord:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作
    • 支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用(P.S. 比 Mybatis 官方的 Generator 更加强大!)
    • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
    • 支持关键词自动转义:支持数据库关键词(order、key......)自动转义,还可自定义关键词
    • 内置分页插件:基于 Mybatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询
    • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询
    • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作

    1.3 代码托管

    官方网站:http://mp.baomidou.com/

    Gitee | Github

    2 MP快速入门【spring】

    2.1 开发环境准备

    2.1.1 创建数据库表
    DROP TABLE IF EXISTS `tb_customer`;
    CREATE TABLE `tb_customer` (
      `id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
      `gender` char(1) DEFAULT NULL,
      `age` int(11) DEFAULT '0',
      `cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
      `cust_phone` varchar(64) DEFAULT NULL COMMENT '固定电话',
      `cust_address` varchar(100) DEFAULT NULL,
      `cust_createtime` datetime DEFAULT NULL COMMENT '创建时间',
      PRIMARY KEY (`id`),
      UNIQUE KEY `key_id` (`id`) USING BTREE
    ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
    
    INSERT INTO `tb_customer` VALUES ('1', '1', '25', '老黎', '0108888887', '北京三里桥', '2016-04-08 16:32:01');
    INSERT INTO `tb_customer` VALUES ('2', '1', '25', '老毕', '0108888887', '北京三里桥', '2016-04-08 16:32:01');
    INSERT INTO `tb_customer` VALUES ('3', '1', '25', '刘备', '0108888887', '北京三里桥', '2016-04-08 16:32:01');
    INSERT INTO `tb_customer` VALUES ('4', '0', '25', '风清扬', '0108888887', '北京三里桥', '2016-04-08 16:32:02');
    INSERT INTO `tb_customer` VALUES ('5', '0', '25', '马化腾', '0108888887', '北京三里桥', '2016-04-08 16:32:03');
    INSERT INTO `tb_customer` VALUES ('6', '0', '25', '马云', '0108888887', '北京三里桥', '2016-04-08 16:32:03');
    INSERT INTO `tb_customer` VALUES ('7', '0', '25', '马云', '0108888887', '北京三里桥', '2016-04-08 16:32:03');
    INSERT INTO `tb_customer` VALUES ('8', '0', '25', '马云', '0108888887', '北京三里桥', '2016-04-08 16:32:03');
    INSERT INTO `tb_customer` VALUES ('9', '0', '25', '马云', '0108888887', '北京三里桥', '2016-04-08 16:32:04');
    INSERT INTO `tb_customer` VALUES ('10', '1', '25', '令狐冲', '0108888886', '北京三里桥6', '2016-04-08 16:32:04');
    
    2.1.2 创建Maven项目映入依赖
     <dependencies>
            <!-- mp依赖 mybatisPlus 会自动的维护Mybatis 以及MyBatis-spring相关的依赖 -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus</artifactId>
                <!--<version>3.0-RELEASE</version>-->
                <version>2.3</version>
            </dependency>
            <!--junit -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.9</version>
            </dependency>
            <!-- log4j -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
            <!-- c3p0 -->
            <dependency>
                <groupId>com.mchange</groupId>
                <artifactId>c3p0</artifactId>
                <version>0.9.5.2</version>
            </dependency>
            <!-- mysql -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.37</version>
            </dependency>
            <!-- spring -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>4.3.10.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-orm</artifactId>
                <version>4.3.10.RELEASE</version>
            </dependency>
        </dependencies>
    

    注意:Mybatis及Mybatis-Spring依赖请勿加入项目配置,以免引起版本冲突Mybatis-Plus会自动帮你维护!

    2.1.3 创建实体类
    public class Customer {
    
        private Integer id;
        private Integer gender;
        private Integer age;
        private String custName;
        private String custPhone;
        private String custAddress;
        private Date createtime;
        // get set methods
    }
    
    2.1.4 修改配置文件

    需要引入数据库的配置文件、spring配置文件、日志文件、mybatis配置文件

    Mybatis-Plus 的集成非常简单,对于 Spring,我们仅仅需要把 Mybatis 自带的MybatisSqlSessionFactoryBean替换为 MP 自带的即可。

    <!--  配置SqlSessionFactoryBean 
    Mybatis提供的: org.mybatis.spring.SqlSessionFactoryBean
    MP提供的:com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean
     -->
    <bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
    <!-- 数据源 -->
    <property name="dataSource" ref="dataSource"></property>
    <property name="configLocation" value="classpath:mybatis-config.xml"></property>
    <!-- 别名处理 -->
    <property name="typeAliasesPackage" value="com.itheima.mp.domain"></property>
    </bean>
    

    详细在资料中

    2.2 CRUD入门案例

    案例入门:以数据库中的 tb_customer表为例,使用MP对数据库进行CRUD的操作。

    回忆:原先使用Mybatis的代理模式的操作。

    MP:只要在编写一个接口,然后在接口上继承 BaseMapper<T> 即可

    /**
     * @author NQ
     * @create 2018-02-30 14:11
     */
    public interface CustomerMapper extends BaseMapper<Customer> {
    
    }
    
    2.2.1 插入数据
    /**
     * @author NQ
     * @create 2018-02-30 14:14
     */
    public class testMapper1 {
    
        ApplicationContext context =
                new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    
        @Test
        public void testInsert(){
            CustomerMapper mapper = context.getBean(CustomerMapper.class);
    
            Customer customer = new Customer();
            customer.setAge(18);
            customer.setCreatetime(new Date());
            customer.setCustAddress("北京金燕龙");
            customer.setCustPhone("13245678564");
            customer.setCustName("小黑");
            customer.setGender(1);
    
            int res = mapper.insert(customer);
            System.out.println(res);
        }
    }
    

    测试运行后出现以下异常:

    分析原因: 当MP对当前记录新增后,不知道当前数据库的ID的主键策略是什么样子的,MP默认会给你生成一个ID,但是它不知道当前生成的ID要封装到实体类中的哪一个属性上。所以出现异常。

    解决方案:

    MP提供一个注解 @TableId(value = "id",type = IdType.AUTO)

    value:如果属性名称和数据库的不一致,可以在此写数据库对应的字段名称

    type:标识数据主键生成策略,是一个枚举类型的参数

    public enum IdType {
        AUTO(0, "数据库ID自增"),
        INPUT(1, "用户输入ID"),
        ID_WORKER(2, "全局唯一ID"),
        UUID(3, "全局唯一ID"),
        NONE(4, "该类型为未设置主键类型"),
        ID_WORKER_STR(5, "字符串全局唯一ID");
        // .....
    }
    

    测试运行,你会发现又报错了,我的天学个东西这么难,还要不要学了啊,不是说比Mybatis简单的吗?强哥你是骗人的吧!!!!

    其实没关系,我是故意的 哈哈哈!!

    分析原因:报错的是找不到,数据库中的表,通过打印的SQL语句,我们发现他要找 数据库的中的Customer表,我想问 能不能找到,我们数据库的中的表叫做 tb_customer, 所以就报错啦。

    解决方案:对咯, 还是注解: @TableName("tb_customer")

    /**
     * 数据库表相关
     */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface TableName {
    
        /**
         * 实体对应的表名
         */
        String value() default "";
    
        /**
         * 实体映射结果集
         */
        String resultMap() default "";
    }
    
    

    现在先不运行,你想一想现在是不是可以举一反三了呢,也就是说 当数据库的表字段和实体类不一致的情况下我们可以添加注解来解决,所以我们来看一下我们的实体类。所以我们还要在加上一个普通属性的注解 @TableField(value="")

    添加后运行测试,哇终于绿了 。。。。心累!

    你以为结束了吗? 还没有,大家想一下,我如果要是有100个类,我这样写的话是不是会累死,一天就在写这个配置,工作效率太低了。怎么办呢?? MP提供了一个全局的配置如下:

    <!-- 定义MybatisPlus的全局策略配置-->
    <bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
    <!-- 在2.3版本以后,dbColumnUnderline 默认值就是true -->
    <property name="dbColumnUnderline" value="true"></property>
    
    <!-- 全局的主键策略 -->
    <property name="idType" value="0"></property>
    
    <!-- 全局的表前缀策略配置 -->
    <property name="tablePrefix" value="tb_"></property>
    </bean>
    
    

    这样是不是就很完美了呢。

    int res = mapper.insertAllColumn(customer);   // 插入所有
    
    
    2.2.2 更新数据
    @Test
    public void testUpdate(){
        CustomerMapper mapper = context.getBean(CustomerMapper.class);
    
        Customer customer = new Customer();
        customer.setAge(38);
        customer.setCreatetime(new Date());
        customer.setCustAddress("北京海淀");
        customer.setCustPhone("13288888888");
        customer.setCustName("小黑");
        customer.setGender(0);
    
        customer.setId(14);
    
        int res = mapper.updateById(customer);
        System.out.println(res);
    }
    
    

    以下是MP的update的所有的方法:自己测试

    2.2.3 删除数据
    @Test
    public void  testDele(){
        CustomerMapper mapper = context.getBean(CustomerMapper.class);
    
        List<Integer> IdList = new ArrayList<Integer>();
        IdList.add(12);
        IdList.add(13);
    
        Integer res = mapper.deleteBatchIds(IdList);
        System.out.println(res);
    }
    
    

    运行结果如下:

    以下是删除所有的方法:其中条件对象稍后去讲解

    2.2.4 查询数据

    查询一条记录

    @Test
    public void testFindOne(){
        CustomerMapper mapper = context.getBean(CustomerMapper.class);
        Customer customer = new Customer();
        customer.setId(14);
        customer = mapper.selectOne(customer);   // 接收对象类型
        System.out.println(customer);
    }
    
    @Test
    public void testFindById(){
        CustomerMapper mapper = context.getBean(CustomerMapper.class);
        Customer customer = mapper.selectById(14);   // 接收id属性
        System.out.println(customer);
    }
    
    

    查询列表

    @Test
    public void testFindListByMap(){
        CustomerMapper mapper = context.getBean(CustomerMapper.class);
        Map<String, Object> map = new HashMap<String, Object>();
    
        // 封装条件   必须是数据的字段名称
        map.put("age",25);
        map.put("gender",0);
        map.put("cust_name","马云");
    
        List<Customer> list = mapper.selectByMap(map);
        for (Customer customer : list) {
            System.out.println(customer);
        }
    }
    
    

    分页查询

    @Test
    public void testFindListByPage(){
        CustomerMapper mapper = context.getBean(CustomerMapper.class);
    
        Page<Customer> page = new Page<Customer>(1,3);   // 参数1:当前页  参数2: 一页显示记录数  
        List<Customer> list = mapper.selectPage(page, null);
        for (Customer customer : list) {
            System.out.println(customer);
        }
    }
    
    

    运行结果如下:

    注意:当前的分页是基于内存的分页,不是真正的分页。也就是说我们查看sql语句没有看到limit关键字。所以这种分页不推荐使用

    以上是基本的 CRUD 操作,如您所见,我们仅仅需要继承一个 BaseMapper 即可实现大部分单表 CRUD 操作。BaseMapper 提供了多达 17 个方法给大家使用, 可以极其方便的实现单一、批量、分页等操作。极大的减少开发负担,难道这就是 MP 的强大之处了吗? 还远远不够。。。

    来我们提出一个新的问题:

    我们需要分页查询 tb_customer 表中,年龄在 18~50 之间性别为男且姓名为 xx 的所有用户

    这时候我们该如何实现上述需求呢?

    MyBatis : 需要在 SQL 映射文件中编写带条件查询的 SQL,并基于 PageHelper 插件完成分页. 实现以上一个简单的需求,往往需要我们做很多重复单调的工作。普通的 Mapper能够解决这类痛点吗?
    MP: 依旧不用编写 SQL 语句, MP 提供了功能强大的条件构造器 EntityWrapper,下一章我们会独立感受他的强大。

    2.2.5 自定义SQL

    在接口中写一个findCustByCondition查询方法:

    public interface CustomerMapper extends BaseMapper<Customer> {
    
        List<Customer> findCustByCondition(Customer customer);
    
    }
    
    

    在对应的扫描包中添加sql语句

    <mapper namespace="com.itheima.mp.mapper.CustomerMapper">
    
        <!-- 通用查询映射结果 -->
        <resultMap id="BaseResultMap" type="com.itheima.mp.domain.Customer">
            <id column="id" property="id" />
            <result column="gender" property="gender" />
            <result column="age" property="age" />
            <result column="cust_name" property="custName" />
            <result column="cust_phone" property="custPhone" />
            <result column="cust_address" property="custAddress" />
            <result column="cust_createtime" property="createtime" />
        </resultMap>
    
        <!-- 通用查询结果列 -->
        <sql id="Base_Column_List">
            id, gender, age, cust_name, cust_phone, cust_address, cust_createtime
        </sql>
        
        <select id="findCustByCondition" parameterType="com.itheima.mp.domain.Customer" resultType="com.itheima.mp.domain.Customer">
           SELECT * from tb_customer WHERE id = #{id} or cust_name like '%${custName}%'
        </select>
    
    </mapper>
    
    

    代码测试:

    /**
         * 自定义sql
         */
    @Test
    public void testSelect() {
        CustomerMapper mapper = context.getBean(CustomerMapper.class);
        Customer customer = new Customer();
        customer.setId(1);
        customer.setCustName("马");
        List<Customer> list = mapper.findCustByCondition(customer);
    
        for (Customer customer1 : list) {
            System.out.println(customer1);
        }
    }
    
    

    运行结果:

    3 EntityWrapper 条件构造器

    3.1 EntityWrapper 简介

    Mybatis-Plus 通过 EntityWrapper(简称 EW,MP 封装的一个查询条件构造器)或者Condition(与 EW 类似) 来让用户自由的构建查询条件,简单便捷,没有额外的负担,能够有效提高开发效率

    实体包装器,主要用于处理 sql 拼接,排序,实体参数查询等

    注意: 使用的是数据库的字段,不是java的属性名称

    条件参数说明:

    查询方式 说明
    setSqlSelect 设置 SELECT 查询字段
    where WHERE 语句,拼接 + WHERE 条件
    and AND 语句,拼接 + AND 字段=值
    andNew AND 语句,拼接 + AND (字段=值)
    or OR 语句,拼接 + OR 字段=值
    orNew OR 语句,拼接 + OR (字段=值)
    eq 等于=
    allEq 基于 map 内容等于=
    ne 不等于<>
    gt 大于>
    ge 大于等于>=
    lt 小于<
    le 小于等于<=
    like 模糊查询 LIKE
    notLike 模糊查询 NOT LIKE
    in IN 查询
    notIn NOT IN 查询
    isNull NULL 值查询
    isNotNull IS NOT NULL
    groupBy 分组 GROUP BY
    having HAVING 关键词
    orderBy 排序 ORDER BY
    orderAsc ASC 排序 ORDER BY
    orderDesc DESC 排序 ORDER BY
    exists EXISTS 条件语句
    notExists NOT EXISTS 条件语句
    between BETWEEN 条件语句
    notBetween NOT BETWEEN 条件语句
    addFilter 自由拼接 SQL
    last 拼接在最后,例如:last("LIMIT 1")

    3.2 EntityWrapper 使用

    问题:年龄在 18~50 之间性别为男且姓名为 马 的所有用户

    /**
     * 年龄在 18~25 之间性别为男且姓名为 马 的所有用户
     */
    @Test
    public void testFindListEntityWrapper(){
        CustomerMapper mapper = context.getBean(CustomerMapper.class);
    
        EntityWrapper<Customer> entityWrapper = new EntityWrapper<Customer>();
        entityWrapper.between("age",18,25)
                .eq("gender",0)
                .like("cust_name","马");
        Page<Customer> page = new Page<Customer>(1,30);
        List<Customer> list = mapper.selectPage(page, entityWrapper);
        for (Customer customer : list) {
            System.out.println(customer);
        }
    }
    
    

    运行结果,观察SQL语句:

    方式2: 年龄在 18~50 之间性别为男 或者 姓名为 黑 的所有用户

    /**
         * 年龄在 18~50 之间性别为男  或者 姓名为 黑 的所有用户
         */
    @Test
    public void testFindListEntityWrapper2() {
        CustomerMapper mapper = context.getBean(CustomerMapper.class);
    
        Page<Customer> page = new Page<Customer>(1, 30);
    
        List<Customer> list = mapper.selectPage(page,
                                                Condition.create()
                                                .between("age",18,25)
                                                .eq("gender",0)
                                                .or()   // .orNew()
                                                .like("cust_name","黑"));
        for (Customer customer : list) {
            System.out.println(customer);
        }
    }
    
    

    EntityWrapper 对象 除可以查询操作外,还可以按照条件 修改和删除, 此处不做扩展,自己可以尝试编写代码测试

    4 ActiveRecord【活动记录】

    1562087025819

    Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。ActiveRecord 一直广受动态语言( PHP 、 Ruby 等)的喜爱,而 Java 作为准静态语言,对于 ActiveRecord 往往只能感叹其优雅,所以 MP 也在 AR 道路上进行了一定的探索

    4.1 插入数据

    4.2 更新数据

    4.3 删除数据

    4.4 查询数据

    5 代码生成器使用

    在代码生成之前,首先进行配置,MP提供了大量的自定义设置,生成的代码完全能够满足各类型的需求,如果你发现配置不能满足你的需求,欢迎提交issue和pull-request,有兴趣的也可以查看源码进行了解。

    默认配置,懒人直达电梯

    MP 的代码生成器 和 Mybatis MBG 代码生成器区别:
    MP 的代码生成器都是基于 java 代码来生成。MBG 基于 xml 文件进行代码生成
    MyBatis 的代码生成器可生成: 实体类、Mapper 接口、Mapper 映射文件
    MP 的代码生成器可生成: 实体类(可以选择是否支持 AR)、Mapper 接口、Mapper 映射文件、 Service 层、 Controller 层.

    MP支持以下4中主键策略,可根据需求自行选用:

    描述
    IdType.AUTO 数据库ID自增
    IdType.INPUT 用户输入ID
    IdType.ID_WORKER 全局唯一ID,内容为空自动填充(默认配置)
    IdType.UUID 全局唯一ID,内容为空自动填充

    IdType.ID_WORKER简单来说就是一个分布式高效有序ID生产黑科技工具,思路主要是来源于Twitter-Snowflake算法

    在MP中,我们建议数据库表名表字段名采用驼峰命名方式, 如果采用下划线命名方式 请开启全局下划线开关,如果表名字段名命名方式不一致请注解指定,我们建议最好保持一致。

    这么做的原因是为了避免在对应实体类时产生的性能损耗,这样字段不用做映射就能直接和实体类对应。当然如果项目里不用考虑这点性能损耗,那么你采用下滑线也是没问题的,只需要在生成代码时配置dbColumnUnderline属性就可以。

    5.1 添加依赖

    <dependency>
        <groupId>org.apache.velocity</groupId>
        <artifactId>velocity-engine-core</artifactId>
        <version>2.0</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.7</version>
     </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.7</version>
    </dependency>
    
    

    5.2 官网代码:

    package com.itheima.mp;
    
    import com.baomidou.mybatisplus.enums.IdType;
    import com.baomidou.mybatisplus.generator.AutoGenerator;
    import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
    import com.baomidou.mybatisplus.generator.config.GlobalConfig;
    import com.baomidou.mybatisplus.generator.config.PackageConfig;
    import com.baomidou.mybatisplus.generator.config.StrategyConfig;
    import com.baomidou.mybatisplus.generator.config.rules.DbType;
    import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
    
    /**
     * @author NQ
     * @create 2018-03-30 19:07
     */
    public class GeneratorMP {
    
        public static void main(String[] args) {
            String packageName = "com.itheima.mp";   // 生成的包名
            boolean serviceNameStartWithI = false;//user -> UserService, 设置成true: user -> IUserService
    
            String dir = "D:\\develop\\work\\workspace-ssm\\mybatis_plus\\mp_generator\\src\\main\\java";
    
            generateByTables(serviceNameStartWithI,
                    packageName,
                    dir, "user", "tb_customer","orders");
        }
    
        private static void generateByTables(boolean serviceNameStartWithI, String packageName, String dir, String... tableNames) {
            GlobalConfig config = new GlobalConfig();
    
            // 数据库相关信息
            String dbUrl = "jdbc:mysql://localhost:3306/mybatis";
            DataSourceConfig dataSourceConfig = new DataSourceConfig();
            dataSourceConfig.setDbType(DbType.MYSQL)
                    .setUrl(dbUrl)
                    .setUsername("root")
                    .setPassword("root")
                    .setDriverName("com.mysql.jdbc.Driver");
    
            // 策略配置
            StrategyConfig strategyConfig = new StrategyConfig();
            strategyConfig
                    .setCapitalMode(true)   // 全局大写命名
                    .setEntityLombokModel(false)   // Lomnok
                    .setDbColumnUnderline(true)   // 表名 字段名 是否使用下滑线命名
                    .setTablePrefix("tb_") // 去除表前缀
                    .setRestControllerStyle(true)
                    .setNaming(NamingStrategy.underline_to_camel) /
     underline_to_camel数据库表映射到实体的命名策略
                    .setInclude(tableNames);//修改替换成你需要的表名,多个表名传数组
    
            // 全局配置
            config.setActiveRecord(false)   //是否支持AR模式
                    .setAuthor("NQ")   // 设置作者
                    .setOutputDir(dir)   // 设置生成的目标路径(绝对路径)
                    .setIdType(IdType.AUTO) //主键策略
                    .setBaseColumnList(true)  // 设置sql片段
                    .setBaseResultMap(true)  // resultMap
                    .setEnableCache(false)   // 不开缓存
                    .setMapperName("%sMapper")
                    .setXmlName("%sMapper")
                    .setFileOverride(true);  // 每一次生成需要覆盖
            if (!serviceNameStartWithI) {
                config.setServiceName("%sService");
            }
            new AutoGenerator().setGlobalConfig(config)
                    .setDataSource(dataSourceConfig)
                    .setStrategy(strategyConfig)
                    .setPackageInfo(
                            new PackageConfig()
                                    .setParent(packageName)
                                    .setController("controller")
                                    .setEntity("entity")
                    ).execute();
        }
    
        private void generateByTables(String packageName, String dir,String... tableNames) {
            generateByTables(true, packageName, dir, tableNames);
        }
    }
    
    

    5.3 生成代码说明

    EmployeeServiceImpl 继承了 ServiceImpl 类,mybatis-plus 通过这种方式为我们注入了 EmployeeMapper,这样可以使用 service 层默认为我们提供的很多方法,也可以调用我们自己在 dao 层编写的操作数据库的方法.

    官方还提供Maven插件的形式地址:https://gitee.com/baomidou/mybatisplus-maven-plugin

    6 常用插件扩展

    6.1 分页插件

    原先我们操作mybatis的分页是有以下几种解决方案:

    • 自定义查询语句分页(自己写sql/mapper)
    • spring 注入 mybatis 配置分页插件Pagehelper

    在MP中也给我们提供了一个强大的分页操作的插件,没有任何代码的侵入,直接配置即可。

    在applicationContext.xml配置文件中的sqlSessionFactoryBean添加一个plugins属性

    <!--配置分页插件-->
    <property name="plugins">
    <array>
    <!--分页插件-->
    <bean id="paginationInterceptor" class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></bean>
    </array>
    </property>
    
    

    代码测试

    @Test
    public void testPage() {
        CustomerMapper mapper = context.getBean(CustomerMapper.class);
        List<Customer> customers = mapper.selectPage(new Page<Customer>(3, 2), null);
        for (Customer customer : customers) {
            System.out.println(customer);
        }
    }
    
    

    运行测试:可以看到原先做过方法分页是不带Limit的现在就已经出现了分页的SQL

    6.2 执行分析插件

    SQL 执行分析拦截器【 目前只支持 MYSQL-5.6.3 以上版本 】,作用是分析 处理 DELETE UPDATE 语句, 防止小白或者恶意 delete update 全表操作! 如果当前配置了这个插件,那么删除所有的操作将会失效

    <!--配置分页插件-->
    <property name="plugins">
        <array>
            <!--分页插件-->
            <bean id="paginationInterceptor" class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></bean>
            
              <!--执行分析插件-->
            <bean id="sqlExplainInterceptor" class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
             <!-- SQL 执行分析拦截器 stopProceed 发现全表执行 delete update 是否停止运行 -->
             <property name="stopProceed" value="true" />
            </bean>
        </array>
    </property>
    
    

    注意:

    • 参数:stopProceed 发现执行全表 delete update 语句是否停止执行
    • 注意!该插件只用于开发环境,不建议生产环境使用

    6.3 性能分析插件

    性能分析拦截器,用于输出每条 SQL 语句及其执行时间 , 如果执行时间超过预设的时间后,当前执行的方法的SQL就不会被执行。可以作为检测慢查询SQL使用。

    <!--配置分页插件-->
    <property name="plugins">
        <array>
    <bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
              <property name="maxTime" value="100" />
              <!--SQL是否格式化 默认false-->
                 <property name="format" value="true" />
          </bean>
        </array>
    </property>
    
    

    代码测试

    @Test
    public void testPage() {
        CustomerMapper mapper = context.getBean(CustomerMapper.class);
        List<Customer> customers = mapper.selectPage(new Page<Customer>(3, 2), null);
        for (Customer customer : customers) {
            System.out.println(customer);
        }
    }
    
    

    结果

    6.4 乐观锁插件

    意图:

    当要更新一条记录的时候,希望这条记录没有被别人更新

    乐观锁实现方式:

    • 取出记录时,获取当前version
    • 更新时,带上这个version
    • 执行更新时, set version = yourVersion+1 where version = yourVersion
    • 如果version不对,就更新失败

    乐观锁配置需要2步 记得两步

    第一步:配置插件

    <!--配置分页插件-->
    <property name="plugins">
        <array>
    <bean class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor"/>
        </array>
    </property>
    
    

    第二步:在实体类中添加一个新的字段 如 version属性

    public class User {
    
        @Version
        private Integer version;
    // set get
        ...
    }
    
    

    注意:仅支持int,Integer,long,Long,Date,Timestamp

    其他相关插件,请查询官网,按照这种学习方式,自己自学。

    7 自定义全局配置

    根据 MybatisPlus 的 AutoSqlInjector 可以自定义各种你想要的 sql ,注入到全局中,相当于自定义 Mybatisplus 自动注入的方法。
    之前需要在 xml 中进行配置的 SQL 语句,现在通过扩展 AutoSqlInjector 在加载 mybatis 环境时就注入。

    8 MP集成SpringBoot

    spring boot 项目集成mp可以使用starter

    8.1 引入依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.3.RELEASE</version>
        </parent>
    
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>mp_springboot</artifactId>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
            <mybatis-plus-boot-starter.version>2.3</mybatis-plus-boot-starter.version>
            <HikariCP.version>3.2.0</HikariCP.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jetty</artifactId>
            </dependency>
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
            </dependency>
            <dependency>
                <groupId>com.zaxxer</groupId>
                <artifactId>HikariCP</artifactId>
                <version>${HikariCP.version}</version>
            </dependency>
    
            <!-- mybatis-plus begin -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus-boot-starter.version}</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.46</version>
            </dependency>
            <!-- mybatis-plus end -->
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
    

    8.2 application.yml配置文件

    mybatis-plus:
      # 如果是放在src/main/java目录下 classpath:/com/yourpackage/*/mapper/*Mapper.xml
      # 如果是放在resource目录 classpath:/mapper/*Mapper.xml
      mapper-locations: classpath:com/itheima/mp/mapper/*Mapper.xml
      #实体扫描,多个package用逗号或者分号分隔
      typeAliasesPackage: com.itheima.mp.entity
      global-config:
        #主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
        id-type: 0
        #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
        field-strategy: 2
        #驼峰下划线转换
        db-column-underline: true
        #mp2.3+ 全局表前缀 mp_
        #table-prefix: mp_
        #刷新mapper 调试神器
        #refresh-mapper: true
        #数据库大写下划线转换
        capital-mode: true
        # Sequence序列接口实现类配置
    #    key-generator: com.baomidou.mybatisplus.incrementer.OracleKeyGenerator
        #逻辑删除配置(下面3个配置)
    #    logic-delete-value: 1
    #    logic-not-delete-value: 0
    #    sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
        #自定义填充策略接口实现
    #    meta-object-handler: com.baomidou.springboot.MyMetaObjectHandler
      configuration:
        #配置返回数据库(column下划线命名&&返回java实体是驼峰命名),自动匹配无需as(没开启这个,SQL需要写as: select user_id as userId)
        map-underscore-to-camel-case: true
        cache-enabled: false
        #配置JdbcTypeForNull, oracle数据库必须配置
        jdbc-type-for-null: 'null'
    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
        driver-class-name: com.mysql.jdbc.Driver
        username: root
        password: root
    ##logging
    logging:
      com.level: debug
    
    

    springboot2.0之后必须开启log日志

    使用代码生成器生成Pojo、mapper、service、controller 等

    8.3 编写启动类Application

    @EnableTransactionManagement
    @SpringBootApplication
    //@ComponentScan(basePackages = {
    //        "com.baomidou.springboot.config",
    //        "com.baomidou.springboot.controller",
    //        "com.baomidou.springboot.service"})
    public class Application {
    
        protected final static Logger logger = LoggerFactory.getLogger(Application.class);
    
        public static void main(String[] args) {
            SpringApplication app = new SpringApplication(Application.class);
            app.setBannerMode(Banner.Mode.OFF);
            app.run(args);
            logger.info("PortalApplication is success!");
            System.err.println("sample started. http://localhost:8080/user/");
        }
    
    }
    
    

    8.4 加入相关插件配置

    package com.itheima.mp.config;
    
    import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
    import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
    import org.mybatis.spring.mapper.MapperScannerConfigurer;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    //@MapperScan("com.baomidou.springboot.mapper*")//这个注解,作用相当于下面的@Bean MapperScannerConfigurer,2者配置1份即可
    public class MybatisPlusConfig {
    
        /**
         * mybatis-plus分页插件<br>
         * 文档:http://mp.baomidou.com<br>
         */
        @Bean
        public PaginationInterceptor paginationInterceptor() {
            PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
            return paginationInterceptor;
        }
    
        /**
         * 相当于顶部的:
         * {@code @MapperScan("com.baomidou.springboot.mapper*")}
         * 这里可以扩展,比如使用配置文件来配置扫描Mapper的路径
         */
        @Bean
        public MapperScannerConfigurer mapperScannerConfigurer() {
            MapperScannerConfigurer scannerConfigurer = new MapperScannerConfigurer();
            scannerConfigurer.setBasePackage("com.itheima.mp.mapper*");
            return scannerConfigurer;
        }
    
    //    @Bean
    //    public H2KeyGenerator getH2KeyGenerator() {
    //        return new H2KeyGenerator();
    //    }
    
        /**
         * 性能分析拦截器,不建议生产使用
         */
        @Bean
        public PerformanceInterceptor performanceInterceptor(){
            PerformanceInterceptor interceptor = new PerformanceInterceptor();
            interceptor.setFormat(true);
            interceptor.setMaxTime(10000);
    
            return interceptor;
        }
    
    //    public SqlExplainInterceptor sqlExplainInterceptor(){
    //        return new SqlExplainInterceptor();
    //    }
        
    }
    
    

    注意:代码生成器中没有在mapper上加注解,导致无法完成注入操作。所以需要我们自己去加上注解 @Mapper

    /**
     * <p>
     *  Mapper 接口
     * </p>
     *
     * @author NQ
     * @since 2018-08-30
     */
    @Mapper
    public interface UserMapper extends BaseMapper<User> {
    
    }
    
    

    8.5 编写Controller

    /**
     *  前端控制器
     *
     * @author NQ
     * @since 2018-08-30
     */
    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @Autowired
        private UserService userService;
    
        /**
         * 代码生成器测试查询全部
         * @return
         */
        @GetMapping("findAll")
        public List<User> findAll(){
            return userService.selectList(null);
        }
    
        @GetMapping("findOne")
        public User findOne(Integer id){
            return userService.selectById(id);
        }
    
        /**
         * 分页测试
         * @param page
         * @param size
         * @return
         */
        @GetMapping("findPage")
        public Page<User> findPage(Integer page,Integer size){
            Page<User> userPage = userService.selectPage(new Page<>(page, size));
            long total = userPage.getTotal();
            System.out.println(total);
            return userPage;
        }
    
        /**
         * mybatis注解使用测试
         * @return
         */
        @GetMapping("findByQuery")
        public List<User> findByQuery(){
            return userService.findByQuery();
        }
    
    }
    
    

    启动引导类测试。

    9 Idea快速开发插件

    • 官方安装: File -> Settings -> Plugins -> Browse Repositories.. 输入 mybatisx 安装下载

      网络问题可能会下载失败

    • Jar 安装: File -> Settings -> Plugins -> Install plugin from disk.. 选中 mybatisx..jar 安装

    MybatisX 源码
    你好!ICAC,请配合我们调查。

  • 2
    Hik
    @Ta / 2019-07-06
    @无期徒刑,markdown需要添加什么ubb么
  • 3
    @Ta / 2019-07-06
    @Hik给你添加了,在内容的开始添加<!md>就行了。
  • 4
    000
    @Ta / 2019-07-06

    不懂Java,不过魂斗罗是真的要出正统续作了最近
    斗图专属版

  • 5
    @Ta / 2019-07-07

    大佬,果然是深藏不露,露着一鸣惊人
    小尾巴我就菜鸡一枚 https://76wp.cn奇乐网

  • 6
    @Ta / 2019-07-07
    林子里难得看到Java基友
  • 7
    @Ta / 2019-07-07

    小米5黑色低配版

  • 8
    @Ta / 2019-07-09
    虎林的markdown对代码块不太友好。其实官方文档就很简单了

    https://mp.baomidou.com/config/#%E5%9F%BA%E6%9C%AC%E9%85%8D%E7%BD%AE
  • 9
    @Ta / 2019-07-09
    另外该作者不仅写了MybatisPlus还有HibernatePlus
  • 10
    @Ta / 2019-10-18
    @无期徒刑,你好大佬,你是如何快速copy作者原贴的markdown?
  • 11
    @Ta / 2019-11-24

    @胖罗 复制网页内容后 到typora之类的markdown编辑器中直接粘贴就行了,会自动转为markdown格式排版
    我们有着共同的敌人——天命;
    你却认命了,还对我说天命不可违‮

添加新回复
回复需要登录

[聊天-此处没有老虎] 暗:喜羊羊 米表http://imi.best精品域名出售