MyBatis-Flex BaseMapper的接口基本用法小结

2025-02-14 18:50

本文主要是介绍MyBatis-Flex BaseMapper的接口基本用法小结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《MyBatis-FlexBaseMapper的接口基本用法小结》本文主要介绍了MyBatis-FlexBaseMapper的接口基本用法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具...

MyBatis-Flex简单介绍

MyBatis-Flex 是一个优雅的 MyBatis 增强框架,它非常轻量、同时拥有极高的性能与灵活性。我们可以轻松的使用 Mybaits-Flex 链接任何数据库,其内置的 QueryWrapper^亮点 帮助我们极大的减少了 SQL 编写的工作的同时,减少出错的可能性。

总而言之,MyBatis-Flex 能够极大地提高我们的开发效率和开发体验,让我们有更多的时间专注于自己的事情。

特性

1、轻量

除了 MyBatis,没有任何第三方依赖轻依赖、没有任何拦截器,其原理是通过 SqlProvider 的方式实现的轻实现。同时,在执行的过程中,没有任何的 Sql 解析(Parse)轻运行。 这带来了几个好处:1、极高的性能;2、极易对代码进行跟踪和调试; 3、更高的把控性。

2、灵活

支持 Entity 的增删改查、以及分页查询的同时,MyBatis-Flex 提供了 Db + Row^灵活 工具,可以无需实体类对数据库进行增删改查以及分页查询。 与此同时,MyBatis-Flex 内置的 QueryWrapper^灵活 可以轻易的帮助我们实现 多表查询链接查询子查询 等等常见的 SQL 场景。

3、强大

支持任意关系型数据库,还可以通过方言持续扩展,同时支持 多(复合)主键逻辑删除乐观锁配置数据脱敏数据审计、 数据填充 等等功能。

基础方法

INSERT

BaseMapper 的接口提供了 insert 和 insertBatch 方法,用于新增数据。

  • insert(entity):插入实体类数据,不忽略 null 值。
  • insertSelective(entity):插入实体类数据,但是忽略 null 的数据,只对有值的内容进行插入。这样的好处是数据库已经配置了一些默认值,这些默认值才会生效。
  • insert(entity, ignoreNulls):插入实体类数据。
  • insertWithPk(entity):插入带有主键的实体类,不忽略 null 值。
  • insertSelectiveWithPk(entity):插入带有主键的实体类,忽略 null 值。
  • insertWithPk(entity, ignoreNulls):带有主键的插入,此时实体类不会经过主键生成器生成主键。
  • insertBatch(entities):批量插入实体类数据,只会根据第一条数据来构建插入的字段内容。
  • insertBatch(entities, size):批量插入实体类数据,按 size 切分。
  • insertOrUpdate(entity):插入或者更新,若主键有值,则更新,若没有主键值,则插入,插入或者更新都不会忽略 null 值。
  • insertOrUpdateSelective(entity):插入或者更新,若主键有值,则更新,若没有主键值,则插入,插入或者更新都会忽略 null 值。
  • insertOrUpdate(entity, ignoreNulls):插入或者更新,若主键有值,则更新,若没有主键值,则插入。

① insert

    /**
     * insert(entity):插入实体类数据,不忽略 null 值。
     * insert(entity, ignoreNulls):插入实体类数据。
     */
    @Test
    public void testInsert() {
        /**
         * 默认不忽略null值
         * INSERT INTO `tb_account`(`user_name`, `age`, `birthday`) VALUES (?, ?, ?)
         */
        int row = accountMapper.insert(new Account().setUserName(null).setBirthday(new Date()).setAge(25));
        Assertions.assertEquals(row, 1);

        /**
         * ignoreNulls true:忽略null , false:不忽略null
         * INSERT INTO `tb_account`(`user_name`) VALUES (?)
         */
        int row2 = accountMapper.insert(new Account().setUserName("ly3").setBirthday(null).setAge(null), true);
        Assertions.assertEquals(row2, 1);
    }

② insertSelective 

    /**
     * insertSelective(entity):插入实体类数据,但是忽略 null 的数据,只对有值的内容进行插入。这样的好处是数据库已经配置了一些默认值,这些默认值才会生效。
     */
    @Test
    public void testInsertSelective() {
        /**
         * INSERT INTO `tb_account`(`user_name`) VALUES (?)
         */
        int row = accountMapper.insertSelective(new Account().setUserName("陈远航").setAge(null));
        Assertions.assertEquals(row, 1);
    }

