MyBatisPlus 之一:Spring 整合 MyBatisPlus 及雪花算法

1. Mybatis-Plus简介

Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。这是官方给的定义,关于mybatis-plus的更多介绍及特性,可以参考https://mp.baomidou.com/。那么它是怎么增强的呢?其实就是它已经封装好了一些crud方法,我们不需要再写xml了,直接调用这些方法就行,就类似于JPA。

特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

2. Spring整合Mybatis-Plus

正如官方所说,mybatis-plus 在 mybatis 的基础上只做增强不做改变,因此其与 spring 的整合亦非常简单。

只需把 mybatis 的依赖换成 mybatis-plus 的依赖,再把 sqlSessionFactory 换成 mybatis-plus 的即可。

注意: 实际应用中,更多的是 SpringBoot 整合 MyBatis-Plus 相对较少。

1) 配置 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>spring_mybatisplus</artifactId><version>1.0-SNAPSHOT</version><properties><java.version>11</java.version><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>5.3.5</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.5</version></dependency><!--MyBatis-Plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus</artifactId><version>3.4.2</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.26</version></dependency><!--用于配置连接池数据源--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-dbcp2</artifactId><version>2.7.0</version></dependency><!--用于spring集成测试--><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.3.5</version></dependency><!--打印SQL日志需要--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.25</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><!--只能在test目录下才能使用--><!--            <scope>test</scope>--></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><configuration><source>11</source><target>11</target></configuration></plugin></plugins></build></project>

2) db.properties

连接数据库的配置信息,以 MySQL8 为例。

resources/目录下:

url=jdbc:mysql://127.0.0.1:3306/wdzldb?useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
driver=com.mysql.cj.jdbc.Driver
dbuname=root
password=root

3) log4j.properties

如果需要打印输出执行过程中的 SQL 日志,配置 log4j

需要下面配置

指定自己的包名:log4j.logger.com.wdzl=debug

其他全局的配置:log4j.rootLogger=warn, stdout

# Global logging configuration  debug  info warn  error 
log4j.rootLogger=warn, stdout
# MyBatis logging configuration...
log4j.logger.org.apache.ibatis=debug## MySelf Package
log4j.logger.com.wdzl=debug
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.Target=System.out
#log4j.appender.stdout.layout.ConversionPattern=%5p %d [%t] - %m%n
log4j.appender.stdout.layout.ConversionPattern=%3p - %m%n

4) spring-mybatis.xml

整合配置基本顺序:数据源-->--SessionFactory-->--Dao

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!--配置连接数据库的属性文件--><context:property-placeholder location="classpath:jdbc.properties" /><!-- DataSource: URL Driver Username Password --><bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"><property name="driverClassName" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${dbuname}"/><property name="password" value="${password}"/></bean><!-- SessionFactory 注意这里所在包,和之前mybatis整合不同。同时,plus 版本不同,这个类位置也有不同 --><bean id="sessionFactory"class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"><property name="dataSource" ref="dataSource" /><property name="typeAliasesPackage" value="com.wdzl.pojo"/></bean><!-- Dao --><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><!--扫描基包下的所有的接口,生成对应的实现代理对象--><property name="basePackage" value="com.wdzl.dao" /><property name="sqlSessionFactoryBeanName"value="sessionFactory"></property></bean><!--注意 启动注解扫描  注意 --><context:component-scan base-package="com.wdzl"/>
</beans>

注意:

SessionFactoy 不是 spring+mybatis 整合时的工厂bean;

com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean

5) 编写 pojo 类

// 驼峰命名的属性,默认生成sql字段时,会变成 book_Id 需要映射

  • @TableId("bookid")

  • 如果数据库表主键自增的,则不添加此@TableId 注解,执行insert 时,是可以的

    但是通过主键查询时,会出现 where null=? 问题。

  • 所以需要配置@TableId

  • 配置注解后的问题

    • 1.不指定 type type = IdType.NONE ,自己设置主键。如果不给主键,默认指定long的唯一主键
    • 2.type = IdType.AUTO : 数据库指定主键。保存时给主键与否,都会采用数据库自增策略
    • 3.ASSIGN_ID 等同NONE : 程序指定主键
      • a.手动设置有值,则使用设置的主键
      • b.如果没有指定,则框架默认使用雪花算法生成主键
