mybatisplus使用

一、导入依赖

<dependency>
   <groupId>com.baomidou</groupId>
   <artifactId>mybatis-plus-boot-starter</artifactId>
   <version>3.4.3.4</version>
</dependency>

二、配置文件。写pojo

spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/market?useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

三、mapper层接口继承 BaseMapper

@Mapper
@Repository  //表示这是dao(持久层)层,只有需要用到mybatis(数据库)时才用到
public interface UserMapper extends BaseMapper<User> {
//所有的CRUD操作都已经编写完成了,你不需要像以前的配置一大堆文件了!
}

四、使用

  @Autowired
    private UserMapper userMapper;

    //继承了BaseMapper,所有的方法都来自己父类
    //我们也可以编写自己的扩展方法!
    @Test
    void contextLoads() {
//        User user =userMapper.selectById(5);
//        System.out.println(user);
        //参数是一个wrapper ,条件构造器,这里我们先不用nuLL/查询全部用户
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);

    }

--------------------------------------------------------------------------------------

正式开始

数据库表结构

完整表结构

实体类的注解

public class User {
    //对应数据库中的主键(uuid、自增id、雪花算法、redis、 zookeeper ! )
    @TableId(type = IdType.NONE)
    private Integer id;
    private String name;
    private Integer password;
    //时间类型LocalDateTime要与MyDateObjectHandler类中对应
    //自动填写插入操作FieldFill.INSERT
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    //自动填写更新操作时间
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;

    @Version   //乐观锁的注解
    private Integer version;

    @TableLogic  //逻辑删除注解
    private Integer deleted;
    }

==================================================

一。简单增删改查使用

@SpringBootTest
class MybatisPlusApplicationTests {

    @Autowired
    private UserMapper userMapper;

    //继承了BaseMapper,所有的方法都来自己父类
    //我们也可以编写自己的扩展方法!
    @Test
    void contextLoads() {
        User user =userMapper.selectById(3);
        System.out.println(user);

//        参数是一个wrapper ,条件构造器,这里我们先不用nuLL,查询全部用户
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }

    //add
    @Test
    public void TestAdd(){
        User user=new User();
        user.setId(7);
        user.setName("rtul");
        user.setPassword(123125);

        int insert=userMapper.insert(user);
        System.out.println(insert);
        System.out.println(user);
    }

    //update
    @Test
    public void TestUpdate(){
//        User user=new User();
//        user.setId(5);
//        user.setName("小乔乔");
//        user.setPassword(12121);
//        int user1=userMapper.updateById(user);
//        System.out.println(userMapper.selectById(5));
    }


    //测试查询
    @Test
    public void TestQuery() {
        User user = userMapper.selectById(3);
        System.out.println(user);
    }

    //查询多个id
    @Test
    public void TestQuery2(){
        //类型是Collection --所以用集合Arrays.asList
        List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
        System.out.println(users);
    }

    //条件查询之一通过map
    @Test
    public void TestQuery3(){
        HashMap<String,Object> map = new HashMap<>();
//        map.put("name","www");
        map.put("password","12121");

        userMapper.selectByMap(map);
        System.out.println();
    }

    //按id删除
    @Test
    public void TestDelete(){
        userMapper.deleteById(1);

        //查询多个id
        //类型是Collection --所以用集合Arrays.asList
        userMapper.deleteBatchIds(Arrays.asList(1,2,3));

        //条件查询之一通过map
        HashMap<String,Object> map = new HashMap<>();
//        map.put("name","www");
        map.put("password","12121");

        userMapper.deleteByMap(map);
    }
    

二。关于时间的创建时间和更新时间

建一个headler包,MyDateObjectHandler类

时间配置类

@Component    //把处理器组件加到IOC容器中
public class MyDateObjectHandler implements MetaObjectHandler {

    //插入时填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
//        this.setFieldValByName("createTime",new Date(),metaObject);
//        this.setFieldValByName("updateTime",new Date(),metaObject);

        this.strictInsertFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class);
        this.strictInsertFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class);

        //this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
        // 或者
       // this.strictInsertFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
        // 或者
        //this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)
    }

    //更新时填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        //this.setFieldValByName("updateTime",new Date(),metaObject);
        this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class);

       // this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐)
        // 或者
        //this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
        // 或者
        //this.fillStrategy(metaObject, "updateTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)
    }
}

三。乐观锁,分页插件和防止恶意全表更新删除的配置

@EnableTransactionManagement   //自动管理事务
@Configuration  //配置类
public class MyBatisPlusConfig {

//    @Bean
    //旧版
//    //注册乐观锁
//    public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor(){
//        return new OptimisticLockerInnerInterceptor();
//    }