③ insertWithPk 

    /**
     * insertWithPk(entity):插入带有主键的实体类,不忽略 null 值。
     */
    @Test
    public void testInsertWithPk() {
        /**
         * INSERT INTO `tb_account`(`id`, `user_name`, `age`, `birthday`) VALUES (?, ?, ?, ?)
         */
        int row = accountMapper.insertWithPk(new Account().setUserName("廖楷瑞").setId(5L).setBirthday(null));
        Assertions.assertEquals(row, 1);
    }

④ insertBatch 

    /**
     * insertBatch(entities):批量插入实体类数据,只会根据第一条数据来构建插入的字段内容。
     * insertBatch(entities, size):批量插入实体类数据,按 size 切分。
     */
    @Test
    public void testInsertBatch() {
        List<Account> accounts = new ArrayList<>(10);
        for (int i = 0; i < 10; i++) {
            Account account = new Account().setUserName("ly" + i).setBirthday(new Date()).setAge(20 + i);
            accounts.add(account);
        }
        /**
         * 批量插入,可以指定每次插入的数据大小size
         * size=2 : INSERT INTO `tb_account`(`user_name`, `age`, `birthday`) VALUES (?, ?, ?), (?, ?, ?)
         * size=3 : INSERT INTO `tb_account`(`user_name`, `age`, `birthday`) VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?)
         * ......
         */
        int rows = accountMapper.insertBatch(accounts, 2);
        System.out.println("rows = " + rows);
    }

⑤ insertOrUpdate 

    /**
     * insertOrUpdate(entity):插入或者更新,若主键有值,则更新,若没有主键值,则插入,插入或者更新都不会忽略 null 值。
     * insertOrUpdateSelective(entity):插入或者更新,若主键有值,则更新,若没有主键值,则插入,插入或者更新都会忽略 null 值。
     * insertOrUpdate(entity, ignoreNulls):插入或者更新,若主键有值,则更新,若没有主键值,则插入。
     */
    @Test
    public void testInsertOrUpdate() {
        Account account = new Account().setUserName("ly-update2").setId(3L).setBirthday(new Date()).setAge(21);
        /**
         * UPDATE `tb_account` SET `user_name` = ? , `age` = ? , `birthday` = ? WHERE `id` = ?
         */
        int row = accountMapper.insertOrUpdate(account);
        Assertions.assertEquals(row, 0, 1);

        account = new Account().setUserName("ly-update2").setBirthday(null).setAge(21);
        /**
         * INSERT INTO `tb_account`(`user_name`, `age`) VALUES (?, ?)
         */
        int row2 = accountMapper.insertOrUpdateSelective(account);
        Assertions.assertEquals(row2, 0, 1);
    }

DELETE

BaseMapper 的接口提供了 deleteById、deleteBatchByIds、deleteByMap、deleteByQuery 方法,用于删除数据;

  • deleteById(id):根据主键删除数据。如果是多个主键的情况下,需要传入数组,例如:new Integer[]{100,101}。
  • deleteBatchByIds(ids):根据多个主键批量删除数据。
  • deleteBatchByIds(ids, size):根据多个主键批量删除数据。
  • deleteByMap(whereConditions):根据 Map 构建的条件来删除数据。
  • deleteByCondition(whereConditions):根据查询条件来删除数据。
  • deleteByQuery(queryWrapper):根据查询条件来删除数据。

① deleteById

    /**
     * deleteById(id):根据主键删除数据。
     * ??? 如果是多个主键的情况下,需要传入数组,例如:new Integer[]{100,101}。 ??? 怀疑态度
     */
    @Test
    public void testDeleteById() {
        /**
         * DELETE FROM `tb_account` WHERE `id` = ?
         */
        int row = accountMapper.deleteById(9L);
        Assertions.assertTrue(row > 0);
    }

