发布时间:2025-12-09 16:19:29 浏览次数:12
惠医疗即为网上预约挂号系统,网上预约挂号是近年来开展的一项便民就医服务,旨在缓解看病难、挂号难的就医难题,许多患者为看一次病要跑很多次医院,最终还不一定能保证看得上医生。网上预约挂号全面提供的预约挂号业务从根本上解决了这一就医难题。随时随地轻松挂号!不用排长队!
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生(提供了一些实用的工具类,如代码生成器、性能分析器、缓存增强器、注解支持等,减少了编写重复代码的工作量,并提高了代码的可读性和性能)。
润物无声
只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑。
效率至上
只需简单配置,即可快速进行 CRUD 操作,从而节省大量时间。
丰富功能
热加载、代码生成、分页、性能分析等功能一应俱全。
mybatis_plus
其对应的数据库 Schema 脚本如下:
CREATE TABLE USER ( id BIGINT(20)NOT NULL COMMENT '主键ID', NAME VARCHAR(30)NULL DEFAULT NULL COMMENT '姓名', age INT(11)NULL DEFAULT NULL COMMENT '年龄', email VARCHAR(50)NULL DEFAULT NULL COMMENT '邮箱', PRIMARY KEY (id) );其对应的数据库 Data 脚本如下:
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 Initializr 快速初始化一个 Spring Boot 工程
Group:com.atguigu
Artifact:mybatis_plus
版本:2.2.1.RELEASE
注意:引入 MyBatis-Plus 之后请不要再次引入 MyBatis,以避免因版本差异导致的问题。
<dependencies><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><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency><!--mybatis-plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.3.1</version></dependency><!--mysql依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--lombok用来简化实体类--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies>在 application.properties 配置文件中添加 MySQL 数据库的相关配置:
spring boot 2.0(内置jdbc5驱动)#mysql数据库连接spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=falsespring.datasource.username=rootspring.datasource.password=rootspring boot 2.1及以上(内置jdbc8驱动)注意:driver和url的变化spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8spring.datasource.username=rootspring.datasource.password=root注意:
Jzt: 必须用mysql 8版本才行
1、这里的 url 使用了 ?serverTimezone=GMT%2B8 后缀,因为8.0版本的jdbc驱动需要添加这个后缀,否则运行测试用例报告如下错误:
java.sql.SQLException: The server time zone value ‘Öйú±ê׼ʱ¼ä’ is unrecognized or represents more
2、这里的 driver-class-name 使用了 com.mysql.cj.jdbc.Driver ,在 jdbc 8 中 建议使用这个驱动,否则运行测试用例的时候会有 WARN 信息
在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹
@SpringBootApplication@MapperScan("com.atguigu.demomptest.mapper")public class DemomptestApplication {public static void main(String[] args) {SpringApplication.run(DemomptestApplication.class, args);}}5.3 添加实体
创建包 entity 编写实体类 User.java(此处使用了 Lombok 简化代码)
@Datapublic class User {private Long id;private String name;private Integer age;private String email;}查看编译结果
创建包 mapper 编写Mapper 接口: UserMapper.java
@Repositorypublic interface UserMapper extends BaseMapper<User> {}添加测试类,进行功能测试:
@SpringBootTestclass DemomptestApplicationTests {@Autowiredprivate UserMapper userMapper;@Testpublic void findAll() {List<User> users = userMapper.selectList(null);System.out.println(users);}}注意:
IDEA在 userMapper 处报错,因为找不到注入的对象,因为类是动态创建的,但是程序可以正确的执行。
为了避免报错,可以在 dao 层 的接口上添加 @Repository 注解
通过以上几个简单的步骤,我们就实现了 User 表的 CRUD 功能,甚至连 XML 文件都不用编写!
(注意:以上并不是医疗项目中所需要的表设计以及代码,以上只是个演练)
查看控制台输出:
注意:数据库插入id值默认为:全局唯一id
MyBatis-Plus默认的主键策略是:ASSIGN_ID (使用了雪花算法)
@TableId(type = IdType.ASSIGN_ID)private String id;雪花算法:分布式ID生成器
雪花算法是由Twitter公布的分布式主键生成算法,它能够保证不同表的主键的不重复性,以及相同表的主键的有序性。
核心思想:
长度共64bit(一个long型)。需要在创建数据表的时候设置主键自增
实体字段中配置 @TableId(type = IdType.AUTO)
@TableId(type = IdType.AUTO)private Long id;要想影响所有实体的配置,可以设置全局主键配置
#全局设置主键生成策略mybatis-plus.global-config.db-config.id-type=auto注意:update时生成的sql自动是动态sql:UPDATE user SET age=? WHERE id=?
//修改@Testpublic void testUpdate() {User user = new User();user.setId(1340868235401764865L);user.setN("lucymary");int count = userMapper.updateById(user);System.out.println(count);}需求描述:
项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等。
我们可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作
在User表中添加datetime类型的新的字段 create_time、update_time
实体上增加字段并添加自动填充注解
@TableField(fill = FieldFill.INSERT)private Date createTime; //create_time@TableField(fill = FieldFill.INSERT_UPDATE)private Date updateTime; //update_time注意:不要忘记添加 @Component 注解
@Componentpublic class MyMetaObjectHandler implements MetaObjectHandler {//mp执行添加操作,这个方法执行@Overridepublic void insertFill(MetaObject metaObject) {this.setFieldValByName("createTime",new Date(),metaObject);this.setFieldValByName("updateTime",new Date(),metaObject);}//mp执行修改操作,这个方法执行@Overridepublic void updateFill(MetaObject metaObject) {this.setFieldValByName("updateTime",new Date(),metaObject);}}**主要适用场景:**当要更新一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数据更新
乐观锁实现方式:
取出记录时,获取当前version添加 @Version 注解
@Versionprivate Integer version;创建包config,创建文件MybatisPlusConfig.java
此时可以删除主类中的 @MapperScan 扫描注解
@Configuration@MapperScan("com.atguigu.demomptest.mapper")public class MpConfig {/*** 乐观锁插件*/@Beanpublic OptimisticLockerInterceptor optimisticLockerInterceptor() {return new OptimisticLockerInterceptor();}}在 MybatisPlusConfig 中注册 Bean
/*** 乐观锁插件*/@Beanpublic OptimisticLockerInterceptor optimisticLockerInterceptor() {return new OptimisticLockerInterceptor();}完成了动态sql的foreach的功能
//多个id批量查询@Testpublic void testSelect1() {List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));System.out.println(users);}通过map封装查询条件
注意:map中的key对应数据库中的列名。如:数据库user_id,实体类是userId,这时map的key需要填写user_id
//简单条件查询@Testpublic void testSelect2() {Map<String, Object> columnMap = new HashMap<>();columnMap.put("name","Jack");columnMap.put("age",20);List<User> users = userMapper.selectByMap(columnMap);System.out.println(users);}MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能
配置类中添加@Bean配置
/*** 分页插件*/@Beanpublic PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();}测试:最终通过page对象获取相关数据
//分页查询@Testpublic void testSelectPage() {Page<User> page = new Page(1,3);Page<User> userPage = userMapper.selectPage(page, null);//返回对象得到分页所有数据long pages = userPage.getPages(); //总页数long current = userPage.getCurrent(); //当前页List<User> records = userPage.getRecords(); //查询数据集合long total = userPage.getTotal(); //总记录数boolean hasNext = userPage.hasNext(); //下一页boolean hasPrevious = userPage.hasPrevious(); //上一页System.out.println(pages);System.out.println(current);System.out.println(records);System.out.println(total);System.out.println(hasNext);System.out.println(hasPrevious);}当指定了特定的查询列时,希望分页结果列表只返回被查询的列,而不是很多null值
测试selectMapsPage分页:结果集是Map
@Testpublic void testSelectMapsPage() {//Page不需要泛型Page<Map<String, Object>> page = newPage<>(1, 5);Page<Map<String, Object>> pageParam = userMapper.selectMapsPage(page, null);List<Map<String, Object>> records = pageParam.getRecords();records.forEach(System.out::println);System.out.println(pageParam.getCurrent());System.out.println(pageParam.getPages());System.out.println(pageParam.getSize());System.out.println(pageParam.getTotal());System.out.println(pageParam.hasNext());System.out.println(pageParam.hasPrevious());}逻辑删除的使用场景:
可以进行数据恢复
有关联数据,不便删除
添加 deleted字段
ALTERTABLE `user` ADD COLUMN `deleted` boolean DEFAULT false添加deleted 字段,并加上 @TableLogic 注解 (需要自动填充)
@TableLogic@TableField(fill = FieldFill.INSERT)//添加的时候设置值(0填充private Integer deleted;application.properties 加入以下配置,此为默认值,如果你的默认值和mp默认的一样,该配置可无
mybatis-plus.global-config.db-config.logic-delete-value=1mybatis-plus.global-config.db-config.logic-not-delete-value=0测试后发现,数据并没有被删除,deleted字段的值由0变成了1
测试后分析打印的sql语句,是一条update
注意:被删除前,数据的deleted 字段的值必须是 0,才能被选取出来执行逻辑删除的操作
@Testpublic void testLogicDelete() {int result = userMapper.deleteById(1L);system.out.println(result);}MyBatis Plus中查询操作也会自动添加逻辑删除字段的判断
@Testpublic void testLogicDeleteSelect() {List<User> users = userMapper.selectList(null);users.forEach(System.out::println);}注意:seletOne()返回的是一条实体记录,当出现多条时会报错
@Testpublic void testSelectOne() {QueryWrapper<User>queryWrapper = newQueryWrapper<>();queryWrapper.eq("name", "Tom");Useruser = userMapper.selectOne(queryWrapper);//只能返回一条记录,多余一条则抛出异常System.out.println(user);}包含大小边界
@Testpublic void testSelectCount() {QueryWrapper<User>queryWrapper = newQueryWrapper<>();queryWrapper.between("age", 20, 30);Integer count = userMapper.selectCount(queryWrapper); //返回数据数量System.out.println(count);}selectMaps()返回Map集合列表,通常配合select()使用
@Testpublic void testSelectMaps() {QueryWrapper<User>queryWrapper = newQueryWrapper<>();queryWrapper.select("name", "age").like("name", "e").likeRight("email", "5");List<Map<String, Object>>maps = userMapper.selectMaps(queryWrapper);//返回值是Map列表maps.forEach(System.out::println);}查询方式说明
setSqlSelect设置 SELECT 查询字段