详细解析MyBatis Plus框架的核心功能!MyBatis Plus框架经典使用场景的分析说明

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 本篇文章介绍了MyBatis Plus框架的核心功能,使用代码实例介绍了MyBatis Plus框架集成SpringBoot和Spring框架的具体使用。最后对MyBatis Plus框架的几个经典场景的使用进行具体的分析与说明,包括代码生成器,通用CRUD,条件构造器,自定义SQL语句,分页插件和性能分析插件,公共字段自动插入。通过这篇文章,可以对MyBatis Plus框架有更全面的认识。

ORM框架-Mybatis Plus

MyBatis Plus是在 MyBatis 的基础上只做增强不做改变,可以简化开发,提高效率.

Mybatis Plus核心功能

  • 支持通用的 CRUD,代码生成器与条件构造器
  • 通用CRUD: 定义好Mapper接口后,只需要继承 BaseMapper接口即可获得通用的增删改查功能,无需编写任何接口方法与配置文件
  • 条件构造器: 通过EntityWrapper(实体包装类),可以用于拼接SQL语句,并且支持排序,分组查询等复杂的 SQL
  • 代码生成器: 支持一系列的策略配置与全局配置,比 MyBatis 的代码生成更好用

BaseMapper接口中通用的 CRUD 方法:
在这里插入图片描述

MyBatis Plus与SpringBoot集成

  • 数据库USER
