mybatis-plus
使用mybatis-plus一般用于做单表的增删改查,如果希望去做多表的连查,也可以自定义方法,自定义SQL去执行。
[MyBatis-Plus (opens new window)](https://github.com/baomidou/mybatis-plus)(简称 MP)是一个 [MyBatis (opens new window)](http://www.mybatis.org/mybatis-3/)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
对于单表的增删改查,mybatis-plus封装了对应的方法,直接调用即可实现对应的功能,无需编写SQL语句。
自动填充
1、导入依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.22</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.43</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
2、创建mapper层接口,接口需要继承BaseMapper接口,BaseMapper接口的泛型指定了当前mapper处理的数据类型
public interface UserMapper extends BaseMapper<User> {
}
3、编写实体类User
@Data
@TableName("t_user")//如果表名与类名不一致,使用@TableName指定当前实体类映射的数据库表名
public class User {
@TableId(type = IdType.AUTO)//指定主键生成策略
private Long id;
private String name;
private Integer age;
private String email;
@TableField(fill = FieldFill.INSERT)//指定自动填充策略
private Date gmtCreate;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date gmtModified;
}
4、mybatisplus通过MetaObjectHandler来处理自动填充,需要实现MetaObjectHandler接口
public class AutoFillUtil implements MetaObjectHandler {
/**
* 新增时自动填充
* @param metaObject
*/
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("gmtCreate",new Date(),metaObject);
this.setFieldValByName("gmtModified",new Date(),metaObject);
}
/**
* 修改时自动填充
* @param metaObject
*/
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("gmtModified",new Date(),metaObject);
}
}
5、编写spring的配置文件
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.woniuxy"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatisplus?characterEncoding=utf-8&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- 配置mybatisplus的sqlsessionfactorybean -->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--指定mybatisplus的全局配置-->
<property name="globalConfig" ref="globalConfig"/>
</bean>
<!--进行mybatisplus全局配置-->
<bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
<!--配置metaObjectHandler,用于实现自动填充-->
<property name="metaObjectHandler">
<bean class="com.woniuxy.utils.AutoFillUtil"/>
</property>
</bean>
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.woniuxy.mapper"/>
</bean>
</beans>
6、测试
public class MybatisPlusTest {
private UserMapper userMapper;
@Before
public void init(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
userMapper=applicationContext.getBean("userMapper",UserMapper.class);
}
@Test
public void test(){
List<User> users = userMapper.selectList(null);//查询所有
System.out.println(users);
}
@Test
public void testAdd(){
User entity = new User();
entity.setName("王五");
entity.setAge(35);
entity.setEmail("3@3.3");
System.out.println(entity);
userMapper.insert(entity);//执行新增
System.out.println(entity);
}
}
乐观锁
乐观锁 : 对一切操作保持乐观,它总是认为不会出现问题,无论干什么不去上锁!如果出现了问题,
再次更新值测试 。
悲观锁:对一切操作保持悲观,它总是认为会出现问题,无论干什么都会上锁!再去操作!
乐观锁实现方式:
1.数据库表中应该有version字段,用于记录当前数据的版本
2.从数据库中取出记录时,获取当前 version
3.更新时,带上获得的version
4.执行更新时, set version = newVersion where version = oldVersion ,如果version不对,就更新失败。
实现步骤:
1、修改数据库表,增加version字段
2、修改实体类,增加version属性,且在属性上加@Version注解
3、修改spring配置文件,在MybatisSqlSessionFactoryBean的plugins中增加加上乐观锁插件。
<!-- 配置mybatisplus的sqlsessionfactorybean -->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--指定mybatisplus的全局配置-->
<property name="globalConfig" ref="globalConfig"/>
<!--配置乐观锁插件-->
<property name="plugins">
<array>
<bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"/>
</array>
</property>
<!-- 配置mybatis的日志记录,输出在控制台 -->
<property name="configuration">
<bean class="com.baomidou.mybatisplus.core.MybatisConfiguration">
<property name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/>
</bean>
</property>
</bean>
3、测试
/**
* 测试乐观锁
*/
@Test
public void testUpdate(){
//线程1:想把ID为6的人改成张三丰
User user1 = userMapper.selectById(6L);//根据id查询记录
user1.setName("张三丰");
//线程2插队了:把ID为6的人改成张无忌
User user2=userMapper.selectById(6L);
user2.setName("张无忌");
//线程2插队成功,执行了修改
userMapper.updateById(user2);//根据ID修改数据库记录。
userMapper.updateById(user1);//线程1开始执行修改
}
逻辑删除
逻辑删除:如果配置了逻辑删除,则此时的删除操作都不会真正去执行delete语句,而是执行update。
注意:逻辑删除操作在mybatisplus高版本中,已被移除。
实现步骤
1、数据库表中添加字段deleted 默认值给个0,表示未删除状态,
2、在实体类中添加属性deleted,属性上加@TableLogic注解,表示启用逻辑删除
3、修改spring配置文件,在globalConfig配置sqlInjector,值使用LogicSqlInjector
<bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
<!--配置metaObjectHandler,用于实现自动填充-->
<property name="metaObjectHandler">
<bean class="com.woniuxy.utils.AutoFillUtil"/>
</property>
<!--配置逻辑删除-->
<property name="sqlInjector">
<bean class="com.baomidou.mybatisplus.extension.injector.LogicSqlInjector"/>
</property>
</bean>
4、测试
/**
* 测试逻辑删除
*/
@Test
public void testLogicDelete(){
userMapper.deleteById(1402517259338924034L);
}
分页插件
配置分页插件:mybatis-plus自带分页插件,不需要单独导入外部依赖。
实现步骤
1、配置分页插件
<!-- 配置mybatisplus的sqlsessionfactorybean -->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--指定mybatisplus的全局配置-->
<property name="globalConfig" ref="globalConfig"/>
<!--配置插件-->
<property name="plugins">
<array>
<!--分页插件-->
<bean class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"/>
<!--乐观锁插件-->
<bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"/>
</array>
</property>
<!-- 配置mybatis在控制台输出SQL -->
<property name="configuration">
<bean class="com.baomidou.mybatisplus.core.MybatisConfiguration">
<property name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/>
</bean>
</property>
</bean>
2、创建page对象,用于封装分页查询后得到的结果,并设置分页查询的条件,调用selectPage方法完成分页查询
/**
* 测试分页查询
*/
@Test
public void testPageQuery(){
//创建page对象,该对象创建时可以设置分页条件,
// 最终使用该对象来接收分页查询后得到的结果
Page<User> userPage = new Page<>(2,3);
//调用分页查询方法
userMapper.selectPage(userPage,null);
System.out.println(userPage.getTotal());//获取总记录数
System.out.println(userPage.getCurrent());//获取当前页码
System.out.println(userPage.getSize());//获取每页记录数
List<User> records = userPage.getRecords();//获取分页查询后的数据
records.forEach(System.out::println);
}
自动代码生成
导入依赖
<dependencies>
<!--mybatisplus自动代码生成时,需要基于velocity模板进行生成-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<!-- mp生成实体类时使用swagger2的注解,需要引入对应依赖 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.22</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.43</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
编写自动代码生成的工具类,进行相应的配置
/**
* 代码自动生成器
*/
public class MybatisPlusAutoCode {
public static void main(String[] args) {
//构建代码自动生成器对象
AutoGenerator autoGenerator = new AutoGenerator();
//配置自动生成策略
// 1、全局配置:
//https://baomidou.com/config/generator-config.html#%E5%85%A8%E5%B1%80%E7%AD%96%E7%95%A5-globalconfig-%E9%85%8D%E7%BD%AE
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir"); //获取当前项目所在目录
gc.setOutputDir(projectPath+"/20210610/src/main/java"); //自定义代码生成后的存放目录
gc.setAuthor("hujianying"); //设置项目作者
gc.setOpen(false); //代码生成后是否打开文件夹
gc.setFileOverride(false); //是否覆盖
gc.setServiceName("%sService"); //去Service的I前缀
gc.setIdType(IdType.ID_WORKER); //自定义主键生成策略
gc.setDateType(DateType.ONLY_DATE); //自定义日期类型
gc.setSwagger2(true); //实体使用swagger2注解
autoGenerator.setGlobalConfig(gc); //添加全局配置
//2、设置数据源:
// https://baomidou.com/config/generator-config.html#%E6%95%B0%E6%8D%AE%E6%BA%90-datasourceconfig-%E9%85%8D%E7%BD%AE
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/mall?characterEncoding=utf-8");
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("root");
dsc.setDbType(DbType.MYSQL); //指定数据库类型
autoGenerator.setDataSource(dsc); //添加数据源配置
//3、包名配置:
// https://baomidou.com/config/generator-config.html#%E5%8C%85%E5%90%8D%E9%85%8D%E7%BD%AE
PackageConfig pc = new PackageConfig();
//pc.setModuleName("rbac"); //指定生成的模块名称
pc.setParent("com.woniuxy"); //设置模块中的父目录名
pc.setEntity("model"); //设置实体类目录名
pc.setMapper("mapper"); //设置mapper目录名
pc.setService("service"); //设置service目录名
pc.setController("controller"); //设置controller目录名
autoGenerator.setPackageInfo(pc);
//4、数据库表配置:
// https://baomidou.com/config/generator-config.html#%E6%95%B0%E6%8D%AE%E5%BA%93%E8%A1%A8%E9%85%8D%E7%BD%AE
StrategyConfig strategy = new StrategyConfig();
// 设置要生成的实体类对应映射的表名
strategy.setInclude("t_goods","t_cart","t_user","t_order","t_order_item");
strategy.setTablePrefix("t_"); //去除表名前缀
//设置表名生成策略,下划线转驼峰
strategy.setNaming(NamingStrategy.underline_to_camel);
//设置列名生成策略,下划线转驼峰
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true); //自动lombok;
//strategy.setLogicDeleteFieldName("deleted"); //设置使用逻辑删除策略的属性名
// 自动填充配置 TableFill
//TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
//TableFill gmtModified = new TableFill("gmt_modified", FieldFill.INSERT_UPDATE);
//ArrayList<TableFill> tableFills = new ArrayList<>();
//tableFills.add(gmtCreate);
//tableFills.add(gmtModified);
//strategy.setTableFillList(tableFills);
//strategy.setVersionFieldName("version"); // 乐观锁
strategy.setRestControllerStyle(true); //生成 @RestController 控制器
strategy.setControllerMappingHyphenStyle(true); //驼峰转连字符--->localhost:8080/hello_id_2
autoGenerator.setStrategy(strategy);
//执行自动生成
autoGenerator.execute();
}
}