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' )