Mybatis Plus ActiveRecord 模式

Mybatis Plus ActiveRecord 模式 使用

DEMO源码地址 https://gitee.com/JackSong2019/demo-mybatis3.git

前言

ActiveRecord 模式 简介
  • ActiveRecord 是一种设计模式,它是一种在软件开发中用于管理关系数据库的模式,他简化了数据库操作的流程,使得开发人员可以更专注于业务逻辑而非数据库细节。它提供了一种面向对象的方法来处理数据库,使得数据库操作变得更加直观、易于维护和扩展。
    • 关于 ActiveRecord 模式的一些重要概念和特点
      1、对象关系映射 (ORM):
      ActiveRecord 是一种对象关系映射 (ORM) 模式的实现。它将数据库中的表格(或集合)映射到应用程序中的对象。
    每个数据库表格对应于一个 ActiveRecord 模型类,而表格中的每一行数据则对应于该模型类的一个实例对象。
    
      2、模型类(Model Class):
      在 ActiveRecord 中,模型类是应用程序中操作数据库的主要组件。每个模型类代表一个数据库表格,
    并且可以用于查询、插入、更新和删除表格中的数据。模型类通常继承自框架提供的 ActiveRecord 基类,
    这个基类提供了许多用于数据库操作的方法和功能。
    
      3、数据表与字段映射:
      ActiveRecord 模式通过约定俗成的方式将数据表中的字段映射到模型类的属性。
    例如,一个数据库表格中的 users 表可能会映射到一个 User 模型类,表中的每个字段(如 id、name、email 等)
    则对应于模型类中的属性。
    
      4、CRUD 操作:
      ActiveRecord 模式使得执行 CRUD 操作变得简单和直观。通过模型类,我们可以轻松地执行
    创建(Create)、读取(Read)、更新(Update)和删除(Delete)这些基本的数据库操作,
    而无需编写复杂的 SQL 查询语句。
    
      5、关联和查询:
      ActiveRecord 支持定义和使用关联关系,比如一对一、一对多、多对多等关系。
    这使得在处理复杂的数据模型时更加便捷。同时,ActiveRecord 提供了强大的查询接口,
    允许开发人员使用链式调用的方式构建复杂的数据库查询,而无需直接编写 SQL。
    
      6、数据验证和回调:
      ActiveRecord 提供了内置的数据验证功能,可以确保数据的完整性和一致性。
    开发人员可以在模型类中定义验证规则,以确保数据符合预期的格式和约束。此外,
    ActiveRecord 还支持回调机制,允许在数据保存、更新等操作前后执行特定的代码。
    

一、前置条件 JDK版本 Springboot版本 MybatisPlus版本

  • JDK 17 以上
  • SpringBoot 3.+ 以上
  • MybatisPlus 3.+ 以上
  • 说明: 实体类只需继承 Model 类即可进行强大的 CRUD 操作 ; 需要项目中已注入对应实体的BaseMapper

二、示例数据脚本 将脚本数据脚本导入到数据库中