DROP TABLE IF EXISTS user;
CREATE TABLE user(
  id bigint(20) DEFAULT NULL COMMENT '唯一标示',
  code varchar(20) DEFAULT NULL COMMENT '编码',
  name varchar(64) DEFAULT NULL COMMENT '名称',
  status char(1) DEFAULT 1 COMMENT '状态 1启用 0 停用',
  gmt_create datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  gmt_modified datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  • pom.xml依赖
 <!--mybatis plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatisplus-spring-boot-starter</artifactId>
    <version>1.0.5</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>2.1.9</version>
</dependency>
  • spring-mybatis.xml配置文件

也可以直接使用@Bean的方式进行或者通过application配置文件进行

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--创建jdbc数据源 这里直接使用阿里的druid数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="driverClassName" value="${mysql.driver}"/>
        <property name="url" value="${mysql.url}"/>
        <property name="username" value="${mysql.username}"/>
        <property name="password" value="${mysql.password}"/>
        <!-- 初始化连接大小 -->
        <property name="initialSize" value="0"/>
        <!-- 连接池最大使用连接数量 -->
        <property name="maxActive" value="20"/>
        <!-- 连接池最大空闲 -->
        <property name="maxIdle" value="20"/>
        <!-- 连接池最小空闲 -->
        <property name="minIdle" value="0"/>
        <!-- 获取连接最大等待时间 -->
        <property name="maxWait" value="60000"/>

        <property name="validationQuery" value="${validationQuery}"/>
        <property name="testOnBorrow" value="false"/>
        <property name="testOnReturn" value="false"/>
        <property name="testWhileIdle" value="true"/>

        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000"/>
        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="25200000"/>

        <!-- 打开removeAbandoned功能 -->
        <property name="removeAbandoned" value="true"/>
        <!-- 1800秒,也就是30分钟 -->
        <property name="removeAbandonedTimeout" value="1800"/>
        <!-- 关闭abanded连接时输出错误日志 -->
        <property name="logAbandoned" value="true"/>

        <!-- 监控数据库 -->
        <property name="filters" value="mergeStat"/>
    </bean>

    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- 可通过注解控制事务 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

    <!--mybatis-->
    <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- 自动扫描mapper.xml文件,支持通配符 -->
        <property name="mapperLocations" value="classpath:mapper/**/*.xml"/>
        <!-- 配置文件,比如参数配置(是否启动驼峰等)、插件配置等 -->
        <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
        <!-- 启用别名,这样就无需写全路径类名了,具体可自行查阅资料 -->
        <property name="typeAliasesPackage" value="cn.lqdev.learning.springboot.chapter9.biz.entity"/>
        <!-- MP 全局配置注入 -->
        <property name="globalConfig" ref="globalConfig"/>
    </bean>
    <bean id="globalConfig" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
        <!--
            AUTO->`0`("数据库ID自增")QW
             INPUT->`1`(用户输入ID")
            ID_WORKER->`2`("全局唯一ID")
            UUID->`3`("全局唯一ID")
        -->
        <property name="idType" value="3" />
    </bean>
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!-- 自动扫描包路径,接口自动注册为一个bean类 -->
        <property name="basePackage" value="cn.lqdev.learning.springboot.chapter9.biz.dao"/>
    </bean>

</beans>
  • 编写启动类,应用启动时自动加载配置xml文件
@Configuration
@ImportResource(locations = {"classpath:/mybatis/spring-mybatis.xml"})
//@MapperScan("cn.lqdev.learning.springboot.chapter9.biz.dao")
//@EnableTransactionManagement
public class MybatisPlusConfig {
}

MyBatis Plus集成Spring

  • 数据表结构
DROP TABLE IF EXISTS tbl_employee;
CREATE TABLE tbl_employee(
  id int(11) NOT NULL AUTO_INCREMENT,
  last_name varchar(50) DEFAULT NULL,
  email varchar(50) DEFAULT NULL,
  gender char(1) DEFAULT NULL,
  age int(11) DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
  • pom.xml
    <dependencies>
        <!-- MP -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>2.3</version>
        </dependency>
        <!-- 测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!-- 数据源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!-- 数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.39</version>
        </dependency>
        <!-- Spring 相关 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.3.9.RELEASE</version>
        </dependency>
    </dependencies>
  • MyBatis全局配置文件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 />
  • 数据源db.properties
jdbc.url=jdbc:mysql://localhost:3306/mp
jdbc.username=mp
jdbc.password=mp
  • Spring 配置文件applicationContext.xml
    <!-- 数据源 -->
    <context:property-placeholder location="classpath:db.properties"/>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

    <!-- MP 提供的 MybatisSqlSessionFactoryBean -->
    <bean id="sqlSessionFactoryBean" 
          class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
        <!-- 数据源 -->
        <property name="dataSource" ref="dataSource"></property>
        <!-- mybatis 全局配置文件 -->
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        <!-- 别名处理 -->
        <property name="typeAliasesPackage" value="com.jas.bean"></property>
        <!-- 注入全局MP策略配置 -->
        <property name="globalConfig" ref="globalConfiguration"></property>
        <!-- 插件注册 -->
        <property name="plugins">
            <list>
                <!-- 注册分页插件 -->
                <bean class="com.baomidou.mybatisplus.plugins.PaginationInterceptor" />
                <!-- 注入 SQL 性能分析插件,建议在开发环境中使用,可以在控制台查看 SQL 执行日志 -->
                <bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
                    <property name="maxTime" value="1000" />
                    <!--SQL 是否格式化 默认false-->
                    <property name="format" value="true" />
                </bean>
            </list>
        </property>
    </bean>

    <!-- 定义 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="tbl_"></property>
    </bean>
    
    <!-- 配置mybatis 扫描mapper接口的路径 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.jas.mapper"></property>
    </bean>

MyBatis Plus使用示例

  • 实体类Employee
@TableName(value = "tbl_employee")
public class Employee {
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @TableField(value = "last_name")
    private String lastName;
    private String email;
    private Integer gender;
    private Integer age;

    public Employee() {
        super();
    }
    
    public Employee(Integer id, String lastName, String email, Integer gender, Integer age) {
        this.id = id;
        this.lastName = lastName;
        this.email = email;
        this.gender = gender;
        this.age = age;
    }
    // 省略 set、get 与 toString() 方法
  • mapper接口
/**
* 不定义任何接口方法
*/
public interface EmployeeMapper extends BaseMapper<Employee> {}
  • 在测试类中生成测试的mapper对象
    private ApplicationContext context = 
            new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
            
    private EmployeeMapper employeeMapper = 
            context.getBean("employeeMapper", EmployeeMapper.class);
  • 查询:
    @Test
    public void getEmpByIdTest() {
        Employee employee = employeeMapper.selectById(1);
        
        System.out.println(employee);
    }
  • 分页查询:
    @Test
    public void getEmpByPage() {
        Page<?> page = new Page<>(1, 5);
        List<Employee> list = employeeMapper.selectPage(page, null);
        
        System.out.println("总记录数:" + page.getTotal());
        System.out.println("总页数" + page.getPages());
        System.out.println(list);
    }
  • 条件构造器:
    @Test
    public void getEmpByName() {
        EntityWrapper<Employee> wrapper = new EntityWrapper<>();
        
        // 'last_name' 与 'age' 对应数据库中的字段 
        wrapper.like("last_name", "张");
        wrapper.eq("age", 20);
        
        List<Employee> list = employeeMapper.selectList(wrapper);
        System.out.println(list);
    }

控制台输出的SQL分析日志
在这里插入图片描述
简单的数据库操作不需要在 EmployeeMapper 接口中定义任何方法,也没有在配置文件中编写SQL语句,而是通过继承BaseMapper接口获得通用的的增删改查方法,复杂的SQL也可以使用条件构造器拼接.不过复杂的业务需求还是要编写SQL语句的,流程和MyBatis一样.

MyBatis Plus使用场景

代码生成器
  • 代码生成器依赖velocity模版引擎,引入依赖
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.0</version>
    <scope>test</scope>
</dependency>
  • 代码生成器类MysqlGenerator:
public class MysqlGenerator {

    private static final String PACKAGE_NAME = "cn.lqdev.learning.springboot.chapter9";
    private static final String MODULE_NAME = "biz";
    private static final String OUT_PATH = "D:\\develop\\code";
    private static final String AUTHOR = "oKong";

    private static final String DRIVER = "com.mysql.jdbc.Driver";
    private static final String URL = "jdbc:mysql://127.0.0.1:3306/learning?useUnicode=true&characterEncoding=UTF-8";
    private static final String USER_NAME = "root";
    private static final String PASSWORD = "123456";

    /**
     * <p>
     * MySQL 生成演示
     * </p>
     */
    public static void main(String[] args) {
        // 自定义需要填充的字段
        List<TableFill> tableFillList = new ArrayList<TableFill>();

        // 代码生成器
        AutoGenerator mpg = new AutoGenerator().setGlobalConfig(
                // 全局配置
                new GlobalConfig().setOutputDir(OUT_PATH)// 输出目录
                        .setFileOverride(true)// 是否覆盖文件
                        .setActiveRecord(true)// 开启 activeRecord 模式
                        .setEnableCache(false)// XML 二级缓存
                        .setBaseResultMap(false)// XML ResultMap
                        .setBaseColumnList(true)// XML columList
                        .setAuthor(AUTHOR)
                        // 自定义文件命名,注意 %s 会自动填充表实体属性!
                        .setXmlName("%sMapper").setMapperName("%sDao")
        // .setServiceName("MP%sService")
        // .setServiceImplName("%sServiceDiy")
        // .setControllerName("%sAction")
        ).setDataSource(
                // 数据源配置
                new DataSourceConfig().setDbType(DbType.MYSQL)// 数据库类型
                        .setTypeConvert(new MySqlTypeConvert() {
                            // 自定义数据库表字段类型转换【可选】
                            @Override
                            public DbColumnType processTypeConvert(String fieldType) {
                                System.out.println("转换类型:" + fieldType);
                                // if ( fieldType.toLowerCase().contains( "tinyint" ) ) {
                                // return DbColumnType.BOOLEAN;
                                // }
                                return super.processTypeConvert(fieldType);
                            }
                        }).setDriverName(DRIVER).setUsername(USER_NAME).setPassword(PASSWORD).setUrl(URL))
                .setStrategy(
                        // 策略配置
                        new StrategyConfig()
                                // .setCapitalMode(true)// 全局大写命名
                                .setDbColumnUnderline(true)// 全局下划线命名
                                // .setTablePrefix(new String[]{"unionpay_"})// 此处可以修改为您的表前缀
                                .setNaming(NamingStrategy.underline_to_camel)// 表名生成策略
                                // .setInclude(new String[] {"citycode_org"}) // 需要生成的表
                                // .setExclude(new String[]{"test"}) // 排除生成的表
                                // 自定义实体,公共字段
                                // .setSuperEntityColumns(new String[]{"test_id"})
                                .setTableFillList(tableFillList)
                                // 自定义实体父类
                                // .setSuperEntityClass("com.baomidou.demo.common.base.BsBaseEntity")
                                // // 自定义 mapper 父类
                                // .setSuperMapperClass("com.baomidou.demo.common.base.BsBaseMapper")
                                // // 自定义 service 父类
                                // .setSuperServiceClass("com.baomidou.demo.common.base.BsBaseService")
                                // // 自定义 service 实现类父类
                                // .setSuperServiceImplClass("com.baomidou.demo.common.base.BsBaseServiceImpl")
                                // 自定义 controller 父类
                                // .setSuperControllerClass("com.baomidou.demo.TestController")
                                // 【实体】是否生成字段常量(默认 false)
                                // public static final String ID = "test_id";
                                .setEntityColumnConstant(true)
                                // 【实体】是否为构建者模型(默认 false)
                                // public User setName(String name) {this.name = name; return this;}
                                .setEntityBuilderModel(true)
                                // 【实体】是否为lombok模型(默认 false)<a href="https://projectlombok.org/">document</a>
                                .setEntityLombokModel(true)
                // Boolean类型字段是否移除is前缀处理
                // .setEntityBooleanColumnRemoveIsPrefix(true)
                // .setRestControllerStyle(true)
                // .setControllerMappingHyphenStyle(true)
                ).setPackageInfo(
                        // 包配置
                        new PackageConfig().setModuleName(MODULE_NAME).setParent(PACKAGE_NAME)// 自定义包路径
                                .setController("controller")// 这里是控制器包名,默认 web
                                .setXml("mapper").setMapper("dao")

                ).setCfg(
                        // 注入自定义配置,可以在 VM 中使用 cfg.abc 设置的值
                        new InjectionConfig() {
                            @Override
                            public void initMap() {
                                Map<String, Object> map = new HashMap<String, Object>();
                                map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
                                this.setMap(map);
                            }
                        }.setFileOutConfigList(
                                Collections.<FileOutConfig>singletonList(new FileOutConfig("/templates/mapper.xml.vm") {
                                    // 自定义输出文件目录
                                    @Override
                                    public String outputFile(TableInfo tableInfo) {
                                        return OUT_PATH + "/xml/" + tableInfo.getEntityName() + "Mapper.xml";
                                    }
                                })))
                .setTemplate(
                        // 关闭默认 xml 生成,调整生成 至 根目录
                        new TemplateConfig().setXml(null)
        // 自定义模板配置,模板可以参考源码 /mybatis-plus/src/main/resources/template 使用 copy
        // 至您项目 src/main/resources/template 目录下,模板名称也可自定义如下配置:
        // .setController("...");
        // .setEntity("...");
        // .setMapper("...");
        // .setXml("...");
        // .setService("...");
        // .setServiceImpl("...");
        );

        // 执行生成
        mpg.execute();
    }

}
通用CRUD
  • 通用CRUD测试类GeneralTest:
@RunWith(SpringRunner.class)
//SpringBootTest 是springboot 用于测试的注解,可指定启动类或者测试环境等,这里直接默认。
@SpringBootTest 
@Slf4j
public class GeneralTest {

    @Autowired
    IUserService userService;

    @Test
    public void testInsert() {
        User user = new User();
        user.setCode("001");
        user.setName("okong-insert");
        //默认的插入策略为:FieldStrategy.NOT_NULL,即:判断 null
        //对应在mapper.xml时写法为:<if test="field!=null">
        //这个可以修改的,设置字段的@TableField(strategy=FieldStrategy.NOT_EMPTY)
        //所以这个时候,为null的字段是不会更新的,也可以开启性能插件,查看sql语句就可以知道
        userService.insert(user);

        //新增所有字段,
        userService.insertAllColumn(user);
        log.info("新增结束");
    }

    @Test
    public void testUpdate() {

        User user = new User();
        user.setCode("101");
        user.setName("oKong-insert");
        //这就是ActiveRecord的功能
        user.insert();
        //也可以直接 userService.insert(user);

        //更新
        User updUser = new User();
        updUser.setId(user.getId());
        updUser.setName("okong-upd");

        updUser.updateById();
        log.info("更新结束");
    }

    @Test
    public void testDelete() {
        User user = new User();
        user.setCode("101");
        user.setName("oKong-delete");

        user.insert();

        //删除
        user.deleteById();
        log.info("删除结束");

    }

    @Test
    public void testSelect() {
        User user = new User();
        user.setCode("201");
        user.setName("oKong-selecdt");

        user.insert();

        log.info("查询:{}",user.selectById());
    }
}
  • MyBatis Plus定义的数据库操作方法

在这里插入图片描述
对于通用代码如何注入的,可查看com.baomidou.mybatisplus.mapper.AutoSqlInjector类,这个就是注入通用的CURD方法的类.

条件构造器

条件构造器主要提供了实体包装器,用于处理SQL语句拼接,排序,实体参数查询:使用的是数据库字段,不是Java属性

  • sql条件拼接:

SQL条件拼接测试类ConditionTest

@RunWith(SpringRunner.class)
//SpringBootTest 是springboot 用于测试的注解,可指定启动类或者测试环境等,这里直接默认。
@SpringBootTest 
@Slf4j
public class ConditionTest {

    @Autowired
    IUserService userService;

    @Test
    public void testOne() {
        User user =  new User();
        user.setCode("701");
        user.setName("okong-condition");
        user.insert();

        EntityWrapper<User> qryWrapper = new EntityWrapper<>();

        qryWrapper.eq(User.CODE, user.getCode());
        qryWrapper.eq(User.NAME, user.getName());

        //也可以直接 
//        qryWrapper.setEntity(user);

        //打印sql语句
        System.out.println(qryWrapper.getSqlSegment());

        //设置select 字段 即:select code,name from 
        qryWrapper.setSqlSelect(User.CODE,User.NAME);
        System.out.println(qryWrapper.getSqlSelect());

        //查询
        User qryUser = userService.selectOne(qryWrapper);
        System.out.println(qryUser);
        log.info("拼接一结束");
    }

    @Test
    public void testTwo() {
        User user =  new User();
        user.setCode("702");
        user.setName("okong-condition");
        user.insert();

        EntityWrapper<User> qryWrapper = new EntityWrapper<>();
        qryWrapper.where("code = {0}", user.getCode())
        .and("name = {0}",user.getName())
        .andNew("status = 0");
        System.out.println(qryWrapper.getSqlSegment());
        //等等很复杂的。
        //复杂的建议直接写在xml里面了,要是非动态的话 比较xml一眼看得懂呀
        //查询
        User qryUser = userService.selectOne(qryWrapper);
        System.out.println(qryUser);
        log.info("拼接二结束");
    }

}

MyBatis Plus提供的条件构造方法com.baomidou.mybatisplus.mapper.Wrapper
在这里插入图片描述

  • 自定义SQL使用条件构造器:

UserDao.java加入接口方法:

/**
     * 
     * @param rowBounds 分页对象 直接传入page即可
     * @param wrapper 条件构造器
     * @return
     */
    List<User> selectUserWrapper(RowBounds rowBounds, @Param("ew") Wrapper<User> wrapper);

UserMapper.xml加入对应的xml节点:

    <!-- 条件构造器形式 -->
    <select id="selectUserWrapper" resultType="user">
        SELECT
        <include refid="Base_Column_List" />
        FROM USER
        <where>
            ${ew.sqlSegment}
        </where>
    </select>

自定义SQL使用条件构造器测试类:

@Test
    public void testCustomSql() {
        User user = new User();
        user.setCode("703");
        user.setName("okong-condition");
        user.insert();

        EntityWrapper<User> qryWrapper = new EntityWrapper<>();
        qryWrapper.eq(User.CODE, user.getCode());

        Page<User> pageUser = new Page<>();
        pageUser.setCurrent(1);
        pageUser.setSize(10);

        List<User> userlist = userDao.selectUserWrapper(pageUser, qryWrapper);
        System.out.println(userlist.get(0));
        log.info("自定义sql结束");
    }
  • xml形式使用wrapper:

UserDao.java:

/**
     * 
     * @param rowBounds 分页对象 直接传入page即可
     * @param wrapper 条件构造器
     * @return
     */
    List<User> selectUserWrapper(RowBounds rowBounds, @Param("ew") Wrapper<User> wrapper);

UserMapper.xml:


    <!-- 条件构造器形式 -->
    <select id="selectUserWrapper" resultType="user">
        SELECT
        <include refid="Base_Column_List" />
        FROM USER
        <where>
            ${ew.sqlSegment}
        </where>
    </select>
  • 条件参数说明:
查询方式 使用说明
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 拼接在最后
自定义SQL语句

在多表关联时,条件构造器和通用CURD都无法满足时,可以编写SQL语句进行扩展.这些都是mybatis的用法.首先改造UserDao接口,有两种方式:

  • 注解形式:
@Select("SELECT * FROM USER WHERE CODE = #{userCode}")
    List<User> selectUserCustomParamsByAnno(@Param("userCode")String userCode);
  • xml形式:
List<User> selectUserCustomParamsByXml(@Param("userCode")String userCode);

UserMapper.xml新增一个节点:

    <!-- 由于设置了别名:typeAliasesPackage=cn.lqdev.learning.mybatisplus.samples.biz.entity,所以resultType可以不写全路径了。 -->
    <select id="selectUserCustomParamsByXml" resultType="user">
        SELECT 
        <include refid="Base_Column_List"/> 
        FROM USER 
       WHERE CODE = #{userCode}
    </select>

自定义SQL语句测试类CustomSqlTest:

@RunWith(SpringRunner.class)
//SpringBootTest 是springboot 用于测试的注解,可指定启动类或者测试环境等,这里直接默认。
@SpringBootTest 
@Slf4j
public class CustomSqlTest {

    @Autowired
    UserDao userDao;

    @Test
    public void testCustomAnno() {
        User user = new User();
        user.setCode("901");
        user.setName("okong-sql");
        user.insert();
        List<User> userlist = userDao.selectUserCustomParamsByAnno(user.getCode());
        //由于新增的 肯定不为null 故不判断了。
        System.out.println(userlist.get(0).toString());
        log.info("注解形式结束------");
    }

    @Test
    public void testCustomXml() {
        User user = new User();
        user.setCode("902");
        user.setName("okong-sql");
        user.insert();
        List<User> userlist = userDao.selectUserCustomParamsByXml(user.getCode());
        //由于新增的 肯定不为null 故不判断了。
        System.out.println(userlist.get(0).toString());
        log.info("xml形式结束------");
    }

}

==注意:==
在使用spring-boot-maven-plugin插件打包成springboot运行jar时,需要注意:由于springboot的jar扫描路径方式问题,会导致别名的包未扫描到,所以这个只需要把mybatis默认的扫描设置为Springboot的VFS实现.修改spring-mybatis.xml文件:

  <!--mybatis-->
    <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- 自动扫描mapper.xml文件,支持通配符 -->
        <property name="mapperLocations" value="classpath:mapper/**/*.xml"/>
        <!-- 配置文件,比如参数配置(是否启动驼峰等)、插件配置等 -->
        <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
        <!-- 启用别名,这样就无需写全路径类名了,具体可自行查阅资料 -->
        <property name="typeAliasesPackage" value="cn.lqdev.learning.mybatisplus.samples.biz.entity"/>
        <!-- MP 全局配置注入 -->
        <property name="globalConfig" ref="globalConfig"/>
        <!-- 设置vfs实现,避免路径扫描问题 -->
        <property name="vfs"  value="com.baomidou.mybatisplus.spring.boot.starter.SpringBootVFS"></property>
    </bean>
分页插件,性能分析插件

mybatis的插件机制使用只需要注册即可

  • mybatis-config.xml
    <plugins>
      <!-- SQL 执行性能分析,开发环境使用,线上不推荐。 -->
      <plugin interceptor="com.baomidou.mybatisplus.plugins.PerformanceInterceptor"></plugin>
      <!-- 分页插件配置 -->
      <plugin interceptor="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></plugin>
    </plugins>
  • 分页测试类(性能分析,配置后可以输出sql及取数时间):
@RunWith(SpringRunner.class)
//SpringBootTest 是springboot 用于测试的注解,可指定启动类或者测试环境等,这里直接默认。
@SpringBootTest 
@Slf4j
public class PluginTest {

    @Autowired
    IUserService userService;

    @Test
    public void testPagination() {
        Page<User> page = new Page<>();
        //每页数
        page.setSize(10);
        //当前页码
        page.setCurrent(1);

        //无条件时
        Page<User> pageList = userService.selectPage(page);
        System.out.println(pageList.getRecords().get(0));

        //新增数据 避免查询不到数据
        User user = new User();
        user.setCode("801");
        user.setName("okong-Pagination");
        user.insert();
        //加入条件构造器
        EntityWrapper<User> qryWapper = new EntityWrapper<>();
        //这里也能直接设置 entity 这是条件就是entity的非空字段值了
//        qryWapper.setEntity(user);
        //这里建议直接用 常量 
    //    qryWapper.eq(User.CODE, user.getCode());
        pageList = userService.selectPage(page, qryWapper);
        System.out.println(pageList.getRecords().get(0));
        log.info("分页结束");
    }

}
  • 性能插件体现,控制台输出:
 Time:4 ms - ID:cn.lqdev.learning.mybatisplus.samples.biz.dao.UserDao.selectPage
 Execute SQL: SELECT id AS id,code,`name`,`status`,gmt_create AS gmtCreate,gmt_modified AS gmtModified FROM user WHERE id=1026120705692434433 AND code='801' AND `name`='okong-Pagination' LIMIT 0,10
公共字段自动填充

通常,每个公司都有自己的表定义,在《阿里巴巴Java开发手册》中,就强制规定表必备三字段:id,gmt_create,gmt_modified.所以通常我们都会写个公共的拦截器去实现自动填充比如创建时间和更新时间的,无需开发人员手动设置.而在MP中就提供了这么一个公共字段自动填充功能

  • 设置填充字段的填充类型:
  • User

==注意==可以在代码生成器里面配置规则的,可自动配置

    /**
     * 创建时间
     */
    @TableField(fill=FieldFill.INSERT)
    private Date gmtCreate;
    /**
     * 修改时间
     */
    @TableField(fill=FieldFill.INSERT_UPDATE)
    private Date gmtModified;
  • 定义处理类:
  • MybatisObjectHandler
public class MybatisObjectHandler extends MetaObjectHandler{

    @Override
    public void insertFill(MetaObject metaObject) {
        //新增时填充的字段
        setFieldValByName("gmtCreate", new Date(), metaObject);
        setFieldValByName("gmtModified", new Date(), metaObject);

    }

    @Override
    public void updateFill(MetaObject metaObject) {
        //更新时 需要填充字段
        setFieldValByName("gmtModified", new Date(), metaObject);
    }
}
  • 修改springb-mybatis.xml文件,加入此配置
    <bean id="globalConfig" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
        <!--
            AUTO->`0`("数据库ID自增")QW
             INPUT->`1`(用户输入ID")
            ID_WORKER->`2`("全局唯一ID")
            UUID->`3`("全局唯一ID")
        -->
        <property name="idType" value="2" />
        <property name="metaObjectHandler" ref="mybatisObjectHandler"></property>
    </bean>

    <bean id="mybatisObjectHandler" class="cn.lqdev.learning.mybatisplus.samples.config.MybatisObjectHandler"/>

再新增或者修改时,对应时间就会进行更新:

 Time:31 ms - ID:cn.lqdev.learning.mybatisplus.samples.biz.dao.UserDao.insert
 Execute SQL: INSERT INTO user ( id, code, `name`, gmt_create,gmt_modified ) VALUES ( 1026135016838037506, '702', 'okong-condition', '2018-08-05 23:57:07.344','2018-08-05 23:57:07.344' )
相关文章
|
12天前
|
人工智能 监控 算法
销售易CRM:功能与优势全解析
销售易CRM是国内领先的客户关系管理(CRM)系统,提供强大的销售管理、全方位客户管理、丰富的营销自动化工具、智能AI赋能及灵活的开放性平台。其功能涵盖线索获取、商机管理、客户画像、营销活动策划、智能预测等,支持企业高效管理客户、优化业务流程、提升销售效率和客户满意度。通过灵活的二次开发和API接口,销售易CRM可无缝集成企业现有系统,助力企业在数字化转型中实现业绩高质量增长。
|
4天前
|
弹性计算 运维 安全
优化管理与服务:操作系统控制平台的订阅功能解析
本文介绍了如何通过操作系统控制平台提升系统效率,优化资源利用。首先,通过阿里云官方平台开通服务并安装SysOM组件,体验操作系统控制平台的功能。接着,详细讲解了订阅管理功能,包括创建订阅、查看和管理ECS实例的私有YUM仓库权限。订阅私有YUM仓库能够集中管理软件包版本、提升安全性,并提供灵活的配置选项。最后总结指出,使用阿里云的订阅和私有YUM仓库功能,可以提高系统可靠性和运维效率,确保业务顺畅运行。
|
11天前
|
JSON 自然语言处理 前端开发
WebSocket调试工具深度对比:Postman与Apipost功能实测解析
本文深入对比了Postman与Apipost两款WebSocket调试工具。作为实时通讯系统工程师,作者在开发智能客服系统时遇到了传统工具调试复杂、文档管理不便的问题。通过引入Apipost的智能连接池、消息分组管理和自动化文档生成等功能,实现了多环境自动切换、消息分类和接口文档自动生成,极大提升了调试效率和团队协作效果。最终,使用Apipost使接口调试时间减少40%,文档维护成本降低70%,跨团队沟通效率提升50%。
|
11天前
|
人工智能 搜索推荐 数据挖掘
销售易CRM:功能与优势全解析
销售易CRM是国内领先的客户关系管理系统,提供从线索获取到订单成交的完整销售漏斗管理,涵盖销售、客户、营销管理和AI赋能等功能。其强大的销售管理功能包括线索与商机管理、销售预测等;全方位客户管理实现360度客户视图;丰富的营销自动化工具支持多渠道营销活动;智能AI技术提升销售效率和客户满意度;灵活的开放性平台满足定制化需求;现代化界面设计简洁直观,支持多设备访问;移动端功能齐全,协同工具丰富;优质的客户服务确保快速响应和技术支持。销售易CRM助力企业优化业务流程,推动销售增长。
|
16天前
|
JSON 前端开发 安全
WebSocket调试工具深度对比:Postman与Apipost功能实测解析
如果你在寻找既能搞定WebSocket调试,又能完美管理文档的工具,不妨试试Apipos!
31 1
|
26天前
|
人工智能 小程序 API
销售易NeoCRM与纷享销客:功能、体验与价格全解析
销售易NeoCRM和纷享销客是国内知名的CRM解决方案,各有特色。销售易功能全面,涵盖销售、客户、营销管理及AI赋能,适合中大型企业;纷享销客则以强大的连接能力和业务协同见长,用户体验佳,性价比高,更适合中小企业。两者在价格、用户体验和适用场景上有所差异,企业应根据自身需求选择合适的CRM系统。
|
1天前
|
SQL 缓存 Java
框架源码私享笔记(02)Mybatis核心框架原理 | 一条SQL透析核心组件功能特性
本文详细解构了MyBatis的工作机制,包括解析配置、创建连接、执行SQL、结果封装和关闭连接等步骤。文章还介绍了MyBatis的五大核心功能特性:支持动态SQL、缓存机制(一级和二级缓存)、插件扩展、延迟加载和SQL注解,帮助读者深入了解其高效灵活的设计理念。
|
24天前
|
人工智能 自然语言处理 供应链
国产与国外CRM系统:功能与优势全解析
随着企业数字化转型加速,CRM系统成为提升竞争力的关键工具。国产CRM系统如销售易、神州云动、八骏科技等,以高性价比、本地化服务和灵活定制见长;国外CRM系统如Salesforce、Zoho CRM、Microsoft Dynamics 365等,则在功能创新、全球化支持和技术成熟度上表现突出。企业在选择时应综合考虑自身需求,选取最适合的CRM系统,助力业务高质量增长。
|
8天前
|
存储 前端开发 JavaScript
在线教育网课系统源码开发指南:功能设计与技术实现深度解析
在线教育网课系统是近年来发展迅猛的教育形式的核心载体,具备用户管理、课程管理、教学互动、学习评估等功能。本文从功能和技术两方面解析其源码开发,涵盖前端(HTML5、CSS3、JavaScript等)、后端(Java、Python等)、流媒体及云计算技术,并强调安全性、稳定性和用户体验的重要性。
|
2天前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
41 29

推荐镜像

更多