② deleteBatchByIds  

    /**js
     * deleteBatchByIds(ids):根据多个主键批量删除数据。
     * deleteBatchByIds(ids, size):根据多个主键批量删除数据。
     */
    @Test
    public void testDeleteBatchByIds() {
        List<Integer> ids = List.of(5, 6, 7, 8);
        /**
         * DELETE FROM `tb_account` WHERE `id` = ? OR `id` = ? OR `id` = ? OR `id` = ?
         */
        int rows = accountMapper.deleteBatchByIds(ids);
        Assertions.assertTrue(rows > 0);

        /**
         * 分批删除
         * size=2 : DELETE FROM `tb_account` WHERE `id` = ? OR `id` = ?
         */
        int rows2 = accountMapper.deleteBatchByIds(ids, 2);
        Assertions.assertTrue(rows2 > 0);
    }

③ deleteByMap 

    /**
     * deleteByMap(whereConditions):根据 Map 构建的条件来删除数据。
     */
    @Test
    public void testDeleteBhttp://www.chinasem.cnyMap() {
        /**
         * DELETE FROM `tb_account` WHERE `tb_account`.`age` = ?
         */
        int rows = accountMapper.deleteByMap(Map.of("age", 25));
        Assertions.assertTrue(rows > 0);
    }

④ deleteByCondition  

    /**
     * deleteByCondition(whereConditions):根据查询条件来删除数据。
     */
    @Test
    public void testDeleteByCondition() {
        QueryCondition condition = QueryCondition.createEmpty().and("age = 27");
        /**
         * DELETE FROM `tb_account` WHERE age = 27
         */
        int rows = accountMapper.deleteByCondition(condition);
        Assertions.assertTrue(rows > 0);

        /**
         * DELETE FROM `tb_account` WHERE `id` > ?
         */
        int rows2 = accountMapper.deleteByCondition(ACCOUNT.ID.gt(35));
        Assertions.assertTrue(rows2 > 0);
    }

⑤ deleteByQuery

    /**
     * deleteByQuery(queryWrapper):根据查询条件来删除数据。
     */
    @Test
    public void testDeleteByQuery() {
        /**
         * DELETE FROM `tb_account` WHERE `age` >= ?
         */
        QueryWrapper wrapper = QueryWrapper.create().where(ACCOUNT.AGE.ge(32));
        int rows = accountMapper.deleteByQuery(wrapper);
        Assertions.assertTrue(rows > 0);
    }

UPDATE

BaseMapper 的接口提供了 update、updateByMap、updateByQuery 方法,用于更新数据;

  • update(entity):根据主键来更新数据,若实体类属性数据为 null,该属性不会新到数据库。
  • update(entity, ignoreNulls):根据主键来更新数据到数据库。
  • updateByMap(entity, whereConditions):根据 Map 构建的条件来更新数据。
  • updateByMap(entity, ignoreNulls, whereConditions):根据 Map 构建的条件来更新数据。
  • updateByCondition(entity, whereConditions):根据查询条件来更新数据。
  • updateByCondition(entity, ignoreNulls, whereConditions):根据查询条件来更新数据。
  • updateByQuery(entity, queryWrapper):根据查询条件来更新数据。
  • updateByQuery(entity, ignoreNulls, queryWrapper):根据查询条件来更新数据。

① update 

    @Test
    public void testUpdate() {
        Account account = new Account().setId(5L)
                .setAge(39)
                .setUserName("测试修改")
                .setBirthday(new Date(2023, Calendar.SEPTEMBER, 6, 12, 12, 12));
        /**
         * UPDATE `tb_account` SET `user_name` = ? , `age` = ? , `birthday` = ? WHERE `id` = ?
         */
        int rows = accountMapper.update(account);
        Assertions.assertTrue(rows > 0);
    }
	
    @Test
    public void testUpdateIgnoreNulls() {
        Account account = new Account().setId(6L)
                .setAge(null)
                .setUserName(null)
                .setBirthday(new Date(2023, Calendar.SEPTEMBER, 6, 12, 12, 12));
        /**
         * 不忽略null值
         * UPDATE `tb_account` SET `user_name` = ? , `age` = ? , `birthday` = ? WHERE `id` = ?
         */
        int rows = accountMapper.update(account, false);
        System.out.println("rows = " + rows);
    }