/****/
@Data
@TableName("Book")
public class Book {@TableId(value = "bookid",type = IdType.ASSIGN_ID)
//    @TableField("bookid")//注意:使用TabelId后,@TableField同时使用无效private Integer bookId;@TableField("bookName")private String bookName;private String author;@TableField("pubDate")   // @TableField 可以设置忽略 exist=true private Date pubDate;private Float price;
}

6) DAO接口

注意:

  • @Repository 注解
  • BaseMapper<Book> 泛型
@Repository
public interface IBookDao extends BaseMapper<Book> {
}

只需要自定义接口继承 BaseMapper 接口同时指定泛型即可。

7) 使用测试

需要依赖 Junit4 以上版本和 spring-test

注意:junit 依赖配置

<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><!--只能在test目录下才能使用--><!--<scope>test</scope>-->
</dependency>

测试用例代码:

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.wdzl.dao.IBookDao;
import com.wdzl.pojo.Book;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.*;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-mybatis.xml"})
public class BookService {@Autowiredprivate IBookDao bookDao;@Testpublic void get(){Book book = bookDao.selectById(26);System.out.println(book);}@Testpublic void findAll(){bookDao.selectList(null).forEach(System.out::println);}@Testpublic void findByMap(){Map<String,Object> map = new HashMap<>();map.put("author","张宇昂");map.put("bookName","JavaEE框架");map.put("price",45f);// 转为等值条件查询bookDao.selectByMap(map).forEach(System.out::println);}@Testpublic void findByWrapper(){QueryWrapper<Book> queryWrapper = new QueryWrapper<>();//选择要查询的列queryWrapper.select("bookname","price","author");//指定条件queryWrapper.ge("price",10);queryWrapper.le("price",100);queryWrapper.like("bookname","%Java%");queryWrapper.in("bookid",23,4,5,63);queryWrapper.between("price",23,89);bookDao.selectList(queryWrapper);}@Testpublic void findByIdList(){List<Integer> integers = Arrays.asList(23, 26, 47);bookDao.selectBatchIds(integers).forEach(System.out::println);}@Testpublic void insert(){Book book = new Book();
//        book.setBookId(49);book.setBookName("JavaEE框架");book.setAuthor("张宇昂");book.setPrice(45f);book.setPubDate(new Date());int insert = bookDao.insert(book);//插入成功后,默认可以自动获取主键System.out.println(insert+"==="+book.getBookId());}
}

8) 雪花算法

简介:

SnowFlake 算法,是 Twitter 开源的分布式 id 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 id。在分布式系统中的应用十分广泛,且ID 引入了时间戳,基本上保持自增的

分布式ID的特点

全局唯一性:不能出现有重复的ID标识,这是基本要求。

递增性:确保生成ID对于用户或业务是递增的。

高可用性:确保任何时候都能生成正确的ID。

高性能性:在高并发的环境下依然表现良好。

分布式ID的常见解决方案
UUID

Java自带的生成一串唯一随机36位字符串(32个字符串+4个“-”)的算法。它可以保证唯一性,且据说够用N亿年,但是其业务可读性差,无法有序递增。

SnowFlake

今天的主角雪花算法,它是Twitter开源的由64位整数组成分布式ID,性能较高,并且在单机上递增

组成部分(64bit)

1.第一位 占用1bit,其值始终是0,没有实际作用。

2.时间戳 占用41bit,精确到毫秒,总共可以容纳约69年的时间。

3.工作机器id 占用10bit,其中高位5bit是数据中心ID,低位5bit是工作节点ID,做多可以容纳1024个节点。

