Java-08 深入浅出 MyBatis - 多对多模型 SqlMapConfig 与 Mapper 详细讲解测试

news2024/11/25 19:22:03

点一下关注吧!!!非常感谢!!持续更新!!!

大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html

请添加图片描述

目前已经更新到了:

  • MyBatis(正在更新)

多对多

在数据库设计中,“多对多”关系是指两张表中的记录可以互相关联,多条记录可以关联多条记录。例如,“学生”表和“课程”表之间的关系可能是多对多,因为一个学生可以选修多门课程,而一门课程也可能被多名学生选修。

要实现多对多的关系,通常需要使用一个 中间表(关联表)。这个中间表起到桥梁的作用,将两个表的记录通过其主键关联起来。

多对多关系的特点

  • 双向性:A可以关联多个B,同时B也可以关联多个A。
  • 需要中间表:为了表示这种关系,通常使用一个中间表来维护关联。
  • 灵活性高:多对多关系非常适合用来表示复杂的业务逻辑,尤其是在需要动态添加或修改关系时。

多对多关系的扩展

添加额外字段

中间表可以扩展为更多功能。例如,可以为选课添加时间戳、成绩字段、是否通过等。

索引优化

为中间表中的外键添加索引,提高查询性能。

ORM 框架支持

现代框架(如 Hibernate、Django ORM)支持多对多关系的自动管理。在代码中只需要声明模型的关系,底层会自动生成并管理中间表。

查询模型

在这里插入图片描述

用户表和角色的关系,一个用户有多个角色,一个角色被多个用户使用。
多对多的查询的需求,查询用户同时查询出该用户所有的角色。

创建表

wzk_user_role

