• mybatis plus中json格式实战


    1.pom.xml

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    4. <modelVersion>4.0.0</modelVersion>
    5. <parent>
    6. <groupId>org.springframework.boot</groupId>
    7. <artifactId>spring-boot-starter-parent</artifactId>
    8. <version>2.7.16</version>
    9. <relativePath/> <!-- lookup parent from repository -->
    10. </parent>
    11. <groupId>com.example</groupId>
    12. <artifactId>StudyMybatisPlus</artifactId>
    13. <version>0.0.1-SNAPSHOT</version>
    14. <name>StudyMybatisPlus</name>
    15. <description>Demo project for Spring Boot</description>
    16. <properties>
    17. <java.version>11</java.version>
    18. </properties>
    19. <dependencies>
    20. <dependency>
    21. <groupId>org.springframework.boot</groupId>
    22. <artifactId>spring-boot-starter</artifactId>
    23. </dependency>
    24. <dependency>
    25. <groupId>org.springframework.boot</groupId>
    26. <artifactId>spring-boot-starter-web</artifactId>
    27. </dependency>
    28. <dependency>
    29. <groupId>org.springframework.boot</groupId>
    30. <artifactId>spring-boot-starter-test</artifactId>
    31. <scope>test</scope>
    32. </dependency>
    33. <dependency>
    34. <groupId>com.baomidou</groupId>
    35. <artifactId>mybatis-plus-boot-starter</artifactId>
    36. <version>3.5.1</version>
    37. </dependency>
    38. <dependency>
    39. <groupId>mysql</groupId>
    40. <artifactId>mysql-connector-java</artifactId>
    41. <version>8.0.21</version>
    42. </dependency>
    43. <dependency>
    44. <groupId>org.projectlombok</groupId>
    45. <artifactId>lombok</artifactId>
    46. <version>1.18.12</version>
    47. </dependency>
    48. <dependency>
    49. <groupId>org.reflections</groupId>
    50. <artifactId>reflections</artifactId>
    51. <version>0.9.10</version>
    52. </dependency>
    53. </dependencies>
    54. <build>
    55. <plugins>
    56. <plugin>
    57. <groupId>org.springframework.boot</groupId>
    58. <artifactId>spring-boot-maven-plugin</artifactId>
    59. </plugin>
    60. </plugins>
    61. </build>
    62. </project>

    2.application.yml

    1. #配置端口
    2. server:
    3. port: 80
    4. spring:
    5. #配置数据源
    6. datasource:
    7. #配置数据源类型
    8. type: com.zaxxer.hikari.HikariDataSource
    9. #配置连接数据库的信息
    10. driver-class-name: com.mysql.cj.jdbc.Driver
    11. url: jdbc:mysql://localhost:3306/mybatis_plus?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT&allowPublicKeyRetrieval=true
    12. username: root
    13. password: root
    14. #mybatis plus配置
    15. mybatis-plus:
    16. configuration:
    17. log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    18. # 字段名和数据库中字段名一致
    19. map-underscore-to-camel-case: false
    20. global-config:
    21. db-config:
    22. #配置mybatis plus 在更新时只更新非空和非NULL的字段
    23. update-strategy: not_empty
    24. # 实体名字和数据库表名一致
    25. table-underline: false
    26. # 需要转化为json的字段
    27. map-field-scan-package: "com.example"

    3.MapData.java

    1. package com.example.studymybatisplus.anno;
    2. import java.lang.annotation.ElementType;
    3. import java.lang.annotation.Retention;
    4. import java.lang.annotation.RetentionPolicy;
    5. import java.lang.annotation.Target;
    6. @Target({ElementType.FIELD})
    7. @Retention(RetentionPolicy.RUNTIME)
    8. public @interface MapData {
    9. }

    4.TypeConfig.java

    1. package com.example.studymybatisplus.config;
    2. import com.baomidou.mybatisplus.annotation.TableName;
    3. import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
    4. import com.baomidou.mybatisplus.autoconfigure.MybatisPlusPropertiesCustomizer;
    5. import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
    6. import com.example.studymybatisplus.anno.MapData;
    7. import org.reflections.Reflections;
    8. import org.springframework.beans.factory.annotation.Value;
    9. import org.springframework.context.annotation.Configuration;
    10. import java.lang.reflect.Field;
    11. import java.util.HashSet;
    12. import java.util.Set;
    13. /**
    14. * 注册需要转换为Map的处理器
    15. */
    16. @Configuration
    17. public class TypeConfig implements MybatisPlusPropertiesCustomizer {
    18. @Value("${map-field-scan-package}")
    19. String packageName;
    20. @Override
    21. public void customize(MybatisPlusProperties properties) {
    22. Reflections reflections = new Reflections(this.packageName);
    23. Set<Class<?>> typesAnnotatedWith = reflections.getTypesAnnotatedWith(TableName.class);
    24. Set<Class<?>> mapTypeSet = new HashSet<>();
    25. typesAnnotatedWith.forEach(clazz -> {
    26. Field[] fields = clazz.getDeclaredFields();
    27. for (Field field : fields) {
    28. field.setAccessible(true);
    29. if (field.getAnnotation(MapData.class) != null) {
    30. if(mapTypeSet.contains(field.getType())){
    31. continue;
    32. }
    33. mapTypeSet.add(field.getType());
    34. properties.getConfiguration().getTypeHandlerRegistry().register(field.getType(), JacksonTypeHandler.class);
    35. }
    36. }
    37. });
    38. }
    39. }

    5.UserMapper.java

    1. package com.example.studymybatisplus.mapper;
    2. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    3. import com.example.studymybatisplus.pojo.User;
    4. import org.springframework.stereotype.Repository;
    5. import java.util.List;
    6. @Repository
    7. public interface UserMapper extends BaseMapper {
    8. /**
    9. * 测试自定义sql
    10. */
    11. List getUserList();
    12. }

    6.User.java

    1. package com.example.studymybatisplus.pojo;
    2. import com.baomidou.mybatisplus.annotation.IdType;
    3. import com.baomidou.mybatisplus.annotation.TableId;
    4. import com.baomidou.mybatisplus.annotation.TableName;
    5. import com.example.studymybatisplus.anno.MapData;
    6. import lombok.Data;
    7. @Data
    8. @TableName(autoResultMap = true)
    9. public class User {
    10. @TableId(type = IdType.AUTO)
    11. private Long id;
    12. private String name = "";
    13. private Integer age = 0;
    14. @MapData
    15. private UserInfo info = new UserInfo();
    16. }

    7.UserInfo.java

    1. package com.example.studymybatisplus.pojo;
    2. import lombok.Data;
    3. import java.util.HashMap;
    4. import java.util.Map;
    5. @Data
    6. public class UserInfo {
    7. private String address="";
    8. private Map map = new HashMap<>();
    9. private DataVo dataVo = new DataVo();
    10. private Integer aaa;
    11. }

    8.DataVo.java

    1. package com.example.studymybatisplus.pojo;
    2. import lombok.Data;
    3. import java.util.HashMap;
    4. import java.util.Map;
    5. @Data
    6. public class DataVo {
    7. private Integer num;
    8. private Map map2 = new HashMap<>();
    9. }

    9.主方法

    1. package com.example.studymybatisplus;
    2. import org.mybatis.spring.annotation.MapperScan;
    3. import org.springframework.boot.SpringApplication;
    4. import org.springframework.boot.autoconfigure.SpringBootApplication;
    5. @SpringBootApplication
    6. @MapperScan("com.example.studymybatisplus.mapper")
    7. public class StudyMybatisPlusApplication {
    8. public static void main(String[] args) {
    9. SpringApplication.run(StudyMybatisPlusApplication.class, args);
    10. }
    11. }

    10.UserMapper.xml   // 测试自定义sql

    1. mapper
    2. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    4. <mapper namespace="com.example.studymybatisplus.mapper.UserMapper">
    5. <select id="getUserList" resultType="com.example.studymybatisplus.pojo.User">
    6. SELECT id, name, age, info
    7. FROM user
    8. select>
    9. mapper>

    可见,完全不需要ResultMap了,非常完美!!!

    11.测试用例

    1. package com.example.studymybatisplus;
    2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    3. import com.example.studymybatisplus.mapper.UserMapper;
    4. import com.example.studymybatisplus.pojo.User;
    5. import org.junit.jupiter.api.Test;
    6. import org.springframework.beans.factory.annotation.Autowired;
    7. import org.springframework.boot.test.context.SpringBootTest;
    8. import org.springframework.transaction.annotation.Transactional;
    9. import java.util.List;
    10. import java.util.Map;
    11. import java.util.Random;
    12. @SpringBootTest
    13. class StudyMybatisPlusApplicationTests {
    14. @Autowired
    15. UserMapper userMapper;
    16. @Test
    17. void insertAndQuery() {
    18. for (int i = 0; i < 10; i++) {
    19. User newUser = new User();
    20. newUser.setName("xx");
    21. newUser.setAge(30);
    22. newUser.getInfo().setAddress("北京 " + new Random().nextInt(10000));
    23. newUser.getInfo().getMap().put(1, 123);
    24. newUser.getInfo().getDataVo().setNum(222);
    25. newUser.getInfo().getDataVo().getMap2().put(666, 888);
    26. newUser.getInfo().getDataVo2().setNum(112222);
    27. int insert = userMapper.insert(newUser);
    28. System.out.println("insert:" + insert);
    29. System.out.println(newUser);
    30. // 测试QueryWrapper
    31. List<User> userList1 = userMapper.selectList(new QueryWrapper<User>().lambda());
    32. System.out.println(userList1);
    33. // 现在自定义sql也完全不需要ResultMap了
    34. List<User> userList2 = userMapper.getUserList();
    35. System.out.println(userList2);
    36. }
    37. }
    38. @Test
    39. void clearAllData() {
    40. userMapper.delete(null);
    41. }
    42. @Test
    43. void addOneUser() {
    44. User user = new User();
    45. Map<Integer, Integer> receiveState = user.getInfo().getReceiveState();
    46. receiveState.put(1, 0);
    47. receiveState.put(2, 1);
    48. userMapper.insert(user);
    49. System.out.println(user.getId());
    50. }
    51. @Test
    52. void updateUser() {
    53. User user = userMapper.selectById(58);
    54. user.getInfo().getReceiveState().put(3, 3);
    55. userMapper.updateById(user);
    56. User user2 = userMapper.selectById(59);
    57. user2.getInfo().getReceiveState().put(33, 33);
    58. userMapper.updateById(user2);
    59. }
    60. }

    9.输出

    1. JDBC Connection [HikariProxyConnection@1111497601 wrapping com.mysql.cj.jdbc.ConnectionImpl@f1d1463] will not be managed by Spring
    2. ==> Preparing: SELECT id,name,age,info FROM user
    3. ==> Parameters:
    4. <== Columns: id, name, age, info
    5. <== Row: 1, xx, 30, <<BLOB>>
    6. <== Row: 2, xx, 30, <<BLOB>>
    7. <== Row: 3, xx, 30, <<BLOB>>
    8. <== Total: 3
    9. Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@27502e5c]
    10. [User(id=1, name=xx, age=30, info=UserInfo(address=北京2, map={1=123}, dataVo=DataVo(num=222, map2={666=888}), aaa=null)), User(id=2, name=xx, age=30, info=UserInfo(address=北京1, map={1=123}, dataVo=DataVo(num=222, map2={666=888}), aaa=null)), User(id=3, name=xx, age=30, info=UserInfo(address=北京 5542, map={1=123}, dataVo=DataVo(num=222, map2={666=888}), aaa=null))]
    11. Creating a new SqlSession
    12. SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@12266084] was not registered for synchronization because synchronization is not active
    13. JDBC Connection [HikariProxyConnection@1839613624 wrapping com.mysql.cj.jdbc.ConnectionImpl@f1d1463] will not be managed by Spring
    14. ==> Preparing: SELECT id, name, age, info FROM user
    15. ==> Parameters:
    16. <== Columns: id, name, age, info
    17. <== Row: 1, xx, 30, <<BLOB>>
    18. <== Row: 2, xx, 30, <<BLOB>>
    19. <== Row: 3, xx, 30, <<BLOB>>
    20. <== Total: 3
    21. Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@12266084]
    22. [User(id=1, name=xx, age=30, info=UserInfo(address=北京2, map={1=123}, dataVo=DataVo(num=222, map2={666=888}), aaa=null)), User(id=2, name=xx, age=30, info=UserInfo(address=北京1, map={1=123}, dataVo=DataVo(num=222, map2={666=888}), aaa=null)), User(id=3, name=xx, age=30, info=UserInfo(address=北京 5542, map={1=123}, dataVo=DataVo(num=222, map2={666=888}), aaa=null))]
    23. 2023-10-22 00:14:07.258 INFO 10232 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
    24. 2023-10-22 00:14:07.274 INFO 10232 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.

    可见,业务层可以愉快的使用Entity了,完全不需要关心是不是自定义sql,完美支持json,这样子mysql和mongodb就是一模一样了,只不过是复杂的类型多了一个自定义的@MapData注解!!

    总结:

    1.增加字段发现确实是可以的,删除字段就报错,所以这也符合游戏的目标也就是不能删和改字段名字。

    2.注意在Entity中给默认值,因为我们用的都是包装类型,使用xdb的经验告诉我,所有的数据要给默认值,Map类型也要初始化一下。

  • 相关阅读:
    Docker中搭建Elasticsearch+Kibana
    【2024秋招】2023-9-14 最右线下后端开发二面
    4+经典思路,肿瘤+WGCNA+预后模型鉴定预后标志物
    vue中定义属性和方法,响应式定义
    基于单片机的甲醛检测器设计
    skimage学习(3)——使灰度滤镜适应 RGB 图像、免疫组化染色分离颜色、过滤区域最大值
    Linux入门第一天——linux基本概念
    计算机的基础知识
    中国程序员容易发错音的单词「GitHub 热点速览 v.22.23」
    聊聊Java的垃圾回收机制
  • 原文地址:https://blog.csdn.net/themagickeyjianan/article/details/133967932