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*/@Overridepublic void insertFill(MetaObject metaObject) {this.setFieldValByName("gmtCreate",new Date(),metaObject);this.setFieldValByName("gmtModified",new Date(),metaObject);}/*** 修改时自动填充* @param metaObject*/@Overridepublic 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/beanshttp://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;@Beforepublic void init(){ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");userMapper=applicationContext.getBean("userMapper",UserMapper.class);}@Testpublic void test(){List<User> users = userMapper.selectList(null);//查询所有System.out.println(users);}@Testpublic 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、测试
/*** 测试乐观锁*/@Testpublic 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、测试
/*** 测试逻辑删除*/@Testpublic 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方法完成分页查询
/*** 测试分页查询*/@Testpublic 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%AEGlobalConfig 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%AEDataSourceConfig 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%AEPackageConfig 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%AEStrategyConfig 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_2autoGenerator.setStrategy(strategy);//执行自动生成autoGenerator.execute();}}