CREATE TABLE `wzk_user_role` (
  `id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `role_id` int(11) NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

wzk_role

CREATE TABLE `wzk_role` (
  `id` int(11) NOT NULL,
  `rolename` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

插入数据

wzk_user_role

INSERT INTO wzk_user_role
VALUES(1, 1, 1);

INSERT INTO wzk_user_role
VALUES(1, 2, 2);

wzk_role

INSERT INTO wzk_role
VALUES(1, "ADMIN");

INSERT INTO wzk_role
VALUES(2, "USER");

查询语句

select u.*,r.*,r.id rid from wzk_user u 
left join wzk_user_role ur on u.id=ur.user_id
inner join wzk_role r on ur.role_id=r.id;

执行结果如下所示:
在这里插入图片描述

创建类

WzkUser

这里需要加入新的字段

package icu.wzk.model;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;
import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class WzkUser {
    private int id;
    private String username;
    private String password;
    private Date birthday;
    private List<WzkOrder> orderList;
    private List<WzkRole> roleList;
}

对应的截图如下所示:
在这里插入图片描述

WzkRole

package icu.wzk.model;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class WzkRole {
    private Integer id;
    private String rolename;
}

对应的截图如下所示:
在这里插入图片描述

UserMapper

package icu.wzk.mapper;

import icu.wzk.model.WzkUser;

import java.util.List;

public interface UserMapper {
    List<WzkUser> findAll();
    List<WzkUser> findAllUserAndRole();
}

对应的截图如下所示:
在这里插入图片描述

UserMapper.xml

<resultMap id="userRoleMap" type="icu.wzk.model.WzkUser">
    <result column="id" property="id"></result>
    <result column="username" property="username"></result>
    <result column="password" property="password"></result>
    <result column="birthday" property="birthday"></result>
    <collection property="roleList" ofType="icu.wzk.model.WzkRole">
        <result column="rid" property="id"></result>
        <result column="rolename" property="rolename"></result>
    </collection>
</resultMap>

<select id="findAllUserAndRole" resultMap="userRoleMap">
    SELECT u.*, r.*, r.id rid
    FROM wzk_user u
    LEFT JOIN wzk_user_role ur on u.id=ur.user_id
    INNER JOIN wzk_role r on ur.role_id=r.id;
</select>

对应的截图如下所示:
在这里插入图片描述

编写代码

package icu.wzk;

import icu.wzk.mapper.UserMapper;
import icu.wzk.model.WzkUser;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class WzkIcu10 {
    public static void main(String[] args) throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
                .build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<WzkUser> dataList = userMapper.findAllUserAndRole();
        dataList.forEach(System.out::println);
        sqlSession.close();
    }
}

代码的截图如下所示:
在这里插入图片描述

运行结果

运行上面的代码,控制台输出的结果如下所示:

WzkUser(id=1, username=wzk, password=icu, birthday=Mon Nov 11 00:00:00 CST 2024, orderList=null, roleList=[WzkRole(id=1, rolename=ADMIN)])
WzkUser(id=2, username=wzk2, password=icu2, birthday=Mon Nov 11 00:00:00 CST 2024, orderList=null, roleList=[WzkRole(id=2, rolename=USER)])
24/11/12 18:02:33 DEBUG jdbc.JdbcTransaction: Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@15b204a1]

对应的截图如下所示:
在这里插入图片描述

注意事项

  • 索引优化:为中间表的外键字段创建索引,提升查询性能。
  • 关系约束:使用外键约束维护数据一致性,避免孤立数据。
  • 批量操作:在大规模插入、更新时,尽量使用批量操作,提升效率。
  • 软删除:中间表可以设计“软删除”标志位,用于保留历史记录。

大表的分表与分库

问题背景

在超大规模应用中,单表可能变得过于庞大,导致性能问题。

解决方法

  • 垂直分表:将额外字段分离,减少单表宽度。
  • 水平分表:将记录按学生或课程拆分到多个表。
  • 分库:将不同表分布在多个数据库实例上。

日志和监控

问题背景

多对多关系中的数据修改频繁,容易引入错误,例如重复记录、孤立记录等。

解决方法

  • 日志记录:记录每次数据操作的详细信息。
  • 监控工具:定期检查中间表是否存在孤立记录或重复记录。

暂时小结

优化多对多关系模型需要从多个方面入手:

  • 提升性能:通过索引、分区、批量操作等方式优化查询和更新。
  • 保证数据一致性:通过外键约束和事务处理避免数据异常。
  • 提高灵活性:通过软删除和日志记录保留历史数据,支持恢复和审计。
  • 应对大数据场景:通过分区、分表或分库设计,确保系统扩展性。

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

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

相关文章

IDEA使用tips(LTS✍)

一、查找项目中某个外部库依赖类的pom来源 1、显示图 2、导出Maven 项目依赖的可视化输出文件 3、点击要查找的目标类&#xff0c;项目中定位后复制依赖名称 4、在导出的依赖的可视化文件中搜索查找 5、综上得到&#xff0c;Around类来自于pom中的spring-boot-starter-aop:jar…

【LLM训练系列02】如何找到一个大模型Lora的target_modules

方法1&#xff1a;观察attention中的线性层 import numpy as np import pandas as pd from peft import PeftModel import torch import torch.nn.functional as F from torch import Tensor from transformers import AutoTokenizer, AutoModel, BitsAndBytesConfig from typ…

如何选择服务器

如何选择服务器 选择服务器时应考虑以下几个关键因素&#xff1a; 性能需求。根据网站的预期流量和负载情况&#xff0c;选择合适的处理器、内存和存储容量。考虑网站是否需要处理大量动态内容或高分辨率媒体文件。 可扩展性。选择一个可以轻松扩展的服务器架构&#xff0c;以便…

C++共享智能指针

C中没有垃圾回收机制&#xff0c;必须自己释放分配的内存&#xff0c;否则就会造成内存泄漏。解决这个问题最有效的方式是使用智能指针。 智能指针是存储指向动态分配(堆)对象指针的类&#xff0c;用于生存期的控制&#xff0c;能够确保在离开指针所在作用域时&#xff0c;自动…

python Flask指定IP和端口

from flask import Flask, request import uuidimport json import osapp Flask(__name__)app.route(/) def hello_world():return Hello, World!if __name__ __main__:app.run(host0.0.0.0, port5000)

虚幻引擎---初识篇

一、学习途径 虚幻引擎官方文档&#xff1a;https://dev.epicgames.com/documentation/zh-cn/unreal-engine/unreal-engine-5-5-documentation虚幻引擎在线学习平台&#xff1a;https://dev.epicgames.com/community/unreal-engine/learning哔哩哔哩&#xff1a;https://www.b…

Java开发经验——SpringRestTemplate常见错误

摘要 本文分析了在使用Spring框架的RestTemplate发送表单请求时遇到的常见错误。主要问题在于将表单参数错误地以JSON格式提交&#xff0c;导致服务器无法正确解析参数。文章提供了错误案例的分析&#xff0c;并提出了修正方法。 1. 表单参数类型是MultiValueMap RestControl…

oracle会话追踪

一 跟踪当前会话 1.1 查看当前会话的SID,SERIAL# #在当前会话里执行 示例&#xff1a; SQL> select distinct userenv(sid) from v$mystat; USERENV(SID) -------------- 1945 SQL> select distinct sid,serial# from v$session where sid1945; SID SERIAL# …

数据可视化复习2-绘制折线图+条形图(叠加条形图,并列条形图,水平条形图)+ 饼状图 + 直方图

目录 目录 一、绘制折线图 1.使用pyplot 2.使用numpy ​编辑 3.使用DataFrame ​编辑 二、绘制条形图&#xff08;柱状图&#xff09; 1.简单条形图 2.绘制叠加条形图 3.绘制并列条形图 4.水平条形图 ​编辑 三、绘制饼状图 四、绘制散点图和直方图 1.散点图 2…

postgresql按照年月日统计历史数据

1.按照日 SELECT a.time,COALESCE(b.counts,0) as counts from ( SELECT to_char ( b, YYYY-MM-DD ) AS time FROM generate_series ( to_timestamp ( 2024-06-01, YYYY-MM-DD hh24:mi:ss ), to_timestamp ( 2024-06-30, YYYY-MM-DD hh24:mi:ss ), 1 days ) AS b GROUP BY tim…

【JavaEE初阶 — 多线程】定时器的应用及模拟实现

目录 1. 标准库中的定时器 1.1 Timer 的定义 1.2 Timer 的原理 1.3 Timer 的使用 1.4 Timer 的弊端 1.5 ScheduledExecutorService 2. 模拟实现定时器 2.1 实现定时器的步骤 2.1.1 定义类描述任务 定义类描述任务 第一种定义方法 …

一文学会Golang里拼接字符串的6种方式(性能对比)

g o l a n g golang golang的 s t r i n g string string类型是不可修改的&#xff0c;对于拼接字符串来说&#xff0c;本质上还是创建一个新的对象将数据放进去。主要有以下几种拼接方式 拼接方式介绍 1.使用 s t r i n g string string自带的运算符 ans ans s2. 使用…

LeetCode 3244.新增道路查询后的最短距离 II:贪心(跃迁合并)-9行py(O(n))

【LetMeFly】3244.新增道路查询后的最短距离 II&#xff1a;贪心&#xff08;跃迁合并&#xff09;-9行py&#xff08;O(n)&#xff09; 力扣题目链接&#xff1a;https://leetcode.cn/problems/shortest-distance-after-road-addition-queries-ii/ 给你一个整数 n 和一个二维…

MyBatis中特殊SQL的执行

目录 1.模糊查询 2.批量删除 3.动态设置表名 4.添加功能获取自增的主键 1.模糊查询 List<User> getUserByLike(Param("username") String username); <select id"getUserByLike" resultType"com.atguigu.mybatis.pojo.User">&…

ES 基本使用与二次封装

概述 基本了解 Elasticsearch 是一个开源的分布式搜索和分析引擎&#xff0c;基于 Apache Lucene 构建。它提供了对海量数据的快速全文搜索、结构化搜索和分析功能&#xff0c;是目前流行的大数据处理工具之一。主要特点即高效搜索、分布式存储、拓展性强 核心功能 全文搜索:…

Azkaban部署

首先我们需要现在相关的组件&#xff0c;在这里已经给大家准备好了相关的安装包&#xff0c;有需要的可以自行下载。 只需要启动hadoop集群就可以&#xff0c;如果现在你的hive是打开的&#xff0c;那么请你关闭&#xff01;&#xff01;&#xff01; 如果不关会造成证书冲突…

Jmeter中的定时器

4&#xff09;定时器 1--固定定时器 功能特点 固定延迟&#xff1a;在每个请求之间添加固定的延迟时间。精确控制&#xff1a;可以精确控制请求的发送频率。简单易用&#xff1a;配置简单&#xff0c;易于理解和使用。 配置步骤 添加固定定时器 右键点击需要添加定时器的请求…

JavaEE初学07

JavaEE初学07 MybatisORMMybatis一对一结果映射一对多结果映射 Mybatis动态sqlif标签trim标签where标签set标签foreach标签补充 Mybatis Mybatis是一款优秀的持久层框架&#xff0c;他支持自定义SQL、存储过程以及高级映射。Mybatis几乎免除了所有的JDBC代码以及设置参数和获取…

【layui】table的switch、edit修改

<title>简单表格数据</title><div class"layui-card layadmin-header"><div class"layui-breadcrumb" lay-filter"breadcrumb"><a>系统设置</a><a>简单表格数据</a></div> </div>&…

工具使用_docker容器_crossbuild

1. 工具简介 2. 工具使用 拉取 multiarch/crossbuild 镜像&#xff1a; docker pull multiarch/crossbuild 创建工作目录和示例代码&#xff1a; mkdir -p ~/crossbuild-test cd ~/crossbuild-test 创建 helloworld.c &#xff1a; #include <stdio.h>int main() …