4.序列号 占用12bit,每个节点每毫秒0开始不断累加,最多可以累加到4095,一共可以产生4096个ID。

SnowFlake算法在同一毫秒内最多可以生成多少个全局唯一ID呢:

: \同一毫秒的ID数量 = 1024 X 4096 = 4194304**

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯第 6 场 小白入门赛 2.猜灯谜(for + 数组)

思路&#xff1a;注意是环形排列的灯笼&#xff0c;它的谜底是相邻两个灯笼的数字之和。这道题要用到两个数组&#xff0c;ans存答案&#xff0c;a存原数据。数据读入部分就不用说了&#xff0c;重点就是单独写明ans[0]和ans[n-1]两个取值&#xff0c;其他的用for循环数组就可以…

数据结构——栈和队列的表示与实现详解

目录 1.栈的定义与特点 2.队列的定义与特点 3.案例引入 4.栈的表示和操作的实现 1.顺序栈的表示 代码示例&#xff1a; 2.顺序栈的初始化 代码示例&#xff1a; 3.判断栈是否为空 代码示例&#xff1a; 4.求顺序栈长度 代码示例&#xff1a; 5.清空顺序栈 …

如何实现图片上传至服务器

在绝大多数的项目中都会涉及到文件上传等&#xff0c;下面我们来说一下技术派中是如何实现原生图片上传的&#xff0c;这个功能说起来简单&#xff0c;但其实对于技术还是有考验的。图片的上传涉及到IO读写&#xff0c;一个文件上传的功能&#xff0c;就可以把IO流涉及到的知识…

✅技术社区—通过Canal框架实现MySQL与ElasticSearch的数据同步

Canal 是一个由阿里巴巴开源的&#xff0c;基于 Java 的数据库变更日志解析的中间件&#xff0c;其原理是基于Binlog订阅的方式实现&#xff0c;模拟一个MySQL Slave 订阅Binlog日志&#xff0c;从而实现CDC&#xff0c;主要用于实现 MySQL 数据库的增量数据同步。它主要的使用…

模块化项目Eclipse测试网零撸教程

简介&#xff1a;Eclipse 是一个基于 Solana 区块链的初创项目&#xff0c;致力于构建基于 Solana 虚拟机的通用 Layer2 解决方案&#xff0c;为以太坊提供更快速、更通用的 Rollup 技术。其主要用途是为开发者提供构建基于 Solana 虚拟机的 Rollup 应用的平台&#xff0c;解决…

Vue3-响应式基础:单文件和组合式文件

单文件&#xff1a;html <!DOCTYPE html> <html> <head><title>响应式基础</title> </head> <body><div id"app" ><!-- dynamic parameter:同样在指令参数上也可以使用一个 JavaScript 表达式&#xff0c;需要包…

SpringBoot(整合MyBatis + MyBatis-Plus + MyBatisX插件使用)

文章目录 1.整合MyBatis1.需求分析2.数据库表设计3.数据库环境配置1.新建maven项目2.pom.xml 引入依赖3.application.yml 配置数据源4.Application.java 编写启动类5.测试6.配置类切换druid数据源7.测试数据源是否成功切换 4.Mybatis基础配置1.编写映射表的bean2.MonsterMapper…

从零到一构建短链接系统(五)

