mybatis-plus也只是听过,但是终究没有使用过。因而本身花几天晚上的时间研究mybatis-plus的使用。前端
下面的研究也是基于其官网:http://mp.baomidou.com/guide/ 。官网的介绍很是详细。java
官网有基于springboot,也有基于spring的原始方式。下面基于原始的spring配置方式进行使用。若是有时间,未来会将本身的SSM项目转为springboot项目,而且整合MP与Redis缓存等操做。。。。。。。mysql
MyBatis-Plus(简称 MP)是一个 MyBatis 的加强工具,在 MyBatis 的基础上只作加强不作改变,为简化开发、提升效率而生。git
引入下面maven依赖以后会自动引入mybatis与mybats-spring,因此须要把原来的删掉github
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>2.0.1</version> </dependency>
参考:https://baomidou.gitee.io/mybatis-plus-doc/#/installweb
1.1我先附上原生的mybatis整合spring以及整合pagehelper插件的xml中的配置,而后两个作对比。spring
<!-- 0.链接池属性设置读取指定的properties文件 --> <context:property-placeholder location="classpath:db.properties" ignore-unresolvable="true"/> <!-- 1.将链接池放入spring容器 --> <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="driverClass" value="${jdbc.driver}"></property> <property name="user" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!--2. 配置 Mybatis的会话工厂 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 数据源 --> <property name="dataSource" ref="dataSource" /> <!-- 配置Mybatis的核心 配置文件所在位置 --> <property name="configLocation" value="classpath:SqlMapConfig.xml" /> <!-- 注意其余配置 --> <property name="plugins"> <array> <bean class="com.github.pagehelper.PageInterceptor"> <property name="properties"> <!--使用下面的方式配置参数,一行配置一个 --> <value> helperDialect=mysql reasonable=true </value> </property> </bean> </array> </property> </bean> <!-- 3.2经过MapperScannerConfigurer扫描进行批量生成代理对象 遵循规范:mapper.java和mapper.xml名字同样且在同一个目录下 自动扫描出来的代理对象的id为mapper类类名(首字母小写) --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 指定扫描的包名,若是有多个,用半角逗号分隔 --> <property name="basePackage" value="cn.xm.jwxt.mapper"></property> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> </bean>
1.2 MP整合的配置sql
下面配置能够替换上面1.1中的配置。可是须要注意分页因为是引用了MP的分页插件,因此会致使原来pagehelper的分页插件不生效。可是原来手写的mapper.xml是生效的,能够说是整合成功。数据库
<!-- 0.链接池属性设置读取指定的properties文件 --> <context:property-placeholder location="classpath:db.properties" ignore-unresolvable="true"/> <!-- 1.将链接池放入spring容器 --> <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="driverClass" value="${jdbc.driver}"></property> <property name="user" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- 配置实体扫描路径,多个package能够用分号; 逗号, 分隔, 支持通配符*--> <!-- com.a.b.entity;com.a.c.entity;com.d.*.entity--> <property name="typeAliasesPackage" value="cn.xm.jwxt.bean.*"/> <property name="configuration" ref="mybatisConfig"/> <!-- MP 全局配置注入 --> <property name="globalConfig" ref="globalConfig"/> <property name="plugins"> <array> <!-- 分页插件配置 --> <bean id="paginationInterceptor" class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"/> <!-- 性能拦截器,兼打印sql,不建议生产环境配置--> <bean id="performanceInterceptor" class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor"/> </array> </property> </bean> <bean id="mybatisConfig" class="com.baomidou.mybatisplus.MybatisConfiguration"> <property name="mapUnderscoreToCamelCase" value="true"/> </bean> <!-- 定义 MP 全局策略 --> <bean id="globalConfig" class="com.baomidou.mybatisplus.entity.GlobalConfiguration"> <!-- 主键策略配置 --> <!-- 可选参数 AUTO->`0`("数据库ID自增") INPUT->`1`(用户输入ID") ID_WORKER->`2`("全局惟一ID") UUID->`3`("全局惟一ID") --> <property name="idType" value="2"/> <!-- 数据库类型配置 --> <!-- 可选参数(默认mysql) MYSQL->`mysql` ORACLE->`oracle` DB2->`db2` H2->`h2` HSQL->`hsql` SQLITE->`sqlite` POSTGRE->`postgresql` SQLSERVER2005->`sqlserver2005` SQLSERVER->`sqlserver` --> <property name="dbType" value="mysql"/> <!-- 全局表为下划线命名设置 true --> <property name="dbColumnUnderline" value="true"/> </bean> <!-- 配置mybatis 扫描mapper接口的路径, 至关于注解@MapperScan,@MapperScan("com.baomidou.mybatisplus.test.h2.entity.mapper")--> <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="cn.xm.jwxt.mapper"/> </bean>
为了使用pageHelper的分页插件,咱们尝试将pageHelper的分页插件加入上面sqlsessionfactory中apache
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- 配置实体扫描路径,多个package能够用分号; 逗号, 分隔, 支持通配符*--> <!-- com.a.b.entity;com.a.c.entity;com.d.*.entity--> <property name="typeAliasesPackage" value="cn.xm.jwxt.bean.*"/> <property name="configuration" ref="mybatisConfig"/> <!-- MP 全局配置注入 --> <property name="globalConfig" ref="globalConfig"/> <property name="plugins"> <array> <!-- pageHelper的分页插件配置 --> <bean class="com.github.pagehelper.PageInterceptor"> <property name="properties"> <!--使用下面的方式配置参数,一行配置一个 --> <value> helperDialect=mysql reasonable=true </value> </property> </bean> <!--MP自带的分页插件--> <bean id="paginationInterceptor" class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"/> <!-- 性能拦截器,兼打印sql,不建议生产环境配置--> <bean id="performanceInterceptor" class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor"/> </array> </property> </bean>
通过证实上面的配置是能够的。也就是咱们能够用原来的pagehelper插件。
并且SQL性能拦截器也生效,以下:
虽然mybatis的日志功能也能够打出SQL以及参数,可是没有这个强大,下面是mybatis整合slf4j打出的SQL:
package cn.xm.jwxt.utils; import com.baomidou.mybatisplus.generator.AutoGenerator; import com.baomidou.mybatisplus.generator.InjectionConfig; 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; import java.util.HashMap; import java.util.Map; /** * <p> * 代码生成器演示 * </p> */ public class MpGenerator { /** * <p> * MySQL 生成演示 * </p> */ public static void main(String[] args) { AutoGenerator mpg = new AutoGenerator(); // 选择 freemarker 引擎,默认 Veloctiy // mpg.setTemplateEngine(new FreemarkerTemplateEngine()); // 全局配置 GlobalConfig gc = new GlobalConfig(); gc.setOutputDir("G://MP"); gc.setFileOverride(true); gc.setActiveRecord(false);// 不须要ActiveRecord特性的请改成false gc.setEnableCache(false);// XML 二级缓存 gc.setBaseResultMap(true);// XML ResultMap gc.setBaseColumnList(false);// XML columList // .setKotlin(true) 是否生成 kotlin 代码 gc.setAuthor("qlq"); // 自定义文件命名,注意 %s 会自动填充表实体属性! // gc.setMapperName("%sDao"); // gc.setXmlName("%sDao"); // gc.setServiceName("MP%sService"); // gc.setServiceImplName("%sServiceDiy"); // gc.setControllerName("%sAction"); mpg.setGlobalConfig(gc); // 数据源配置 DataSourceConfig dsc = new DataSourceConfig(); dsc.setDbType(DbType.MYSQL); dsc.setDriverName("com.mysql.jdbc.Driver"); dsc.setUsername("sa"); dsc.setPassword("123456"); dsc.setUrl("jdbc:mysql://localhost:3306/jwxt"); mpg.setDataSource(dsc); // 策略配置 StrategyConfig strategy = new StrategyConfig(); // strategy.setCapitalMode(true);// 全局大写命名 ORACLE 注意 strategy.setTablePrefix(new String[] { "tlog_", "tsys_" });// 此处能够修改成您的表前缀 strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略 // strategy.setInclude(new String[] { "user" }); // 须要生成的表 // strategy.setExclude(new String[]{"test"}); // 排除生成的表 // 自定义实体父类 // strategy.setSuperEntityClass("com.baomidou.demo.TestEntity"); // 自定义实体,公共字段 // strategy.setSuperEntityColumns(new String[] { "test_id", "age" }); // 自定义 mapper 父类 // strategy.setSuperMapperClass("com.baomidou.demo.TestMapper"); // 自定义 service 父类 // strategy.setSuperServiceClass("com.baomidou.demo.TestService"); // 自定义 service 实现类父类 // strategy.setSuperServiceImplClass("com.baomidou.demo.TestServiceImpl"); // 自定义 controller 父类 // strategy.setSuperControllerClass("com.baomidou.demo.TestController"); // 【实体】是否生成字段常量(默认 false) // public static final String ID = "test_id"; // strategy.setEntityColumnConstant(true); // 【实体】是否为构建者模型(默认 false) // public User setName(String name) {this.name = name; return this;} // strategy.setEntityBuilderModel(true); mpg.setStrategy(strategy); // 包配置 PackageConfig pc = new PackageConfig(); pc.setParent("cn.xm.mapper"); pc.setModuleName("module"); mpg.setPackageInfo(pc); // 注入自定义配置,能够在 VM 中使用 cfg.abc 【可无】 InjectionConfig cfg = 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); } }; mpg.setCfg(cfg); // 自定义模板配置,能够 copy 源码 mybatis-plus/src/main/resources/templates 下面内容修改, // 放置本身项目的 src/main/resources/templates 目录下, 默认名称一下能够不配置,也能够自定义模板名称 // TemplateConfig tc = new TemplateConfig(); // tc.setController("..."); // tc.setEntity("..."); // tc.setMapper("..."); // tc.setXml("..."); // tc.setService("..."); // tc.setServiceImpl("..."); // 如上任何一个模块若是设置 空 OR Null 将不生成该模块。 // mpg.setTemplate(tc); // 执行生成 mpg.execute(); // 打印注入设置【可无】 System.err.println(mpg.getCfg().getMap().get("abc")); } }
下面贴出生成的代码的结构:看的出来MP导出的时候是以模块进行分隔的,也就是先模块后三层架构,我习惯是先三层架构后模块(看目录名称就知道对应目录的东西),比mybatis的generator强大的是生成了对应的service目录和web目录,同时生成了对应的文件,都省下咱们手写了。并且也能够指定生成哪些表或者不生成哪些表。
咱们查看mapper和一个文件:(没有任何抽象方法,XML也没有任何SQL)
package cn.xm.mapper.module.mapper; import cn.xm.mapper.module.entity.ApArrangeCourseAudit; import com.baomidou.mybatisplus.mapper.BaseMapper; /** * <p> * Mapper 接口 * </p> * * @author qlq * @since 2018-11-20 */ public interface ApArrangeCourseAuditMapper extends BaseMapper<ApArrangeCourseAudit> { }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.xm.mapper.module.mapper.ApArrangeCourseAuditMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="cn.xm.mapper.module.entity.ApArrangeCourseAudit"> <id column="audit_id" property="audit_id" /> <result column="arrange_task_id" property="arrange_task_id" /> <result column="auditor_name" property="auditor_name" /> <result column="auditor_id" property="auditor_id" /> <result column="audit_time" property="audit_time" /> <result column="audit_suggestion" property="audit_suggestion" /> <result column="audit_result" property="audit_result" /> <result column="remark" property="remark" /> </resultMap> </mapper>
查看service目录和一个文件
package cn.xm.mapper.module.service; import cn.xm.mapper.module.entity.ApArrangeCourseAudit; import com.baomidou.mybatisplus.service.IService; /** * <p> * 服务类 * </p> * * @author qlq * @since 2018-11-20 */ public interface IApArrangeCourseAuditService extends IService<ApArrangeCourseAudit> { }
package cn.xm.mapper.module.service.impl; import cn.xm.mapper.module.entity.ApArrangeCourseAudit; import cn.xm.mapper.module.mapper.ApArrangeCourseAuditMapper; import cn.xm.mapper.module.service.IApArrangeCourseAuditService; import com.baomidou.mybatisplus.service.impl.ServiceImpl; import org.springframework.stereotype.Service; /** * <p> * 服务实现类 * </p> * * @author qlq * @since 2018-11-20 */ @Service public class ApArrangeCourseAuditServiceImpl extends ServiceImpl<ApArrangeCourseAuditMapper, ApArrangeCourseAudit> implements IApArrangeCourseAuditService { }
查看web目录以及查看文件:
package cn.xm.mapper.module.web; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * <p> * 前端控制器 * </p> * * @author qlq * @since 2018-11-20 */ @Controller @RequestMapping("/module/apArrangeCourseAudit") public class ApArrangeCourseAuditController { }
发现上面的控制层模板默认是SpringMVC。
上面Generator中能够设置这些的默认模板,咱们能够拷贝一个出来而后进行修改
// 自定义模板配置,能够 copy 源码 mybatis-plus/src/main/resources/templates 下面内容修改, // 放置本身项目的 src/main/resources/templates 目录下, 默认名称一下能够不配置,也能够自定义模板名称 // TemplateConfig tc = new TemplateConfig(); // tc.setController("..."); // tc.setEntity("..."); // tc.setMapper("..."); // tc.setXml("..."); // tc.setService("..."); // tc.setServiceImpl("..."); // 如上任何一个模块若是设置 空 OR Null 将不生成该模块。 // mpg.setTemplate(tc);
查看 TemplateConfig 类:
咱们再查看/template/controller.java.vm内容:
package ${package.Controller}; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; #if(${superControllerClassPackage}) import ${superControllerClassPackage}; #end /** * <p> * ${table.comment} 前端控制器 * </p> * * @author ${author} * @since ${date} */ @Controller @RequestMapping("#if(${package.ModuleName})/${package.ModuleName}#end/${table.entityPath}") #if(${superControllerClass}) public class ${table.controllerName} extends ${superControllerClass} { #else public class ${table.controllerName} { #end }
看了上面源码以后若是想修改模板就很简单了。
实际其超类 BaseMapper 已经包括了好多成熟的方法,相似hebernatetemplate,封装了基本的增删改查以及查询全部等操做。
关于其超类包装的方法只列出接口的抽象方法,具体的实现能够参考源码:
Dao层超类Mapper封装的基本方法。
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.baomidou.mybatisplus.mapper; import java.io.Serializable; import java.util.List; import java.util.Map; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.session.RowBounds; public interface BaseMapper<T> { Integer insert(T var1); Integer deleteById(Serializable var1); Integer deleteByMap(@Param("cm") Map<String, Object> var1); Integer delete(@Param("ew") Wrapper<T> var1); Integer deleteBatchIds(List<? extends Serializable> var1); Integer updateById(T var1); Integer update(@Param("et") T var1, @Param("ew") Wrapper<T> var2); T selectById(Serializable var1); List<T> selectBatchIds(List<? extends Serializable> var1); List<T> selectByMap(@Param("cm") Map<String, Object> var1); T selectOne(@Param("ew") T var1); Integer selectCount(@Param("ew") Wrapper<T> var1); List<T> selectList(@Param("ew") Wrapper<T> var1); List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> var1); List<Object> selectObjs(@Param("ew") Wrapper<T> var1); List<T> selectPage(RowBounds var1, @Param("ew") Wrapper<T> var2); List<Map<String, Object>> selectMapsPage(RowBounds var1, @Param("ew") Wrapper<T> var2); }
上面的wrapper是mybatis封装查询条件的超类,在本版本的MP中是用EntityWrapper封装条件。
下面研究简单的使用:
0.环境准备:(导出一个表便可)
package cn.xm.jwxt.ceshi; import java.util.HashMap; import java.util.Map; import com.baomidou.mybatisplus.generator.AutoGenerator; import com.baomidou.mybatisplus.generator.InjectionConfig; 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; /** * <p> * 代码生成器演示 * </p> */ public class MpGenerator { /** * <p> * MySQL 生成演示 * </p> */ public static void main(String[] args) { AutoGenerator mpg = new AutoGenerator(); // 选择 freemarker 引擎,默认 Veloctiy // mpg.setTemplateEngine(new FreemarkerTemplateEngine()); // 全局配置 GlobalConfig gc = new GlobalConfig(); gc.setOutputDir("G://MP"); gc.setFileOverride(true); gc.setActiveRecord(false);// 不须要ActiveRecord特性的请改成false gc.setEnableCache(false);// XML 二级缓存 gc.setBaseResultMap(true);// XML ResultMap gc.setBaseColumnList(false);// XML columList // .setKotlin(true) 是否生成 kotlin 代码 gc.setAuthor("qlq"); // 自定义文件命名,注意 %s 会自动填充表实体属性! // gc.setMapperName("%sDao"); // gc.setXmlName("%sDao"); // gc.setServiceName("MP%sService"); // gc.setServiceImplName("%sServiceDiy"); // gc.setControllerName("%sAction"); mpg.setGlobalConfig(gc); // 数据源配置 DataSourceConfig dsc = new DataSourceConfig(); dsc.setDbType(DbType.MYSQL); dsc.setDriverName("com.mysql.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("123456"); dsc.setUrl("jdbc:mysql://localhost:3306/jwxt"); mpg.setDataSource(dsc); // 策略配置 StrategyConfig strategy = new StrategyConfig(); // strategy.setCapitalMode(true);// 全局大写命名 ORACLE 注意 // strategy.setTablePrefix(new String[] { "tlog_", "tsys_" });// 此处能够修改成您的表前缀 // strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略 strategy.setInclude(new String[] { "user" }); // 须要生成的表 // strategy.setExclude(new String[]{"test"}); // 排除生成的表 // 自定义实体父类 // strategy.setSuperEntityClass("com.baomidou.demo.TestEntity"); // 自定义实体,公共字段 // strategy.setSuperEntityColumns(new String[] { "test_id", "age" }); // 自定义 mapper 父类 // strategy.setSuperMapperClass("com.baomidou.demo.TestMapper"); // 自定义 service 父类 // strategy.setSuperServiceClass("com.baomidou.demo.TestService"); // 自定义 service 实现类父类 // strategy.setSuperServiceImplClass("com.baomidou.demo.TestServiceImpl"); // 自定义 controller 父类 // strategy.setSuperControllerClass("com.baomidou.demo.TestController"); // 【实体】是否生成字段常量(默认 false) // public static final String ID = "test_id"; // strategy.setEntityColumnConstant(true); // 【实体】是否为构建者模型(默认 false) // public User setName(String name) {this.name = name; return this;} // strategy.setEntityBuilderModel(true); mpg.setStrategy(strategy); // 包配置 PackageConfig pc = new PackageConfig(); pc.setParent("cn.xm.jwxt"); pc.setModuleName("ceshi"); mpg.setPackageInfo(pc); // 注入自定义配置,能够在 VM 中使用 cfg.abc 【可无】 InjectionConfig cfg = 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); } }; mpg.setCfg(cfg); // 自定义模板配置,能够 copy 源码 mybatis-plus/src/main/resources/templates 下面内容修改, // 放置本身项目的 src/main/resources/templates 目录下, 默认名称一下能够不配置,也能够自定义模板名称 // TemplateConfig tc = new TemplateConfig(); // tc.setController("..."); // tc.setEntity("..."); // tc.setMapper("..."); // tc.setXml("..."); // tc.setService("..."); // tc.setServiceImpl("..."); // 如上任何一个模块若是设置 空 OR Null 将不生成该模块。 // mpg.setTemplate(tc); // 执行生成 mpg.execute(); // 打印注入设置【可无】 System.err.println(mpg.getCfg().getMap().get("abc")); } }
applicationContext-dao.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd "> <!-- 0.链接池属性设置读取指定的properties文件 --> <context:property-placeholder location="classpath:db.properties" ignore-unresolvable="true"/> <!-- 1.将链接池放入spring容器 --> <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="driverClass" value="${jdbc.driver}"></property> <property name="user" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- 配置实体扫描路径,多个package能够用分号; 逗号, 分隔, 支持通配符*--> <!-- com.a.b.entity;com.a.c.entity;com.d.*.entity--> <property name="typeAliasesPackage" value="cn.xm.jwxt.*"/> <property name="configuration" ref="mybatisConfig"/> <!-- MP 全局配置注入 --> <property name="globalConfig" ref="globalConfig"/> <property name="plugins"> <array> <!-- pageHelper的分页插件配置 --> <bean class="com.github.pagehelper.PageInterceptor"> <property name="properties"> <!--使用下面的方式配置参数,一行配置一个 --> <value> helperDialect=mysql reasonable=true </value> </property> </bean> <!--MP自带的分页插件--> <bean id="paginationInterceptor" class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"/> <!-- 性能拦截器,兼打印sql,不建议生产环境配置--> <bean id="performanceInterceptor" class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor"/> </array> </property> </bean> <bean id="mybatisConfig" class="com.baomidou.mybatisplus.MybatisConfiguration"> <property name="mapUnderscoreToCamelCase" value="false"/> </bean> <!-- 定义 MP 全局策略 --> <bean id="globalConfig" class="com.baomidou.mybatisplus.entity.GlobalConfiguration"> <!-- 主键策略配置 --> <!-- 可选参数 AUTO->`0`("数据库ID自增") INPUT->`1`(用户输入ID") ID_WORKER->`2`("全局惟一ID") UUID->`3`("全局惟一ID") --> <property name="idType" value="1"/> <!-- 数据库类型配置 --> <!-- 可选参数(默认mysql) MYSQL->`mysql` ORACLE->`oracle` DB2->`db2` H2->`h2` HSQL->`hsql` SQLITE->`sqlite` POSTGRE->`postgresql` SQLSERVER2005->`sqlserver2005` SQLSERVER->`sqlserver` --> <property name="dbType" value="mysql"/> <!-- 全局表为下划线命名设置 true --> <property name="dbColumnUnderline" value="false"/> </bean> <!-- 配置mybatis 扫描mapper接口的路径, 至关于注解@MapperScan,@MapperScan("com.baomidou.mybatisplus.test.h2.entity.mapper")--> <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="cn.xm.jwxt"/> </bean> <!-- 4.配置事务管理器 --> <!-- 事务核心管理器,封装了事务操做,依赖于链接池 --> <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 5.开启注解管理aop事务 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- 6.开启注解AOP (前提是引入aop命名空间和相关jar包) --> <aop:aspectj-autoproxy expose-proxy="true" proxy-target-class="true"></aop:aspectj-autoproxy> <!-- 7.开启aop,对类代理强制使用cglib代理 --> <aop:config proxy-target-class="true"></aop:config> <!-- 8.扫描 @Service @Component 注解--> <context:component-scan base-package="cn.xm.jwxt" ></context:component-scan> </beans>
注意:对导出的表的实体,最好加上主键列在数据库中的列名称,不然调用MP本身的方法设计到主键操做的时候会报错语句绑定错误。以下
1.测试简单的增长:
package cn.xm.jwxt.ceshi; import java.sql.SQLException; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import cn.xm.jwxt.ceshi.entity.User; import cn.xm.jwxt.ceshi.mapper.UserMapper; /** * @Author: qlq * @Description * @Date: 22:06 2018/11/22 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:application*.xml") public class MpTest { @Autowired private UserMapper userMapper1; @Test public void test1() throws SQLException { User user = new User(); user.setUserName("username"); user.setUserID("ceshi"); user.setPassword("111222"); userMapper1.insert(user); } }
结果:
Time:581 ms - ID:cn.xm.jwxt.ceshi.mapper.UserMapper.insert SQL Params:['ceshi', 'username', '111222'] Execute SQL:INSERT INTO user ( userID, userName, `password` ) VALUES ( ?, ?, ? )
(0)调用MP本身的根据主键查询,查询单个和查询多个
@Test public void test1() throws SQLException { // 查询单个 User selectById = userMapper1.selectById("ceshi"); System.out.println(selectById); // 批量查询 List<String> idList = new ArrayList<String>(); idList.add("ceshi"); idList.add("ceshi2"); List<User> selectBatchIds = userMapper1.selectBatchIds(idList); System.out.println(selectBatchIds); // 根据map条件查询,map中封装的是数据的列的条件 Map<String, Object> columnMap = new HashMap<>(); columnMap.put("userId", "ceshi"); List<User> selectByMap = userMapper1.selectByMap(columnMap); System.out.println(selectByMap); }
结果:
mybatis-plus init success.
Time:235 ms - ID:cn.xm.jwxt.ceshi.mapper.UserMapper.selectById
SQL Params:['ceshi']
Execute SQL:SELECT userId AS userID,userCode,userName,`password`,userSort,userStuTeaNum,userUnitName,userUnitNum,isUse,remark1 FROM user WHERE userId=?
User [userID=ceshi, userCode=null, userName=username, password=111222, userSort=null, userStuTeaNum=null, userUnitName=null, userUnitNum=null, isUse=null, remark1=null]
Time:16 ms - ID:cn.xm.jwxt.ceshi.mapper.UserMapper.selectBatchIds
SQL Params:['ceshi', 'ceshi2']
Execute SQL:SELECT userId AS userID,userCode,userName,`password`,userSort,userStuTeaNum,userUnitName,userUnitNum,isUse,remark1 FROM user WHERE userId IN ( ? , ? )
[User [userID=ceshi, userCode=null, userName=username, password=111222, userSort=null, userStuTeaNum=null, userUnitName=null, userUnitNum=null, isUse=null, remark1=null], User [userID=ceshi2, userCode=null, userName=username, password=111222, userSort=null, userStuTeaNum=null, userUnitName=null, userUnitNum=null, isUse=null, remark1=null]]
Time:20 ms - ID:cn.xm.jwxt.ceshi.mapper.UserMapper.selectByMap
SQL Params:['ceshi']
Execute SQL:SELECT userId AS userID,userCode,userName,`password`,userSort,userStuTeaNum,userUnitName,userUnitNum,isUse,remark1 FROM user WHERE userId = ?
[User [userID=ceshi, userCode=null, userName=username, password=111222, userSort=null, userStuTeaNum=null, userUnitName=null, userUnitNum=null, isUse=null, remark1=null]]
(1)封装Wrapper进行查询:
@Test public void test1() throws SQLException { // 批量查询 // 构造实体对应的 EntityWrapper 对象,进行过滤查询 EntityWrapper<User> ew = new EntityWrapper<>(); ew.where("userId={0}", "ceshi").like("username", "user"); List<User> selectList = userMapper1.selectList(ew); System.out.println(selectList); }
咱们查看 EntityWrapper 的源码: (其更多的方法是封装在其父类Wrapper中 )
/** <a href="http://www.cpupk.com/decompiler">Eclipse Class Decompiler</a> plugin, Copyright (c) 2017 Chen Chao. */ package com.baomidou.mybatisplus.mapper; import com.baomidou.mybatisplus.toolkit.ReflectionKit; import com.baomidou.mybatisplus.toolkit.StringUtils; /** * <p> * Entity 对象封装操做类,定义T-SQL语法 * </p> * * @author hubin , yanghu , Dyang , Caratacus * @Date 2016-11-7 */ @SuppressWarnings("serial") public class EntityWrapper<T> extends Wrapper<T> { /** * 拼接WHERE后应该是AND仍是OR */ private String AND_OR = "AND"; /** * 数据库表映射实体类 */ protected T entity = null; public EntityWrapper() { /* 注意,传入查询参数 */ } public EntityWrapper(T entity) { this.entity = entity; } public EntityWrapper(T entity, String sqlSelect) { this.entity = entity; this.sqlSelect = sqlSelect; } public T getEntity() { return entity; } public void setEntity(T entity) { this.entity = entity; } /** * <p> * 添加OR条件 * </p> * * @param sqlOr * or 条件语句 * @param params * 参数集 * @return this */ @Override public Wrapper<T> or(String sqlOr, Object... params) { if (StringUtils.isEmpty(sql.toString())) { AND_OR = "OR"; } super.or(sqlOr, params); return this; } /** * <p> * 使用OR换行,并添加一个带()的新的条件 * </p> * <p> * eg: ew.where("name='zhangsan'").and("id=11").orNew("statu=1"); 输出: WHERE * (name='zhangsan' AND id=11) OR (statu=1) * </p> * * @param sqlOr * AND 条件语句 * @param params * 参数值 * @return this */ @Override public Wrapper<T> orNew(String sqlOr, Object... params) { if (StringUtils.isEmpty(sql.toString())) { AND_OR = "OR"; } super.orNew(sqlOr, params); return this; } /** * SQL 片断 */ @Override public String getSqlSegment() { /* * 无条件 */ String sqlWhere = sql.toString(); if (StringUtils.isEmpty(sqlWhere)) { return null; } /* * 根据当前实体判断是否须要将WHERE替换成 AND 增长实体不为空但全部属性为空的状况 */ sqlWhere = ReflectionKit.checkFieldValueNotNull(entity) ? sqlWhere.replaceFirst("WHERE", AND_OR) : sqlWhere; return sqlWhere; } }
补充:wrapper还有好对条件可使用,in、order等均可以,例如:
EntityWrapper<User> ew = new EntityWrapper<>(); ew.where("userId={0}", "ceshi").like("username", "user").in("", new ArrayList<>()).exists("") .setSqlSelect(" xx = xx").orderBy("sss", false).notIn("", new ArrayList<>());
(2)分页查询(实际是逻辑分页,所有查出以后进行筛选)
// 传一个空对象或者传null查全部 EntityWrapper<User> ew = new EntityWrapper<>(); ew.orderBy("userId"); Integer selectCount = userMapper1.selectCount(ew); System.out.println(selectCount); List<User> selectPage = userMapper1.selectPage(new RowBounds(0, 5), ew); System.out.println(selectPage);
结果::
mybatis-plus init success.
Time:240 ms - ID:cn.xm.jwxt.ceshi.mapper.UserMapper.selectCount
SQL Params:[]
Execute SQL:SELECT COUNT(1) FROM user ORDER BY userId
8
Time:31 ms - ID:cn.xm.jwxt.ceshi.mapper.UserMapper.selectPage
SQL Params:[]
Execute SQL:SELECT userId AS userID,userCode,userName,`password`,userSort,userStuTeaNum,userUnitName,userUnitNum,isUse,remark1 FROM user ORDER BY userId
Page{count=false, pageNum=1, pageSize=5, startRow=0, endRow=5, total=-1, pages=1, reasonable=false, pageSizeZero=false}
(3)查询结果映射为Map的查询方法:
List<Map<String, Object>> selectMaps = userMapper1.selectMaps(null); System.out.println(selectMaps); List<Map<String, Object>> selectMapsPage = userMapper1.selectMapsPage(new RowBounds(0, 5), null); System.out.println(selectMapsPage);
结果:
mybatis-plus init success.
[{userID=3c51dd8f9dc04315b97a34f9a939f3b9, userCode=2014223, isUse=1, userName=lll, userUnitNum=Soft0102, password=123456, userUnitName=软件工程教研室111, userSort=教师}, {userID=5ea97f30d605410da4e00df52c2fedc4, userCode=院长, isUse=1, userName=院长, userUnitNum=无, password=123, userUnitName=无, userSort=教师}, {userID=a9e65788297e4a8cb68a369522ee5af7, userCode=123, isUse=1, userName=培养方案, userUnitNum=无, password=123, userUnitName=无, userSort=教师}, {userID=b33b938faada40aeac2b5ca228336473, userCode=root, isUse=1, userName=超级管理员, userUnitNum=超管, password=root, userUnitName=超管, userSort=教师}, {userID=c43aeab8a15c427e81fda9b6e55571c4, userCode=教研室主任, isUse=1, userName=教研室主任, userUnitNum=无, password=123, userUnitName=无, userSort=教师}, {userID=ceshi, userName=username, password=111222}, {userID=ceshi2, userName=username, password=111222}, {userID=e0973fd895bf4d93bd116f18512b461b, userCode=1, isUse=1, userName=1, userUnitNum=无, password=1, userUnitName=无, userSort=学生}]
Time:349 ms - ID:cn.xm.jwxt.ceshi.mapper.UserMapper.selectMaps
SQL Params:[]
Execute SQL:SELECT userId AS userID,userCode,userName,`password`,userSort,userStuTeaNum,userUnitName,userUnitNum,isUse,remark1 FROM user
Page{count=false, pageNum=1, pageSize=5, startRow=0, endRow=5, total=-1, pages=1, reasonable=false, pageSizeZero=false}
Time:30 ms - ID:cn.xm.jwxt.ceshi.mapper.UserMapper.selectMapsPage
SQL Params:[]
Execute SQL:SELECT userId AS userID,userCode,userName,`password`,userSort,userStuTeaNum,userUnitName,userUnitNum,isUse,remark1 FROM user
@Test public void test1() throws SQLException { // 修改单个 User entity = new User(); entity.setUserID("ceshi"); entity.setUserName("userName2"); userMapper1.updateById(entity); // 批量修改,第二个是条件 User entity2 = new User(); entity2.setPassword("8888"); Integer update = userMapper1.update(entity2, new EntityWrapper<User>()); }
查看打出的SQL:
mybatis-plus init success.
Time:236 ms - ID:cn.xm.jwxt.ceshi.mapper.UserMapper.updateById
SQL Params:['userName2', 'ceshi']
Execute SQL:UPDATE user SET userName=? WHERE userId=?
Time:250 ms - ID:cn.xm.jwxt.ceshi.mapper.UserMapper.update
SQL Params:['8888']
Execute SQL:UPDATE user SET `password`=?
// 删除单个 Integer deleteById = userMapper1.deleteById("ceshi"); // 批量删除 List<String> idList = new ArrayList<>(); idList.add("ceshi"); idList.add("ceshi2"); Integer deleteBatchIds = userMapper1.deleteBatchIds(idList); // 根据列批量删除 Map<String, Object> condition = new HashMap<>(); condition.put("username", "username"); Integer deleteByMap = userMapper1.deleteByMap(condition); // Wrapper传条件删除 EntityWrapper ew = new EntityWrapper<User>(); ew.and("username={0}", "username"); Integer delete = userMapper1.delete(ew);
结果:
mybatis-plus init success.
Time:326 ms - ID:cn.xm.jwxt.ceshi.mapper.UserMapper.deleteById
SQL Params:['ceshi']
Execute SQL:DELETE FROM user WHERE userId=?
Time:147 ms - ID:cn.xm.jwxt.ceshi.mapper.UserMapper.deleteBatchIds
SQL Params:['ceshi', 'ceshi2']
Execute SQL:DELETE FROM user WHERE userId IN ( ? , ? )
Time:4 ms - ID:cn.xm.jwxt.ceshi.mapper.UserMapper.deleteByMap
SQL Params:['username']
Execute SQL:DELETE FROM user WHERE username = ?
Time:4 ms - ID:cn.xm.jwxt.ceshi.mapper.UserMapper.delete
SQL Params:[]
Execute SQL:DELETE FROM user WHERE (username='username')
与普通的mybatis开发同样,也是接口中声明方法,XML中写对应的SQL
package cn.xm.jwxt.ceshi.mapper; import cn.xm.jwxt.ceshi.entity.User; import org.apache.ibatis.annotations.Param; import com.baomidou.mybatisplus.mapper.BaseMapper; /** * <p> * Mapper 接口 * </p> * * @author qlq * @since 2018-11-24 */ public interface UserMapper extends BaseMapper<User> { public User select(@Param("id") String idString); }
(2)xml中写SQL
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.xm.jwxt.ceshi.mapper.UserMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="cn.xm.jwxt.ceshi.entity.User"> <id column="userID" property="userID" /> <result column="userCode" property="userCode" /> <result column="userName" property="userName" /> <result column="password" property="password" /> <result column="userSort" property="userSort" /> <result column="userStuTeaNum" property="userStuTeaNum" /> <result column="userUnitName" property="userUnitName" /> <result column="userUnitNum" property="userUnitNum" /> <result column="isUse" property="isUse" /> <result column="remark1" property="remark1" /> </resultMap> <select id="select" parameterType="string" resultType="user"> select * from user where userId = #{id} </select> </mapper>
(3)测试
@Test public void test1() throws SQLException { User select = userMapper1.select("ceshi"); System.out.println(select); }
结果:
Time:440 ms - ID:cn.xm.jwxt.ceshi.mapper.UserMapper.select
SQL Params:['ceshi']
Execute SQL:select * from user where userId = ?
cn.xm.jwxt.ceshi.entity.User@1f7c1b71