mybatis plus中json格式实战

news/2024/7/24 7:05:48 标签: mybatis, json

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.16</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>StudyMybatisPlus</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>StudyMybatisPlus</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.21</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>

        <dependency>
            <groupId>org.reflections</groupId>
            <artifactId>reflections</artifactId>
            <version>0.9.10</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

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<Class<?>> 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<User> {
    /**
     * 测试自定义sql
     */
    List<User> 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<Integer, Integer> 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<Integer, Integer> 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

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.example.studymybatisplus.mapper.UserMapper">
    <select id="getUserList" resultType="com.example.studymybatisplus.pojo.User">
        SELECT id, name, age, info
        FROM user
    </select>
</mapper>

可见,完全不需要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<User> lambda = new QueryWrapper<User>().lambda();
            List<User> userList1 = userMapper.selectList(lambda);
            System.out.println(userList1);

            // 现在自定义sql也完全不需要ResultMap了
            List<User> 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, <<BLOB>>
<==        Row: 2, xx, 30, <<BLOB>>
<==        Row: 3, xx, 30, <<BLOB>>
<==      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, <<BLOB>>
<==        Row: 2, xx, 30, <<BLOB>>
<==        Row: 3, xx, 30, <<BLOB>>
<==      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类型也要初始化一下。


http://www.niftyadmin.cn/n/5111223.html

相关文章

java蓝桥杯前10题总结

文章目录 1.单词分析1.代码2.知识点 2.成绩统计1.代码2.知识点1.如何四舍五入&#xff1f;2.如何保留小数点后几位小数呢&#xff1f; 3.最短路4.回文日期1.代码2.知识点1.日期类2.字符串细节3.连等的细节 5.门牌制作1.代码 6.卡片1.代码2.细节 7.数字三角形1.代码2.细节 8.成绩…

渲染过程JS 文件的处理方式

渲染过程中遇到 JS 文件怎么处理&#xff1f;&#xff08;浏览器解析过程&#xff09; JavaScript 的加载、解析与执行会阻塞文档的解析&#xff0c;也就是说&#xff0c;在构建 DOM 时&#xff0c;HTML 解析器若遇到了 JavaScript&#xff0c;那么它会暂停文档的解析&#xf…

Selenium定位元素的方法css和xpath的区别!

selenium是一种自动化测试工具&#xff0c;它可以通过不同的定位方式来识别网页上的元素&#xff0c;如id、name、class、tag、link text、partial link text、css和xpath。 css和xpath是两种常用的定位方式&#xff0c;它们都可以通过元素的属性或者层级关系来定位元素&#…

react常用hooks总结

React Hooks常用总结 Hooks简介 概述 Hooks是React16.8的新增特性。它可以让你在不编写class的情况下使用state,以及其他的React特性,用简单的话来说&#xff0c;React Hooks就是一些React提供的内置函数&#xff0c;这些函数可以让Function Component和Class Component一样能…

Python---练习:while循环案例:猜数字

需求&#xff1a; 计算机从1 ~ 10之间随机生成一个数字&#xff0c;然后提示输入数字&#xff0c;如果我们输入的数字与随机数相等&#xff0c;则提示恭喜你&#xff0c;答对了。如果输入的数字比随机数大&#xff0c;则提示&#xff0c;猜大了。反之&#xff0c;则提示猜小了…

性能测试基础理论

什么是性能测试 01生活中遇到的软件性能问题 10月20晚&#xff0c;淘宝崩了&#xff0c;给客服发消息发不出去&#xff1b;2022.3.24抖音崩了&#xff0c;视频无法正常播放。 02性能测试定义 测试人员借助性能测试工具&#xff0c;模拟系统在不同场景下&#xff0c;对应的性…

推特爆火!超越ChatGPT和Llama2,新一代检索增强方法Self-RAG来了原创

作者 | ZenMoore 前言 大型语言模型&#xff08;LLMs&#xff09;具有出色的能力&#xff0c;但由于完全依赖其内部的参数化知识&#xff0c;它们经常产生包含事实错误的回答&#xff0c;尤其在长尾知识中。为了解决这一问题&#xff0c;之前的研究人员提出了检索增强生成&…

【汇编语言-王爽】第三章:寄存器(内存访问)

知识点 CPU中&#xff0c;用16位寄存器来存储一个字。字的低位字节存放在低地址单元中&#xff0c;高位字节存放在高地址单元中。DS寄存器&#xff0c;通常用来存放要访问数据的段地址。栈是一种具有特殊访问方式的存储空间&#xff1a;后进先出。push 和 pop。入栈和出栈都是…