MybatisPlus

  • Post author:
  • Post category:其他


1.不用写mapper.xml映射文件,让接口继承自basemapper即可。

数据库中表的字段必须和user类中的字段一摸一样,数据库中的表必须叫user

只能进行简单的crud操作。

package com.atguigu.rj1192.springboot630.mapper;

import com.atguigu.rj1192.springboot630.pojo.User;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

//只需要继承自basemapper接口,就可以实现该方法
//数据库中有一个user表,对应我们的user类
//@Mapper
public interface UserMapper extends BaseMapper <User>{
}

2.当实体类和表名不一致时,可以在实体类指定表名

package com.atguigu.rj1192.springboot630.pojo;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Data
@ToString
@TableName("users")//当实体类和表名不一致的时候,用@tablename来指定表名
public class User {
    @TableField(exist = false)
    public String tons;//类中有,但是表中没有的属性
    public int id;
    public String username;
    public String password;
}

2.service层

userservice接口要继承自IService<User>

package com.atguigu.rj1192.springboot630.service.impl;

import com.atguigu.rj1192.springboot630.pojo.User;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.stereotype.Service;

import java.util.Collection;

@Service
public interface UserService extends IService<User> {

}

Userserviceimpl实现类要继承自ServiceImpl<UserMapper,User>

第一个参数代表要使用哪个mappper映射文件

第二个参数代表要操作的数据类型

package com.atguigu.rj1192.springboot630.service;

import com.atguigu.rj1192.springboot630.mapper.UserMapper;
import com.atguigu.rj1192.springboot630.pojo.User;
import com.atguigu.rj1192.springboot630.service.impl.UserService;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
//第一个参数代表要使用哪个mappper映射文件
//第二个参数代表要操作的数据类型
public class UserServiceimpl extends ServiceImpl<UserMapper,User>  implements UserService{

}

controller层调用的时候

    @RequestMapping("/")
    public ModelAndView index() {
        ModelAndView mav = new ModelAndView();
        mav.setViewName("index");
//        将要查询出来的user类型的数据,转换成wrapper类型。
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        Collection<User> users=userService.list(wrapper);
        mav.addObject("users", users);
        return mav;
    }

3.mybatisplus主键自增

IdType.INPUT IdType.None 不自增 ,需要用户设置id,一般用input

IdType.ASSIGN_UUID varchar类型     IdType.ASSIGN_ID bigint类型 雪花算法生成随机id

插入新数据时不用管id,会自增的。

其他的主键自增方法还有:

1》mysql自增,缺点是如果做了分库分表,需要查询最大的id后,+1才能插入新数据,比较耗时间

2》uuid 缺点是无法排序,每次都生成唯一且随机的

3》redis集群 原子操作

@Data
public class User {
//    IdType.INPUT IdType.None 不自增 ,需要用户设置id,一般用input
//    IdType.ASSIGN_UUID varchar类型     IdType.ASSIGN_ID bigint类型 雪花算法生成随机id
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    private Integer age;
    private String email;

    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    //    添加和修改时都有值

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

4.mybatisplus修改时间和添加时间自动填充


(1)数据库表中添加自动填充字段

在User表中添加datetime类型的新的字段 create_time、update_time


(2)实体上添加注解


FieldFill.INSERT  在插入新数据时执行对应的方法(第三步定义)


FieldFill.INSERT_UPDATE 在插入和更新数据时执行对应的方法(第三步定义)

@Data
public class User {
//    IdType.INPUT IdType.None 不自增 ,需要用户设置id,一般用input
//    IdType.ASSIGN_UUID varchar类型     IdType.ASSIGN_ID bigint类型 雪花算法生成随机id
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    private Integer age;
    private String email;

    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    //    添加和修改时都有值

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

(3)编写实际的填充类和填充方法


@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyMetaObjectHandler.class);

    //使用mp执行添加操作,会执行
    @Override
    public void insertFill(MetaObject metaObject) {//MetaObject 原数据对象  数据库名 表名等信息
        LOGGER.info("开始添加填充 ....");
//注意:这里的字段名是类中的名称,不是数据库中的字段!!!!
        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }

    //    使用mp执行更新操作,会执行
    @Override
    public void updateFill(MetaObject metaObject) {
        LOGGER.info("开始更新填充 ....");
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }

}

(4)在修改和插入时就会自动填充修改时间和插入时间。

    @Test
    void updateuser() {
        User user = new User();
//        不需要去设置id值,mp会帮我们自动生成id值
        user.setAge(555);
        user.setId(102l);
        //        返回结果是影响的行数
        System.out.println("修改影响的行数:" + userMapper.updateById(user));
    }

5.mybatisplus设置乐观锁

mike工资是五千 管理员a 要将工资修改为8000       管理员b要将工资减少两千

a和b同时修改,同时拿到修改前的5000

a修改工资为8000,提交事务。

a提交事务后,b修改工资5000-2000=3000,b将工资修改为3000

mike的工资变成了3000,而不是6000,就造成了丢失更新问题

乐观锁和悲观锁可以解决丢失更新问题

乐观锁:设置一个版本号,管理员在修改数据前,需要先获得版本号

管理员a和b同时获得1版本,a修改完了提交,数据变成2版本,b修改完了提交,发现数据已经变成2版本了,则b管理员提交失败。

悲观锁:不允许两个管理员同时修改一条数据,必须等一个修改完一个才能修改

1》数据库中添加version字段 bigint类型

2》实体类中添加version字段,并添加@Version注解

并通过@TableField(fill = FieldFill.INSERT)设置添加新记录时给verison默认值1


@Data
public class User {
    //    IdType.INPUT IdType.None 不自增 ,需要用户设置id,一般用input
//    IdType.ASSIGN_UUID varchar类型     IdType.ASSIGN_ID bigint类型 雪花算法生成随机id
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    private Integer age;
    private String email;

