MybatisPlus

        
            org.springframework.boot
            spring-boot-starter
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
            
                
                    org.junit.vintage
                    junit-vintage-engine
                
            
        
        
        
            com.baomidou
            mybatis-plus-boot-starter
            3.0.5
        
        
        
            mysql
            mysql-connector-java
        
        
        
            org.projectlombok
            lombok
        

引入mybatisplus 后就不需要引入mybatis和mybatis-spring了

lombok还需要安装插件才能使用


在application.properties里

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis-plus?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root

使用这个mysql8的驱动url需要加上时区


项目结构

启动类上需要加上

@MapperScan("com.xu.mpdemo1010.mapper")

这样就不需要在每一个mapper接口上加@Mapper了

mapper接口继承BaseMapper接口,就可以使用mybatisplus为我们提供的很多数据库操作的方法,只有特别复杂的sql才需要自己编写xml文件

public interface UserMapper extends BaseMapper

service接口需要继承IService接口,并且接口的实现类还需继承ServiceImpl,同样为我们提供了很多方法来使用。(若实现类不继承,那么需要重写所有的方法,很不方便)

service的实现类上需要加注解@Service交给spring容器管理,@Autowired注入XxxMapper,

return xxxMapper.方法

在controller需要加上@Controller注解用于页面跳转,或者@Restcontroller用于返回数据

@Autowired注入XxxService,调用方法


 mybatisplus自带的主键生成策略

 id是string类型就用下面那个MybatisPlus_第1张图片


mp的自动填充功能

表加上create_time和update_time两个字段

第一步添加实体类属性及注解:

        @TableField(fill = FieldFill.INSERT)//直接自动填充时间
        private Date createTime;

        @TableField(fill = FieldFill.INSERT_UPDATE)
        private Date updateTime;

第二步创建一个类实现MetaObjectHandler接口并重写方法

类上加@Component交给ioc容器管理

@Component//交给spring管理
public class MyMetaObjectHandler implements MetaObjectHandler {

    //使用mp实现添加操作时这个方法执行
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime", new Date(), metaObject);//三个参数属性名,属性值,源数据
        this.setFieldValByName("updateTime", new Date(), metaObject);

       
    }

    //使用mp实现修改操作时这个方法执行
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }
}
 
  

乐观锁

表加version字段,默认为1

原理:提交事务之前需比较当前版本号和数据库的版本号是否相同,不相同则不能修改。

还需将版本号加1,这样若是有正在拿相同版本号修改的人就改不了了,因为版本号加1了

第一步实体类加@Version

        @Version
        @TableField(fill = FieldFill.INSERT)//去方法里添加一个默认值1
        private Integer version;//版本号(用于乐观锁)

第二步编写一个配置类引入乐观锁插件

@Configuration//配置类
public class MpConfig {

    /**
     * 乐观锁插件
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }

}

也可以将启动类上面的

@MapperScan("com.xu.mpdemo1010.mapper")//扫描mapper包

放到这个配置类上,效果相同

第三步在实体类的属性version上加上,为了实现自动填充功能

@TableField(fill = FieldFill.INSERT)

第四步在上面讲到的自动填充功能的类中给version一个默认值1

@Component//交给spring管理
public class MyMetaObjectHandler implements MetaObjectHandler {

    //使用mp实现添加操作时这个方法执行
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime", new Date(), metaObject);//三个参数属性名,属性值,源数据
        this.setFieldValByName("updateTime", new Date(), metaObject);
        this.setFieldValByName("version", 1, metaObject);
    }

    //使用mp实现修改操作时这个方法执行
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }
}

分页

第一步在mp的配置类里引入分页插件

 /**
     *分页插件
    */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

第二步 

new一个page对象传入当前页和每页记录数(可以加泛型)

xxxService.Page(page,条件),得到的数据都存在page里(下面的实例没用到service层,只是测试)

    //分页查询(通过分页插件)
    @Test
    public void testPage() {
        Page page = new Page<>(1,3);//第一个参数是当前页,第二个参数是记录数
        //调用分页查询方法,在查询过程中底层会将查到的数据封装到page对象中
        userMapper.selectPage(page, null);

        //通过page对象获取分页数据
        System.out.println(page.getCurrent());//当前页
        System.out.println(page.getRecords());//每页数据list集合
        System.out.println(page.getSize());//每页显示记录数
        System.out.println(page.getTotal());//总记录数
        System.out.println(page.getPages());//总页数

        System.out.println(page.hasNext());//是否有下一页
        System.out.println(page.hasPrevious());//是否有上一页
    }


逻辑删除(加入这个功能以后进行删除操作就不删除数据而是置1,同样的mp框架自动在查询的时候不查1的数据)

(表中数据仍存在,但是处于删除状态无法查到)

第一步表中加入deleted字段

第二步实体类属性上加上注解

