mybatis plus中json格式实战

1.pom.xml



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.7.16
         
    
    com.example
    StudyMybatisPlus
    0.0.1-SNAPSHOT
    StudyMybatisPlus
    Demo project for Spring Boot
    
        11
    
    
        
            org.springframework.boot
            spring-boot-starter
        
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
            com.baomidou
            mybatis-plus-boot-starter
            3.5.1
        
        
            mysql
            mysql-connector-java
            8.0.21
        
        
            org.projectlombok
            lombok
            1.18.12
        

        
            org.reflections
            reflections
            0.9.10
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


2.application.yml

#配置端口
server:
  port: 80

spring:
  #配置数据源
  datasource:
    #配置数据源类型
    type: com.zaxxer.hikari.HikariDataSource
    #配置连接数据库的信息
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_plus?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT
    username: root
    password: root

#mybatis plus配置
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

    # 字段名和数据库中字段名一致
    map-underscore-to-camel-case: false
  global-config:
    db-config:
      #配置mybatis plus 在更新时只更新非空和非NULL的字段
      update-strategy: not_empty

      # 实体名字和数据库表名一致
      table-underline: false

# 需要转化为json的字段
map-field-scan-package: "com.example"

3.MapData.java

package com.example.studymybatisplus.anno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MapData {
}

4.TypeConfig.java

package com.example.studymybatisplus.config;

import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusPropertiesCustomizer;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.example.studymybatisplus.anno.MapData;
import org.reflections.Reflections;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import java.lang.reflect.Field;
import java.util.Set;

/**
 * 注册需要转换为Map的处理器
 */
@Configuration
public class TypeConfig implements MybatisPlusPropertiesCustomizer {

    @Value("${map-field-scan-package}")
    String packageName;

    @Override
    public void customize(MybatisPlusProperties properties) {
        Reflections reflections = new Reflections(this.packageName);
        Set> typesAnnotatedWith = reflections.getTypesAnnotatedWith(TableName.class);
        typesAnnotatedWith.forEach(clazz -> {
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                if (field.getAnnotation(MapData.class) != null) {
                    properties.getConfiguration().getTypeHandlerRegistry().register(field.getType(), JacksonTypeHandler.class);
                }
            }
        });
    }
}

5.UserMapper.java

package com.example.studymybatisplus.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.studymybatisplus.pojo.User;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface UserMapper extends BaseMapper {
    /**
     * 测试自定义sql
     */
    List getUserList();
}

6.User.java

package com.example.studymybatisplus.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.example.studymybatisplus.anno.MapData;
import lombok.Data;

@Data
@TableName(autoResultMap = true)
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name = "";
    private Integer age = 0;

    @MapData
    private UserInfo info = new UserInfo();
}

7.UserInfo.java

package com.example.studymybatisplus.pojo;

import lombok.Data;

import java.util.HashMap;
import java.util.Map;

@Data
public class UserInfo {
    private String address="";
    private Map map = new HashMap<>();
    private DataVo dataVo = new DataVo();
    private Integer aaa;
}

8.DataVo.java

package com.example.studymybatisplus.pojo;

import lombok.Data;

import java.util.HashMap;
import java.util.Map;

@Data
public class DataVo {
    private Integer num;
    private Map map2 = new HashMap<>();
}

9.主方法

package com.example.studymybatisplus;

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

@SpringBootApplication
@MapperScan("com.example.studymybatisplus.mapper")
public class StudyMybatisPlusApplication {
    public static void main(String[] args) {
        SpringApplication.run(StudyMybatisPlusApplication.class, args);
    }
}

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




    

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

11.测试用例

package com.example.studymybatisplus;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.studymybatisplus.mapper.UserMapper;
import com.example.studymybatisplus.pojo.User;
import com.example.studymybatisplus.pojo.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
import java.util.Random;

@SpringBootTest
class StudyMybatisPlusApplicationTests {

    @Autowired
    UserMapper userMapper;

    @Test
    void contextLoads() {
        for (int i = 0; i < 10; i++) {
            User newUser = new User();
            newUser.setName("xx");
            newUser.setAge(30);

            newUser.getInfo().setAddress("北京 " + new Random().nextInt(10000));
            newUser.getInfo().getMap().put(1, 123);

            newUser.getInfo().getDataVo().setNum(222);
            newUser.getInfo().getDataVo().getMap2().put(666, 888);

            newUser.getInfo().getDataVo2().setNum(112222);

            int insert = userMapper.insert(newUser);
            System.out.println("insert:" + insert);
            System.out.println(newUser);

            // 测试QueryWrapper
            LambdaQueryWrapper lambda = new QueryWrapper().lambda();
            List userList1 = userMapper.selectList(lambda);
            System.out.println(userList1);

            // 现在自定义sql也完全不需要ResultMap了
            List userList2 = userMapper.getUserList();
            System.out.println(userList2);
        }
    }
}

9.输出

JDBC Connection [HikariProxyConnection@1111497601 wrapping com.mysql.cj.jdbc.ConnectionImpl@f1d1463] will not be managed by Spring
==>  Preparing: SELECT id,name,age,info FROM user
==> Parameters: 
<==    Columns: id, name, age, info
<==        Row: 1, xx, 30, <>
<==        Row: 2, xx, 30, <>
<==        Row: 3, xx, 30, <>
<==      Total: 3
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@27502e5c]
[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))]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@12266084] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@1839613624 wrapping com.mysql.cj.jdbc.ConnectionImpl@f1d1463] will not be managed by Spring
==>  Preparing: SELECT id, name, age, info FROM user
==> Parameters: 
<==    Columns: id, name, age, info
<==        Row: 1, xx, 30, <>
<==        Row: 2, xx, 30, <>
<==        Row: 3, xx, 30, <>
<==      Total: 3
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@12266084]
[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))]
2023-10-22 00:14:07.258  INFO 10232 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
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类型也要初始化一下。

你可能感兴趣的:(#,springboot,mybatis,json)