每日学习之一万个为什么
Mybatis官网
https://mybatis.org/mybatis-3/zh_CN/configuration.html
Myabtis 入参
#{} 与 ${} 区别:前者占位符赋值,后者字符串拼接会在动态field和关键字用到但要防止SQL注入。
SQL中单个参数,占位符中建议写 形参名
如果是多个参数
- 方案1:形参列表从左到右默认为 arg0 arg1 / param 1 param 2
- 方案2:@Param(“别名”)
传参是实体类和map 实体类写属性名 map写key
Mybatis 结果集 resultType
DML 返回 int
DQL resultType:
- 返回类型全限定名
- Mybatis官网定义的别名
- 自定义标签设置Object别名
- @MapKey (value=" ") 加在mapper接口上
主键回显
DML标签中设置 主键回显属性
<insert id="insert" keyProperty="id" keyColumn="id" useGeneratedKeys="true">
        insert into user (username, password) values (#{username}, #{password})
    </insert>
主键赋值UUID函数
DML设置 selectkey 标签,标签中设置先执行
<selectKey keyProperty="id" resultType="int" order="AFTER">
            select REPLACE(UUID(), '-', '') AS id
        </selectKey>
结果映射 resultMap
推荐看官网
存储表关系(表关系)
- 一对一关系 (One-to-One)(hot-to-cold)
 这种关系指的是一个表中的每一条记录与另一个表中的唯一一条记录相关联。
- 实例: 在一个用户管理系统中,可以将用户的个人信息(如姓名、联系方式等)和用户的认证信息(如密码、安全问题等)分开存储。这样做的好处是可以保护敏感信息,并简化某些操作,比如更换联系方式时不需要修改认证信息。
 表A: Users (用户ID, 姓名, 联系方式)
 表B: UserAuths (用户ID, 密码, 安全问题)
- 一对多关系 (One-to-Many)
 这是一种常见关系,表示一个表中的单条记录可以关联到另一个表中的多条记录。
- 实例: 在订单处理系统中,一个客户可以下多个订单,但每个订单只属于一个客户。
 表A: Customers (客户ID, 客户名)
 表B: Orders (订单ID, 订单日期, 客户ID) 这里客户ID作为外键指向Customers表的客户ID。
- 多对多关系 (Many-to-Many)
 在这种关系中,一个表中的任何记录都可以关联到另一个表中的任意数量的记录,反之亦然。这种情况通常需要通过第三个表来实现,称为连接表或桥接表。
- 实例: 在一个课程注册系统中,学生可以选择多个课程,同时每个课程也可以由多名学生选修。
 表A: Students (学生ID, 学生名)
 表B: Courses (课程ID, 课程名)
 桥接表: StudentCourse (学生ID, 课程ID) 其中学生ID和课程ID分别是两个主表的外键。
- 自引用关系 (Self-referencing Relationship)
 有时候,表中的记录可能需要与同一张表中的其他记录建立联系,这被称为自引用关系。
- 实例: 在一个员工管理系统中,可能存在上级和下属的关系,即一名员工可能是另一名员工的直接上司。
 表: Employees (员工ID, 员工名, 上司ID) 这里的上司ID也是该表的一个字段,形成自引用关系。
查询表关系
查询操作是在某个表的角度去思考,设计查询结果集
设计忠告
- 只有真实发生多表查询时,才需要设计和修改实体类,否则不提前设计和修改实习类。
- 无论多少张表查,实体类设计都是两两考虑
- 在查询映射的时候,只需要关注本次查询的相关属性
多表查询案例
要求文件+SQL:
CREATE TABLE t_student(sid INT AUTO_INCREMENT PRIMARY KEY,sname VARCHAR(20));  
INSERT INTO t_student(sid,sname) VALUES(1,"二狗子"),(2,"驴蛋蛋");
CREATE TABLE t_detail(sid INT PRIMARY KEY,age INT , height DOUBLE(4,1));  
INSERT INTO t_detail(sid,age,height) VALUES(1,18,180.5),(2,19,163.4);
CREATE TABLE t_score(cid INT AUTO_INCREMENT PRIMARY KEY,cnum INT , sid INT ,uid INT);  
INSERT INTO t_score(cid,cnum,sid,uid) VALUES(1,80,1,1),(2,90,1,2),(3,70,2,1),(4,95,2,2);
CREATE TABLE t_course(uid INT AUTO_INCREMENT PRIMARY KEY,uname VARCHAR(20));  
INSERT INTO t_course(uid,uname) VALUES(1,"java"),(2,"php");
#需求1: 查询所有学生和学生详情信息
SELECT * FROM t_student ts JOIN t_detail td ON ts.sid = td.sid;
#需求2: 查询指定id的学生和学生分数信息
SELECT * FROM t_student ts JOIN t_score tc ON ts.sid = tc.sid WHERE ts.sid = 1;
#需求3: 查询全部分数和分数对应的课程
SELECT * FROM t_score tc JOIN t_course tu ON tc.uid = tu.uid;
#需求4: 查询全部学生和学生的分数以及分数对应的课程
SELECT * FROM t_student ts JOIN t_score tc ON ts.sid = tc.sid 
                           JOIN t_course tu ON tc.uid = tu.uid;
#需求5: 查询指定id的学生信息和详细信息以及分数和课程信息
SELECT * FROM t_student ts JOIN t_detail td ON ts.sid = td.sid
                           JOIN t_score tc ON ts.sid = tc.sid 
                           JOIN t_course tu ON tc.uid = tu.uid;
工程结构:
 
 Mapper映射参考:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace等于mapper接口类的全限定名 -->
<mapper namespace="com.qxy.mapper.StudentMapper">
    <resultMap id="map1" type="StudentDetail">
        <id column="sid" property="sid"/>
        <result column="sname" property="sname"/>
        <association property="detail" javaType="detail">
            <result property="age" column="age"/>
            <result property="height" column="height"/>
        </association>
    </resultMap>
    <resultMap id="map2" type="StudentScore">
        <id column="sid" property="sid"/>
        <result column="sname" property="sname"/>
        <collection property="scores"  ofType="Score">
            <id column="cid" property="cid"/>
            <result column="cnum" property="cnum"/>
        </collection>
    </resultMap>
    <resultMap id="map3" type="ScoreCourse">
        <id column="cid" property="cid"/>
        <result column="cnum" property="cnum"/>
        <association property="course" javaType="Course">
            <id column="uid" property="uid"/>
            <result column="uname" property="uname"/>
        </association>
    </resultMap>
    <resultMap id="map4" type="StudentScoreCourse">
        <id column="sid" property="sid"/>
        <result column="sname" property="sname"/>
        <association property="scoreCourse" javaType="ScoreCourse">
            <id column="cid" property="cid"/>
            <result column="cnum" property="cnum"/>
            <association property="course" javaType="Course">
                <id column="uid" property="uid"/>
                <result column="uname" property="uname"/>
            </association>
        </association>
    </resultMap>
    <resultMap id="map5" type="StudentDetailScoreCourse">
        <id column="stid" property="sid"/>
        <result column="sname" property="sname"/>
        <association property="detailScoreCourse" javaType="DetailScoreCourse">
            <result property="age" column="age"/>
            <result property="height" column="height"/>
            <collection property="scoreCourse" ofType="ScoreCourse">
                <id column="cid" property="cid"/>
                <result column="cnum" property="cnum"/>
                <association property="course" javaType="Course">
                    <id column="uid" property="uid"/>
                    <result column="uname" property="uname"/>
                </association>
            </collection>
        </association>
    </resultMap>
    <select id="selectAll" resultMap="map1">
        SELECT * FROM t_student ts JOIN t_detail td ON ts.sid = td.sid;
    </select>
    <select id="selectScoreBySid" resultMap="map2">
        SELECT * FROM t_student ts JOIN t_score tc ON ts.sid = tc.sid WHERE ts.sid = #{sid};
    </select>
    <select id="selectScoreCourseByuid" resultMap="map3">
        SELECT * FROM t_score tc JOIN t_course tu ON tc.uid = tu.uid;
    </select>
    <select id="selectStudentScoreCourseBysid" resultMap="map4">
        SELECT * FROM t_student ts JOIN t_score tc ON ts.sid = tc.sid
        JOIN t_course tu ON tc.uid = tu.uid;
    </select>
    <select id="selectStudentDetailScoreCourseBySid" resultMap="map5">
        SELECT * FROM t_student ts JOIN t_detail td ON #{sid} = td.sid
        JOIN t_score tc ON #{sid} = tc.sid
        JOIN t_course tu ON tc.uid = tu.uid;
    </select>
</mapper>
Maven依赖:
    <dependencies>
        <!-- mybatis依赖 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.11</version>
        </dependency>
        <!-- MySQL驱动 mybatis底层依赖jdbc驱动实现,本次不需要导入连接池,mybatis自带! -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.25</version>
        </dependency>
        <!--junit5测试-->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.36</version>
        </dependency>
    </dependencies>