1.修改UserService Service public class UserServiceImpl extends ServiceImpl<UserMapper, UserDO> implements UserService {public UserRespDTO getUserByUsername(String username) {LambdaQueryWrapper<UserDO> queryWrapper Wrappers.lambdaQuery(UserDO.c…

MySQL实战:监控

监控指标 性能类指标 名称说明QPS数据库每秒处理的请求数量TPS数据库每秒处理的事务数量并发数数据库实例当前并行处理的会话数量连接数连接到数据库会话的数量缓存命中率Innodb的缓存命中率 功能类指标 名称说明可用性数据库是否正常对外提供服务阻塞当前是否有阻塞的会话…

HarmonyOS-鸿蒙系统概述

你了解鸿蒙系统吗&#xff1f; 你看好鸿蒙系统吗&#xff1f; 今年秋季即将推出的HarmonyOS Next 星河版热度空前&#xff0c;一起来了解一下吧。本文将从HarmonyOS 的应用场景、发展历程、架构、开发语言、开发工具、生态建设六个角度聊一聊个人的理解。 1、应用场景 鸿蒙…

深度学习pytorch——拼接与拆分(持续更新)

cat拼接 使用条件&#xff1a;合并的dim的size可以不同&#xff0c;但是其它的dim的size必须相同。 语法&#xff1a;cat([tensor1,tensor2],dim n) # 将tensor1和tensor2的第n个维度合并 代码演示&#xff1a; # 拼接与拆分 a torch.rand(4,32,8) b torch.rand(…

多线程JUC 第2季 wait和notify唤醒机制

一 wait和notify的区别与相同 1.1 wait和notify的作用 1) 使用wait()、notify()和notifyAII()时需要先对调用对象加锁。否则直接调用的话会抛出 IllegalMonitorStateExceptiona。 2) 调用wait()方法后&#xff0c;线程状态。由RUNNING变为WAITING&#xff0c;并将当前线程放置…

【LabVIEW FPGA入门】流水线

LabVIEW中流水线 在当今多核处理器和多线程应用程序的世界中&#xff0c;程序员在开发应用程序时需要不断思考如何最好地利用尖端 CPU 的强大功能。尽管用传统的基于文本的语言构建并行代码可能难以编程和可视化&#xff0c;但 NI LabVIEW 等图形开发环境越来越多地允许工程师和…

【Docker】一文趣谈Docker

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》《项目实战》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 …

ELK日志管理实现的3种常见方法

ELK日志管理实现的3种常见方法 1. 日志收集方法 1.1 使用DaemonSet方式日志收集 通过将node节点的/var/log/pods目录挂载给以DaemonSet方式部署的logstash来读取容器日志,并将日志吐给kafka并分布写入Zookeeper数据库.再使用logstash将Zookeeper中的数据写入ES,并通过kibana…

第七节:Vben Admin权限-后端获取路由和菜单

系列文章目录 第一节:Vben Admin介绍和初次运行 第二节:Vben Admin 登录逻辑梳理和对接后端准备 第三节:Vben Admin登录对接后端login接口 第四节:Vben Admin登录对接后端getUserInfo接口 第五节:Vben Admin权限-前端控制方式 第六节:Vben Admin权限-后端控制方式 第七节…

PHP魔术方法详解

php魔术方法是一些特殊的方法&#xff0c;由特定的环境来进行触发。 这些魔术方法让开发者能够更好地控制对象的行为&#xff0c;特别是在处理不常见的操作或者需要自动化处理某些任务时非常有用。 1、_construct()构造函数&#xff1a; <?php highlight_file(__FILE__);…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:SideBarContainer)

提供侧边栏可以显示和隐藏的侧边栏容器&#xff0c;通过子组件定义侧边栏和内容区&#xff0c;第一个子组件表示侧边栏&#xff0c;第二个子组件表示内容区。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起…

《LeetCode热题100》笔记题解思路技巧优化_Part_4

《LeetCode热题100》笔记&题解&思路&技巧&优化_Part_4 &#x1f60d;&#x1f60d;&#x1f60d; 相知&#x1f64c;&#x1f64c;&#x1f64c; 相识&#x1f622;&#x1f622;&#x1f622; 开始刷题二叉树&#x1f7e2;1. 二叉树的中序遍历&#x1f7e2;2.…

【计算机网络_应用层】https协议——加密和窃密的攻防

文章目录 1.https协议的介绍2. 加密和解密2.1 什么是加密2.2 常见的加密方式2.2.1 对称加密2.2.2 非对称加密 2.3 数据摘要&#xff08;数据指纹&#xff09;2.4 数字签名 3. https协议的加密和解密方案一&#xff1a;使用对称加密&#xff08;❌&#xff09;方案二&#xff1a…