② updateByMap 

    @Test
    public void testUpdateByMap() {
        Account account = new Account()
                .setId(7L) // 不生效
                .setUserName("updateByMap")
                .setAge(24)
                .setBirthday(null);
        // 注意:这样更新实体类的id是不生效的
        Map<String, Object> whereCondition = Map.of("id", 13);

        /**
         * 忽略null
         * UPDATE `tb_account` SET `user_name` = ? , `age` = ? WHERE `id` = ?
         */
        accountMapper.updateByMap(account, whereCondition);

        /**
         * 不忽略null
         * UPDATE `tb_account` SET `user_name` = ? , `age` = ? , `birthday` = ? WHERE `id` = ?
         */
        accountMapper.updateByMap(account, false, whereCondition);
    }

③ updateByCondition 

    /**
     * updateByCondition(entity, whereConditions):根据查询条件来更新数据。
     * updateByCondition(entity, ignoreNulls, whereConditions):根据查询条件来更新数据。
     */
    @Test
    public void testUpdateByCondition() {
        Account account = new Account()
                .setId(8L)
                .setUserName("updateByCondition")
                .setBirthday(DateUtil.toDate(LocalDateTime.now()));
        QueryCondition condition = QueryCondition.create(new QueryColumn("id"),
                SqlConsts.EQUALS, 8);
        /**
         * 忽略null
         * UPDATE `tb_account` SET `user_name` = ? , `birthday` = ? WHERE `id` = ?
         */
        accountMapper.updateByCondition(account, condition);

        /**
         * 不忽略null
         * UPDATE `tb_account` SET `user_name` = ? , `age` = ? , `birthday` = ? WHChina编程ERE `id` = ?
         */
        accountMapper.updateByCondition(account, false, condition);
    }

④ updateByQuery

    /**
     * updateByQuery(entity, queryWrapper):根据查询条件来更新数据。
     * updateByQuery(entity, ignoreNulls, queryWrapper):根据查询条件来更新数据。
     */
    @Test
    public void testUpdateByQuery() {
        Account account = new Account().setUserName("updateByQuery");

        /**
         * UPDATE `tb_account` SET `user_name` = ? WHERE `id` = ?
         */
        accountMapper.updateByQuery(accou编程nt,
                QueryWrapper.create().where(ACCOUNT.ID.eq(9L)));
    }

⑤ UpdateEntity部分字段更新

    @Test
    public void testUpdateEntity1() {
        Account account = UpdateEntity.of(Account.class, 10L);
        /**
         * 官方说明:通过 UpdateEntity 创建的对象,只会更新调用了 setter 方法的字段,若不调用 setter 方法,不管这个对象里的属性的值是什么,都不会更新到数据库。
         */
        account.setAge(66)
                .setUserName("UpdateEntity")
                .setBirthday(null);
        accountMapper.update(account);
    }

    @Test
    public void testUpdateEntity2() {
        Account account = new Account()
                .setId(10L)
                .setUserName("UpdateEntity2");
        UpdateWrapper wrapper = UpdateWrapper.of(account);
        // wrapper.set(ACCOUNT.AGE, ACCOUNT.AGE.add(1));

        wrapper.setRaw("age", "age + 1");
        accountMapper.update(account);
    }

    @Test
    public void testUpdateEntity3() {
        Account account = new Account()
                .setId(10L)
                .setUserName("UpdateEntity2");
        UpdateWrapper wrapper = UpdateWrapper.of(account);

        // wrapper.set(ACCOUNT.AGE, ACCOUNT.AGE.add(1));

        wrapper.setRaw(ACCOUNT.AGE, "select * from t_account where id = 3");
        // accountMapper.updateByCondition(account, wrapper);
    }

⑥ UpdateChain

    @Test
    public void testUpdateChain() {
        /**
         * UPDATE `tb_account` SET `birthday` = ? , `age` = age + 1 WHERE `age` = ?
         */
        UpdateChain.of(Account.class)
                .set(Account::getBirthday, new Date())
                .setRaw(Account::getAge, "age + 1")
                .where(ACCOUNT.AGE.eq(11)).update();
    }

set() 和 setRaw() 的区别在 Row、UpdateWrapper、UpdateChain 中,都提供了 set() 和 setRaw() 两个方法用于设置数据。 那么,它们有什么区别呢?

  • set() 方法用于设置参数数据。
  • setRaw() 用于设置 SQL 拼接数据。

举个例子,

//更新数据
UpdateChain.of(Account.class)
	.set(Account::getAge, ACCOUNT.AGE.add(1))
	http://www.chinasem.cn.where(Account::getId).ge(100)
	.and(Account::getAge).eq(18)
	.update();