-- user 表Schema 脚本
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`
(
    id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age INT NULL DEFAULT NULL COMMENT '年龄',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    PRIMARY KEY (id)
);

--  Data 脚本
DELETE FROM `user`;
INSERT INTO `user` (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');

三、初始化工程

  • 1、 创建一个空的 Spring Boot 工程
  提示 :
    a、可以使用 Spring Initializer (opens new window)快速初始化一个 Spring Boot 工程
    b、也可以创建一个maven空工程,然后按需要引入依赖

#添加依赖

  • 2、 引入 Spring Boot Starter 父工程
      <parent>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-parent</artifactId>
          <!-- 因为使用的mybatis plus 3.+ 所以需要指定springboot3.+以上的版本 -->
          <version>3.1.5</version>
          <relativePath/>
      </parent>
    
  • 3、 引入 spring-boot-starter、spring-boot-starter-test、mybatis-plus-boot-starter、mysql 依赖:
  <dependencies>
          <!-- SpringBoot -->
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter</artifactId>
          </dependency>
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-test</artifactId>
              <scope>test</scope>
          </dependency>
  
          <!-- lombok -->
          <dependency>
              <groupId>org.projectlombok</groupId>
              <artifactId>lombok</artifactId>
              <scope>provided</scope>
          </dependency>
  
          <!-- mybatis plus3 -->
          <dependency>
              <groupId>com.baomidou</groupId>
              <!--3.5.4开始,支持SpringBoot3使用此版本-->
              <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
              <version>3.5.4</version>
          </dependency>
  
          <!-- mysql -->
          <dependency>
              <groupId>mysql</groupId>
              <artifactId>mysql-connector-java</artifactId>
              <version>8.0.33</version>
              <scope>runtime</scope>
          </dependency>
      </dependencies>
  • 4、 配置application.yml 文件 主要是数据库连接信息
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test_db?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  • 5、 添加启动类,在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹
package org.example;


import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("org.example.mapper")
public class DemoMybatis3Application {
    public static void main(String[] args) {
        SpringApplication.run(DemoMybatis3Application.class, args);
    }
}
  • 6、编写 User 实体类 及 UserMapper 接口
@Data
@TableName("`user`")
public class User extends Model<User>{
    private Long id;
    private String name;
    private Integer age;
    private String email;
}
public interface UserMapper  extends BaseMapper<User> {
    
}
  • 7、 CRUD操作测试
 /**
     * 测试查询所有
     */
    @Test
    public void testSelectAll() {
        System.out.println(("----- selectAll method test ------"));
        User user = new User();
        List<User> userList = user.selectAll();
        userList.forEach(System.out::println);
    }

    /**
     * 测试新增
     */
    @Test
    public void add() {
        System.out.println(("----- add method test ------"));
        User user = new User();
        user.setName("赵六");
        user.setAge(30);
        user.setEmail("zhaoliu@163.com");
        user.insert();
        System.out.println(user.toString());
    }

    /**
     * 测试单条查询
     */
    @Test
    public void getOne() {
        System.out.println(("----- getOne method test ------"));
        User user = new User();
//        user.setId(9L);
//        user = user.selectById();
        user = user.selectById(9L);
        System.out.println(user.toString());
    }

    /**
     * 测试修改
     */
    @Test
    public void update() {
        System.out.println(("----- update method test ------"));
        User user = new User();
        user.setId(9L);
        user.setName("赵六六");
        user.setAge(33);
        user.setEmail("zhaoliu@163.com");
        user.updateById();
        System.out.println(user.toString());
    }

    /**
     * 测试删除
     */
    @Test
    public void del() {
        System.out.println(("----- del method test ------"));
        User user = new User();
//        user.setId(9L);
//        user.deleteById();
        boolean b = user.deleteById(9L);
        System.out.println(b);
    }
  • 8、 SimpleQuery 工具类
说明:
对selectList查询后的结果用Stream流进行了一些封装,使其可以返回一些指定结果,简洁了api的调用
需要项目中已注入对应实体的BaseMapper

测试代码示例

 @Test
public void listOperate() {
System.out.println(("----- SimpleQuery listOperate method test ------"));
List<String> userNames = new java.util.ArrayList<>();
List<String> emails = new java.util.ArrayList<>();
// 该查询 追加了 获取id集,打印,获取name集,获取email集的操作
List<Long> ids = SimpleQuery.list(lambdaQuery(),
        User::getId, System.out::println, user -> userNames.add(user.getName()),
        user -> emails.add(user.getEmail()));
// 打印ids
ids.forEach(System.out::println);
// 打印userNames
userNames.forEach(System.out::println);
// 打印emails
emails.forEach(System.out::println);
}

/**
* 测试查询 keyMap 返回为Map<属性,实体>
*/
@Test
public void keyMap() {
System.out.println(("----- SimpleQuery keyMap method test ------"));
// 查询表内记录,封装返回为Map<属性,实体>
//        Map<Long,User> userMap = SimpleQuery.keyMap(Wrappers.lambdaQuery(),
//                User::getId);
// 查询表内记录,封装返回为Map<属性,实体>,考虑了并行流的情况
Map<Long,User> userMap = SimpleQuery.keyMap(lambdaQuery(),
        User::getId,true);
userMap.forEach((k,v)->{
  System.out.println(k+"-->"+v);
});
}


/**
* 测试查询 map  返回为Map<属性,属性>
*/
@Test
public void map() {
System.out.println(("----- SimpleQuery map method test ------"));
//  查询表内记录,封装返回为Map<属性,属性>
//        Map<Long,String> userMap = SimpleQuery.map(Wrappers.lambdaQuery(),
//                User::getId,User::getName);
// 查询表内记录,封装返回为Map<属性,属性>,考虑了并行流的情况
Map<Long,String> userMap = SimpleQuery.map(lambdaQuery(),
        User::getId,User::getEmail,true);
userMap.forEach((k,v)->{
  System.out.println(k+"-->"+v);
});
}

/**
* 测试查询 group  返回为Map<属性,List<实体>>
*/
@Test
public void group() {
System.out.println(("----- SimpleQuery group method test ------"));
//  查询表内记录,封装返回为Map<属性,List<实体>>
//        Map<Integer,List<User>> userMap = SimpleQuery.group(Wrappers.lambdaQuery(),
//                User::getAge);
// 查询表内记录,封装返回为Map<属性,List<实体>>,考虑了并行流的情况
Map<Integer,List<User>> userMap = SimpleQuery.group(lambdaQuery(),
        User::getAge,true);
userMap.forEach((k,v)->{
  System.out.println(k+"-->"+v);
});
}

/**
* 测试查询 group  返回为Map<属性,分组后对集合进行的下游收集器>
*/
@Test
public void groupM() {
System.out.println(("----- SimpleQuery groupM method test ------"));
//  查询表内记录,封装返回为Map<属性,List<实体>>
//        Map<Integer, Set<User>> group = SimpleQuery.group(Wrappers.lambdaQuery(),
//                User::getAge, Collectors.toSet());

//        Map<Integer, Map<Long, String>> group = SimpleQuery.group(Wrappers.lambdaQuery(),
//                User::getAge, Collectors.toMap(User::getId, User::getName, (a, b) -> a));

//        // 查询表内记录,封装返回为Map<属性,List<实体>>,考虑了并行流的情况
//        Map<Integer, Set<User>> group = SimpleQuery.group(Wrappers.lambdaQuery(),
//                User::getAge, Collectors.toSet(),true);
Map<Integer, Map<Long, String>> group = SimpleQuery.group(lambdaQuery(),
        User::getAge, Collectors.toMap(User::getId, User::getName, (a, b) -> a));
group.forEach((k,v)->{
  System.out.println(k+"-->"+v);
});
}

/**
* 测试查询 list 返回为List<属性>
*/
@Test
public void list() {
System.out.println(("----- SimpleQuery list method test ------"));
// 查询表内记录,封装返回为List<属性>
//        List<String> names = SimpleQuery.list(Wrappers.lambdaQuery(), User::getName);
// 查询表内记录,封装返回为List<属性>,考虑了并行流的情况
List<String> names = SimpleQuery.list(lambdaQuery(), User::getName,true);
// 打印 names
names.forEach(System.out::println);
}

@Test
void testList() {
// 我要这张表里的ids
List<Long> entityIds = SimpleQuery.list(lambdaQuery(), User::getId);
assertThat(entityIds).containsExactly(1L, 2L);

// 可叠加后续操作
List<String> names = SimpleQuery.list(lambdaQuery(), User::getName,
        e -> Optional.ofNullable(e.getName())
                .map(String::toUpperCase)
                .ifPresent(e::setName));
assertThat(names).containsExactly("RUBEN", null);
}

  • 9、Db类
说明:

使用静态调用的方式,执行CRUD方法,避免Spring环境下Service循环注入、简洁代码,提升效率
需要项目中已注入对应实体的BaseMapper
对于参数为Wrapper的,需要在Wrapper中传入Entity或者EntityClass供寻找对应的Mapper
不建议在循环中调用,如果是批量保存,建议将数据构造好后使用 Db.saveBatch(数据) 保存

代码示例

 @Test
    void dbTest() {
        // 根据id查询
        List<User> list = Db.listByIds(Arrays.asList(1L, 2L), User.class);
        list.stream().forEach(System.out::println);

        // 根据条件构造器查询
        List<User> list1 = Db.list(Wrappers.lambdaQuery(User.class));
        list1.stream().forEach(System.out::println);
        // 批量根据id更新
//        boolean isSuccess = Db.updateBatchById(list);
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/603251.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【2024最新华为OD-C卷试题汇总】游戏表演赛分队(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; 文章目录 前…

博睿数据将出席ClickHouse Hangzhou User Group第1届 Meetup

2024年5月18日&#xff0c;博睿数据数智能力中心负责人李骅宸将受邀参加ClickHouse Hangzhou User Group第1届 Meetup活动&#xff0c;分享《ClickHouse在可观测性的应用实践和优化》的主题演讲。 在当前数字化浪潮下&#xff0c;数据的规模和复杂性不断攀升&#xff0c;如何高…

【触想智能】工业级平板电脑五大特征与应用领域分析

工业级平板电脑是专供工业环境使用的工业控制计算机&#xff0c;也被称为工控一体机。工业级平板电脑基本性能及兼容性与商用平板电脑几乎相同&#xff0c;但是工业级平板电脑更注重在不同环境下的稳定性能&#xff0c;因此&#xff0c;工业级平板电脑与普通的商用平板电脑存在…

【揭秘!】我国土地管理的基本国策与基本国情,你了解多少?

在这片古老而又充满活力的土地上&#xff0c;每一寸土地都承载着历史的记忆和未来的希望。我国的土地管理政策&#xff0c;正是在基本国情的基础上&#xff0c;精心编织的一张保障国家和人民利益的大网。今天&#xff0c;就让我们一起揭开我国土地管理的基本国策和基本国情的神…

记录我的程序猿副业首笔创收

在这个充满机遇的数字时代&#xff0c;我&#xff0c;一个普通的程序猿&#xff0c;编程爱好者&#xff0c;终于在云端源想这个平台上收获了属于我的第一桶金。这是一个关于兼职、学习与成长的故事&#xff0c;希望能激发同在编程路上的你&#xff0c;勇敢迈出那一步。 先晒晒…

Web3钱包开发获取测试币-OKB X1Testnet(三)

Web3钱包开发获取测试币-OKB X1Testnet(三) 基于以上两篇 Web3钱包开发获取测试币-Polygon Mumbai(一) &#xff1a;https://suwu150.blog.csdn.net/article/details/137949473Web3钱包开发获取测试币-Base Sepolia(二)&#xff1a;https://suwu150.blog.csdn.net/article/det…

《Decoupled Contrastive Learning for Long-Tailed Recognition》阅读笔记

论文标题 《Decoupled Contrastive Learning for Long-Tailed Recognition》 针对长尾识别的解耦对比学习 作者 Shiyu Xuan 和 Shiliang Zhang 来自北京大学计算机学院多媒体信息处理国家重点实验室 初读 摘要 监督对比损失&#xff08;Supervised Contrastive Loss, SC…

《米小圈动画古诗》—“诗情画意”也不是很难嘛!

创新是一个民族的灵魂和希望&#xff0c;是一个国家兴旺发达的不竭动力&#xff0c;而学习古诗词就是丰富孩子想象力、培养学生创新精神最有效的方法。因为&#xff0c;诗的韵律&#xff0c;情绪跌宕&#xff0c;可以让孩子在大脑中形成一幅完整的图画。 诗歌带给人最美妙的体…

MacOS搭建docker本地私有镜像库

相关环境 macOS: bigsur 11.7.8 docker desktop: 4.22.0 docker engine: 24.0.5 准备工作 本机已经安装好docker desktop&#xff0c;未安装的自行参考其他教程。如果不能翻墙&#xff0c;可以修改本地的镜像地址&#xff0c;可在docker desktop 设置中的docker engine中修…

最新AI实景自动无人直播软件:智能讲解、一键开播,享受24小时自动专业直播体验

在现今数字化时代&#xff08;ai无人直播下载&#xff1a;hzzxar&#xff09;直播行业越来越受到人们的关注和喜爱。随着人工智能的不断发展&#xff0c;AI实景自动无人直播软件应运而生&#xff0c;为商家提供了更便捷、高效的直播方式。本文将介绍如何利用这一创新技术&#…

活动预告 | 5月16日 Streaming Lakehouse Meetup · Online 与你相约!

随着 Apache Flink 技术社区的不断成熟和发展&#xff0c;越来越多企业开始利用 Flink 进行流式数据处理&#xff0c;从而提升数据时效性价值&#xff0c;获取业务实时化效果。与此同时&#xff0c;在大数据领域数据湖架构也日益成为新的技术趋势&#xff0c;越来越多企业开始采…

源码部署与SaaS账号:企业软件选择的自建房与租赁公寓之辩

在数字化运营的时代&#xff0c;企业选择软件解决方案就如同在选择住所&#xff1a;源码部署类似于“自建房屋”&#xff0c;而SaaS账号则更像是“租赁公寓”。 自建房屋&#xff08;源码部署&#xff09; 当你选择自建房屋时&#xff0c;你需要投入大量的时间和资金来购买土地…

Vue3---router(安装、路由跳转、路由守卫、本地存储)

Vue3—router&#xff08;安装、路由跳转、路由守卫、本地存储&#xff09; 目录 Vue3---router&#xff08;安装、路由跳转、路由守卫、本地存储&#xff09;基础使用安装创建路由 路由跳转无参跳转js写法html写法 有参跳转queryparams 路由守卫额外&#xff1a;本地存储sessi…

百度云内容审核快速配置 (java)

为什么要选择百度云 &#xff1f; 因为他免费用一年 首先要先开通百度云内容安全服务 按照操作指引走完整套 ContentCensor Java SDK目录结构** com.baidu.aip├── auth //签名相关类├── http //Http通…

SpringCloudAlibaba:4.2云原生网关higress的基本使用

概述 简介 Higress是基于阿里内部的Envoy Gateway实践沉淀、以开源Istio Envoy为核心构建的下一代云原生网关&#xff0c; 实现了流量网关 微服务网关 安全网关三合一的高集成能力&#xff0c;深度集成Dubbo、Nacos、Sentinel等微服务技术栈 定位 在虚拟化时期的微服务架构…

力扣HOT100 - 74. 搜索二维矩阵

解题思路&#xff1a; 两次二分&#xff0c;第一次定位行&#xff0c;第二次定位列。 class Solution {public boolean searchMatrix(int[][] matrix, int target) {int m matrix.length, n matrix[0].length;int l 0, r m - 1;//定位行int row -1;while (l < r) {in…

Amazon Bedrock 托管 Llama 3 8B70B

Amazon Bedrock 托管 Llama 3 8B&70B&#xff0c;先来体验&#xff1a;&#xff08;*实验环境账号有效期为1天&#xff0c;到期自动关停&#xff0c;请注意重要数据保护&#xff09; https://dev.amazoncloud.cn/experience/cloudlab?id65fd86c7ca2a0d291be26068&visi…

AnaTraf:一款功能强大的网络流量分析工具,助您实现高效网络管理

在当下迅速发展的网络时代&#xff0c;网络流量分析已经成为网络管理和维护的关键环节。 AnaTraf网络流量分析仪&#xff1a;全面把控网络状况 AnaTraf 是一款高性能的实时网络流量分析工具,能够帮助您全面了解网络状况,提高网络运维效率。其主要功能包括: 全流量回溯分析&am…

Django框架之请求生命周期流程图

一、引言 WSGI、wsgiref、uwsgi三者是什么关系? WSGI是协议&#xff0c;小写的wsgiref和uwsgi是实现该协议的功能模块 缓存数据库 提前已经将你想要的数据准备好了&#xff0c;需要的时候直接拿就可以&#xff0c;提高了效率和响应时间。 eg:当你在修改你的数据的时候&…

Java -- (part23)

一.网络编程 1.概述 在网络通信协议下,不同计算机上运行的程序,进行数据传输 2.软件架构 CS架构:客户端和服务端 BS架构:浏览器和服务端 3.服务器概念 安装了服务器软件的计算机 4.通信三要素 IP地址 a.概述 计算机的唯一标识,用于两台计算机之间的链接 b.特殊的IP…
最新文章