 @TableLogic//这个注解代表逻辑删除
 @TableField(fill = FieldFill.INSERT)
 private Integer deleted;

第三步在自动填充功能里加上(默认0表示未删除,1表示已删除)

这部分可以通过数据库对字段加默认值实现,两者取其一

this.setFieldValByName("deleted", 0, metaObject);
#逻辑删除字段为0表示未删除,1表示删除,0和1是默认值,下面两句可不写可用于自定义值
#mybatis-plus.global-config.db-config.logic-delete-value=1
#mybatis-plus.global-config.db-config.logic-not-delete-value=0

第四步配置类加入逻辑删除插件

/**
     *逻辑删除插件
     */
    @Bean
    public ISqlInjector sqlInjector() {
        return new LogicSqlInjector();
    }

如果需要查逻辑删除已删除的数据,只能通过自己写xml文件写sql语句来查,用mp提供的查不了


性能分析插件

第一步引入性能分析插件

    /**
     * SQL 执行性能分析插件
     * 开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长
     *dev开发环境
     *test测试环境
     *prod生产环境
     */
    @Bean
    @Profile({"dev","test"})// 设置 dev test 环境开启
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        performanceInterceptor.setMaxTime(500);//ms,超过此处设置的ms则sql不执行
        performanceInterceptor.setFormat(true);
        return performanceInterceptor;
    }

第二步设置当前环境为dev开发环境

#环境设置:dev、test、prod
spring.profiles.active=dev


wapper条件选择器

wapper是一个抽象类,通常用他的实现类queryWapper

测试

    //mp实现复杂查询操作
    @Test
    public void testSelectQuery() {

        //创建querywrapper对象
        QueryWrapper wrapper = new QueryWrapper<>();

        //通过wrapper设置条件
        //ge,gt,le,lt  >=  >  <=  <
        //查询age>=30
//        wrapper.ge("age", 30);//第一个参数字段,第二个参数值
//        List users = userMapper.selectList(wrapper);
//        System.out.println(users);


        //eq,ne   =   !=
//        wrapper.eq("name", "Sandy");
//        List users = userMapper.selectList(wrapper);
//        System.out.println(users);

        //between
//        wrapper.between("age", 20, 30);
//        List users = userMapper.selectList(wrapper);
//        System.out.println(users);


        //like
//        wrapper.like("name", "S");
//        List users = userMapper.selectList(wrapper);
//        System.out.println(users);

        //orderbydesc
//        wrapper.orderByDesc("id");
//        List users = userMapper.selectList(wrapper);
//        System.out.println(users);

        //last拼接语句
//        wrapper.last("limit 1");
//        List users = userMapper.selectList(wrapper);
//        System.out.println(users);

        //查询指定的列
        wrapper.select("id", "name");//只查所写字段
        List users = userMapper.selectList(wrapper);
        System.out.println(users);
    }
}


mp提供的代码生成器

第一步引入依赖(版本号自己找)



    org.apache.velocity
    velocity-engine-core

第二步执行代码


import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
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.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.Test;

/**
 * @author
 * @since 2018/12/13
 */
public class CodeGenerator {

    @Test
    public void run() {

        // 1、创建代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 2、全局配置,加上项目的绝对路径
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir("D:\\Spring\\gulischool\\guli_parent\\service\\service_edu" + "/src/main/java");

        gc.setAuthor("testjava");
        gc.setOpen(false); //生成后是否打开资源管理器
        gc.setFileOverride(false); //重新生成时文件是否覆盖

        gc.setServiceName("%sService");	//去掉Service接口的首字母I
        gc.setIdType(IdType.ID_WORKER_STR); //主键策略,这个表主键是字符类型,如果是long类型就不需要加_STR
        gc.setDateType(DateType.ONLY_DATE);//定义生成的实体类中日期类型
        gc.setSwagger2(true);//开启Swagger2模式

        mpg.setGlobalConfig(gc);

        // 3、数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/guli?serverTimezone=GMT%2B8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 4、包配置
        PackageConfig pc = new PackageConfig();

        pc.setParent("com.xu");
        pc.setModuleName("eduservice"); //模块名
        pc.setController("controller");
        pc.setEntity("entity");
        pc.setService("service");
        pc.setMapper("mapper");
        mpg.setPackageInfo(pc);

        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setInclude("edu_comment");//表名
        strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
        strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀

        strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
        strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作

        strategy.setRestControllerStyle(true); //restful api风格控制器
        strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符

        mpg.setStrategy(strategy);


        // 6、执行
        mpg.execute();
    }
}


注解

1.表名注解

@TableName("表名")用在实体类上面

2.主键注解

@TableIdMybatisPlus_第2张图片

 3.字段注解

@TableField数据库字段名

你可能感兴趣的:(spring,boot,java,mysql)