    //分页组件配置
//    旧版
//    @Bean
//    public PaginationInterceptor paginationInterceptor(){
//        return new PaginationInterceptor();
//    }


//    逻辑删除旧版需要的配置,新版不需要
//    @Bean
//    public ISqlInjector sqlInjector() {
//        return new LogicSqlInjector();
//    }

        //新版
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        //注册乐观锁
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());

        //分页插件配置
        //默认DbType.数据库类型
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));

        //配置全表更新与删除插件,针对 update 和 delete 语句 作用: 阻止恶意的全表更新删除
        interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());

        return interceptor;

    }

}

测试

    //测试乐观锁成功
    @Test
    public void TestOptimisticLocker(){
        //1.查询用户信息
        User user=userMapper.selectById(4);
        //2.插入用户信息
        user.setName("白起1");
        user.setPassword(22322);
        //3.执行更新操作
        userMapper.updateById(user);
    }

    //测试乐观锁失败
    @Test
    public void TestOptimisticLocker2(){
        User user=userMapper.selectById(1);
        user.setName("白起1");
        user.setPassword(22322);

        //模拟插队
        User user2=userMapper.selectById(1);
        user.setName("白起2");
        user.setPassword(22322);
        userMapper.updateById(user2);

        //可以自旋锁来多次尝试提交!
        userMapper.updateById(user);//如果没有乐观锁就会覆盖插队线程的值!
    }

    //分页查询三种方式-1、使用limit。2、第三方插件。3、MyBatisPlus内置分页
    //分页查新。需要配置拦截组件
    //MybatisPlus3.5的在Mybatis方法里面直接加 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL))
    @Test
    public void TestPageQuery(){
        //参数一是页码,二是数量
        Page<User> Page = new Page<>(1,3);
        //wrapper暂时不用
        userMapper.selectPage(Page,null);
        //getRecords获得记录
        Page.getRecords().forEach(System.out::println);
        Page.getPages(); //一共多少页
        Page.getTotal();//一共多少条数据
        Page.getCurrent(); //当前第几页
        Page.getRecords();//获取分页后的数据
    }

  //防止全表更新删除
    @Test
    public void testDeleteUpdate() {
        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(User::getId, 1);
        User user = new User();
        user.setId(5);
        user.setName("custom_name");

        //我没写这个方法,不知道wrapper是什么
//        userMapper.saveOrUpdate(user, wrapper);
    }

逻辑删除

逻辑删除旧版需要的配置类,新版不需要。
要在application.properties中配置
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

## 日志,StdOutImpl系统自带日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

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

# 配置端口
# server.port=8000
# 开发模式
# spring.profiles.active=dev

测试

   //逻辑删除。物理删除是直接从数据库中删除。逻辑删除是在数据库中没有删除,而是通过变量来使他失效
    //管理员可以查看删除记录,以防数据丢失,类似于回收站
    //在配置文件中配置了之后删除不会删除数据库中的数据
//    UPDATE user SET deleted=1 WHERE id=? AND deleted=0实际执行的是update
    @Test
    public void TestLogicDelete() {
        //按id删除
        userMapper.deleteById(1);
    }

------------------------------------------------------------------------------------------

wrapper条件构造器用法

极其好用

测试

@SpringBootTest
public class wrapperTest {

    @Autowired
    private UserMapper userMapper;

    //wrapper是条件构造器,多重条件查询
    @Test
    public void TestPageQuery(){
        //wrapper是条件构造器,多重条件
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //年龄大于20,年龄,更新时间非空
        //非空
        wrapper.isNotNull("age");
        wrapper.isNotNull("update_time");
        //大于
        wrapper.ge("age",20);

        System.out.println(userMapper.selectList(wrapper));
    }

//    查询一个
    @Test
    public void TestPageQuery2(){
        //wrapper是条件构造器,多重条件
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //名字==诸葛
        wrapper.eq("name","诸葛");
        //selectOne只能查一个存在的
        User user=userMapper.selectOne(wrapper);
        System.out.println(user);
    }

    //    查询一个
    @Test
    public void TestPageQuery3(){
        //wrapper是条件构造器,多重条件
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //年龄18到30之间的
        wrapper.between("age",18,30);

        Long count = userMapper.selectCount(wrapper);
        System.out.println(count);
//        List<User> users = userMapper.selectList(wrapper);
//        users.forEach(System.out::println);
    }

    //    Map查询
    @Test
    public void TestPageQuery4(){
        //wrapper是条件构造器,多重条件
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //不包含
//        wrapper.notLike("name","w");
        //包含
        wrapper.like("name","w");
        //右开头,比如 w%
        wrapper.likeRight("name","l");

        List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
        maps.forEach(System.out::println);
    }
}

自学自狂神,有位大哥总结的更好:https://blog.csdn.net/greenhandp/article/details/124008224?spm=1001.2014.3001.5506

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值