    @Version
    @TableField(fill = FieldFill.INSERT)
    private Integer version;

    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    //    添加和修改时都有值

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

设置添加新记录时给verison默认值1

this.setFieldValByName(“version”, 1, metaObject);

(上面添加新纪录时间自动填充的步骤一样)

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyMetaObjectHandler.class);

    //使用mp执行添加操作,会执行
    @Override
    public void insertFill(MetaObject metaObject) {//MetaObject 原数据对象  数据库名 表名等信息
        LOGGER.info("开始添加填充 ....");
        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
        this.setFieldValByName("version", 1, metaObject);
    }

    //    使用mp执行更新操作,会执行
    @Override
    public void updateFill(MetaObject metaObject) {
        LOGGER.info("开始更新填充 ....");
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }

3》配置乐观锁插件

在mybatisplus设置类中 设置乐观锁插件

(在这个类中配置@mapperscan注解,这个注解尽量不写在启动类上,而是写在mp配置类中。)

@MapperScan("com.example.mp1229.mapper")
@Configuration
public class MPconfig {
//    乐观锁插件
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

4》需要先查询出来,再修改    在修改之后,会发现该数据的verision增加了1

    //测试乐观锁
    @Test
    void testOptimisticLocker() {
        User user = userMapper.selectById(102l);
//        不需要去设置id值,mp会帮我们自动生成id值
        user.setAge(10);
        //        返回结果是影响的行数
        System.out.println("修改影响的行数:" + userMapper.updateById(user));
    }

模拟取出数据后,数据库中version实际数据比取出的值大,即已被其它线程修改并更新了version

    //测试乐观锁
    @Test
    void testOptimisticLocker() {
        User user = userMapper.selectById(102l);
//        不需要去设置id值,mp会帮我们自动生成id值
        user.setAge(10);
//       模拟取出数据后,数据库中version实际数据比取出的值大,即已被其它线程修改并更新了version
        user.setVersion(user.getVersion()-1);
        //        返回结果是影响的行数
        System.out.println("修改影响的行数:" + userMapper.updateById(user));
    }

6.逻辑删除(mp3.3.0版本后)

逻辑删除:假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录


1)数据库中添加 deleted字段

2)mybatisplus实体类中添加deleted字段,并设置默认值 0 (未删除)   和上面一样。

user类

    @TableField(fill = FieldFill.INSERT)
    private Integer deleted;
MyMetaObjectHandler类
  //使用mp执行添加操作,会执行
    @Override
    public void insertFill(MetaObject metaObject) {//MetaObject 原数据对象  数据库名 表名等信息
        LOGGER.info("开始添加填充 ....");
        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
        this.setFieldValByName("version", 1, metaObject);
//        添加新数据时,逻辑已删除值设置为0,未删除
        this.setFieldValByName("deleted",0,metaObject);
    }

3)application.yaml配置逻辑删除字段,删除和未删除对应的 逻辑值

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: deleted # 全局逻辑删除的实体字段名( 3.3.0 版本后,配置后可以忽略不配置步骤2)
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

4)使用deletebyid 删除即可


    @Test
    void logcaldel(){
        int result=userMapper.deleteById(1608419885151080450l);
        System.out.println("逻辑删除结果"+result);
    }
5)查询所有 会自动携带查询deleted为0的数据
@Test
void findall() {
    System.out.println(userMapper.selectList(null));
}

7.逻辑删除(mp3.0.5版本)

1.引入逻辑删除插件

//项目的总配置类
@MapperScan("com.atguigu.eduservice.mapper")
@Configuration
public class EduConfig {
    //    逻辑删除插件
    @Bean
    public ISqlInjector sqlInjector() {
        return new LogicSqlInjector();
    }
}

2.逻辑删除属性上加@login注解

 @TableLogic
    private Boolean isDeleted;

8.分页插件

1》在配置类中加入分页插件

//项目的总配置类
@MapperScan("com.atguigu.eduservice.mapper")
@Configuration
public class EduConfig {

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

2.使用时实现page对象

 Page<EduTeacher> pageTeacher = new Page<>(current, limit);
        eduTeacherService.page(pageTeacher, null);//底层会把分页的所有数据封装到pageTeacher对象中
        List<EduTeacher> records = pageTeacher.getRecords();
        long size = pageTeacher.getSize();

9.代码生成器

3.0.5mp

1.添加依赖


        <!-- velocity 模板引擎, Mybatis Plus 代码生成器需要 -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>

2.在test类中新建类,点击运行即可

package com.hxut.zh.gaoxiaofix;

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.jupiter.api.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("E:\\java\\GaoXiaoFix" + "/src/main/java");

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

        //UserServie
        gc.setServiceName("%sService");    //去掉Service接口的首字母I

        gc.setIdType(IdType.ID_WORKER_STR); //主键策略  疑问:是主键自动补全的类型吗?
        gc.setDateType(DateType.ONLY_DATE);//定义生成的实体类中日期类型
        gc.setSwagger2(true);//开启Swagger2模式

        mpg.setGlobalConfig(gc);

        // 3、数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/gaoxiaofix?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("mysql");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 4、包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName("gaoxiaofix"); //模块名
        //包  com.atguigu.eduservice
        pc.setParent("com.hxut.zh");
        //包  com.atguigu.eduservice.controller
        pc.setController("controller");
        pc.setEntity("entity");
        pc.setService("service");
        pc.setMapper("mapper");
        mpg.setPackageInfo(pc);

        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();

        strategy.setInclude("device_info","fix_history","fix_info");//表名称,根据哪个表生成代码

        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();
    }
}




版权声明:本文为sharesb原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。