通过 UpdateChain 进行 update(),其执行的 SQL 如下:

UPDATE `tb_account` SET `age` = `age` + 1
WHERE  `id` >= 100 AND `age` = 18

到此这篇关于MyBatis-Flex BaseMapper的接口基本用法小结的文章就介绍到这了,更多相关MyBatis-Flex BaseMapper接口用法内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)! 

这篇关于MyBatis-Flex BaseMapper的接口基本用法小结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1153435

相关文章

redis中使用lua脚本的原理与基本使用详解

《redis中使用lua脚本的原理与基本使用详解》在Redis中使用Lua脚本可以实现原子性操作、减少网络开销以及提高执行效率,下面小编就来和大家详细介绍一下在redis中使用lua脚本的原理... 目录Redis 执行 Lua 脚本的原理基本使用方法使用EVAL命令执行 Lua 脚本使用EVALSHA命令

MyBatis模糊查询报错:ParserException: not supported.pos 问题解决

《MyBatis模糊查询报错:ParserException:notsupported.pos问题解决》本文主要介绍了MyBatis模糊查询报错:ParserException:notsuppo... 目录问题描述问题根源错误SQL解析逻辑深层原因分析三种解决方案方案一:使用CONCAT函数(推荐)方案二:

SpringBoot3.4配置校验新特性的用法详解

《SpringBoot3.4配置校验新特性的用法详解》SpringBoot3.4对配置校验支持进行了全面升级,这篇文章为大家详细介绍了一下它们的具体使用,文中的示例代码讲解详细,感兴趣的小伙伴可以参考... 目录基本用法示例定义配置类配置 application.yml注入使用嵌套对象与集合元素深度校验开发

判断PyTorch是GPU版还是CPU版的方法小结

《判断PyTorch是GPU版还是CPU版的方法小结》PyTorch作为当前最流行的深度学习框架之一,支持在CPU和GPU(NVIDIACUDA)上运行,所以对于深度学习开发者来说,正确识别PyTor... 目录前言为什么需要区分GPU和CPU版本?性能差异硬件要求如何检查PyTorch版本?方法1:使用命

Redis 热 key 和大 key 问题小结

《Redis热key和大key问题小结》:本文主要介绍Redis热key和大key问题小结,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、什么是 Redis 热 key?热 key(Hot Key)定义: 热 key 常见表现:热 key 的风险:二、

SpringBoot UserAgentUtils获取用户浏览器的用法

《SpringBootUserAgentUtils获取用户浏览器的用法》UserAgentUtils是于处理用户代理(User-Agent)字符串的工具类,一般用于解析和处理浏览器、操作系统以及设备... 目录介绍效果图依赖封装客户端工具封装IP工具实体类获取设备信息入库介绍UserAgentUtils

Spring Boot读取配置文件的五种方式小结

《SpringBoot读取配置文件的五种方式小结》SpringBoot提供了灵活多样的方式来读取配置文件,这篇文章为大家介绍了5种常见的读取方式,文中的示例代码简洁易懂,大家可以根据自己的需要进... 目录1. 配置文件位置与加载顺序2. 读取配置文件的方式汇总方式一:使用 @Value 注解读取配置方式二

Java中的@SneakyThrows注解用法详解

《Java中的@SneakyThrows注解用法详解》:本文主要介绍Java中的@SneakyThrows注解用法的相关资料,Lombok的@SneakyThrows注解简化了Java方法中的异常... 目录前言一、@SneakyThrows 简介1.1 什么是 Lombok?二、@SneakyThrows

Python中的getopt模块用法小结

《Python中的getopt模块用法小结》getopt.getopt()函数是Python中用于解析命令行参数的标准库函数,该函数可以从命令行中提取选项和参数,并对它们进行处理,本文详细介绍了Pyt... 目录getopt模块介绍getopt.getopt函数的介绍getopt模块的常用用法getopt模

C 语言中enum枚举的定义和使用小结

《C语言中enum枚举的定义和使用小结》在C语言里,enum(枚举)是一种用户自定义的数据类型,它能够让你创建一组具名的整数常量,下面我会从定义、使用、特性等方面详细介绍enum,感兴趣的朋友一起看... 目录1、引言2、基本定义3、定义枚举变量4、自定义枚举常量的值5、枚举与switch语句结合使用6、枚