7.Mybatis的一对多,多对一处理

一.代码简化工具Lombok(只要了解,一般不用)

  • Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率。例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器、equals等方法,而且需要维护,当属性多时会出现大量的getter/setter方法,这些显得很冗长也没有太多技术含量,一旦修改属性,就容易出现忘记修改对应方法的失误。

  • Lombok能通过注解的方式,在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString方法。出现的神奇就是在源码中没有getter和setter方法,但是在编译生成的字节码文件中有getter和setter方法。这样就省去了手动重建这些代码的麻烦,使代码看起来更简洁些。

1.使用步骤:

(1)在IDEA中安装Lombok插件

(2)在项目中导入lombok的jar包

1 <dependencies>
2     <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
3     <dependency>
4         <groupId>org.projectlombok</groupId>
5         <artifactId>lombok</artifactId>
6         <version>1.18.10</version>
7     </dependency>
8 </dependencies>

(3)Lombok有哪些简化配置

 1 @Getter and @Setter
 2 @FieldNameConstants
 3 @ToString
 4 @EqualsAndHashCode
 5 @AllArgsConstructor, @RequiredArgsConstructor and @NoArgsConstructor
 6 @Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger, @CustomLog
 7 @Data
 8 @Builder
 9 @SuperBuilder
10 @Singular
11 @Delegate
12 @Value
13 @Accessors
14 @Wither
15 @With
16 @SneakyThrows
17 @val
18 @var
19 experimental @var
20 @UtilityClass
21 Lombok config system
22 Code inspections
23 Refactoring actions (lombok and delombok)

(4)使用在实体类上加注解即可

只需要知道:

  • @Data :添加了无参构造,getter,setter,hashcode,toString, equals等方法
  • @AllArgsConstructor :有参构造
  • @Getter and @Setter
  • @ToString
  • @EqualsAndHashCode
 1 import lombok.Data;
 2
 3 //实体类
 4 @Data
 5 public class User {
 6     private int id;  //id
 7     private String name;   //姓名
 8     private String password;   //密码
 9
10
11 }

(5)lombok优缺点

  • 优点:

    1. 能通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法,提高了一定的开发效率

    2. 让代码变得简洁,不用过多的去关注相应的方法

    3. 属性做修改时,也简化了维护为这些属性所生成的getter/setter方法等

  • 缺点:

    1. 不支持多种参数构造器的重载

    2. 虽然省去了手动创建getter/setter方法的麻烦,但大大降低了源代码的可读性和完整性,降低了阅读源代码的舒适度

(6)建议不要去使用lombok只要了解即可

二.多对一处理

  • 多个学生对应一个老师

  • 如果对于学生这边,就是一个多对一的现象,即从学生这边关联一个老师!

1.复杂查询环境搭建

(1)新建teacher和student表:

 1 CREATE TABLE `teacher` (
 2   `id` INT(10) NOT NULL,
 3   `name` VARCHAR(30) DEFAULT NULL,
 4   PRIMARY KEY (`id`)
 5 ) ENGINE=INNODB DEFAULT CHARSET=utf8;
 6
 7 INSERT INTO teacher(`id`, `name`) VALUES (1, ‘秦老师‘);
 8
 9 CREATE TABLE `student` (
10   `id` INT(10) NOT NULL,
11   `name` VARCHAR(30) DEFAULT NULL,
12   `tid` INT(10) DEFAULT NULL,
13   PRIMARY KEY (`id`),
14   KEY `fktid` (`tid`),
15   CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
16 ) ENGINE=INNODB DEFAULT CHARSET=utf8;
17
18
19 INSERT INTO `student` (`id`, `name`, `tid`) VALUES (‘1‘, ‘小明‘, ‘1‘);
20 INSERT INTO `student` (`id`, `name`, `tid`) VALUES (‘2‘, ‘小红‘, ‘1‘);
21 INSERT INTO `student` (`id`, `name`, `tid`) VALUES (‘3‘, ‘小张‘, ‘1‘);
22 INSERT INTO `student` (`id`, `name`, `tid`) VALUES (‘4‘, ‘小李‘, ‘1‘);
23 INSERT INTO `student` (`id`, `name`, `tid`) VALUES (‘5‘, ‘小王‘, ‘1‘); 

(2)新建子项目mybatis-05

  1. 导入Lombok

  2. 创建Teacher和Student两个实体类

  3. 建立Mapper接口

  4. 建立Mapper.xml文件

  5. 在核心配置文件中绑定注册我们的Mapper接口或Mapper.xml文件!

  6. 测试执行是否成功!

Student.java:

 1 import lombok.Data;
 2
 3 @Data
 4 public class Student {
 5
 6     private int id;
 7     private String name;
 8
 9     //学生需要关联一个老师
10     private Teacher teacher;
11 }

Teacher.java:

1 import lombok.Data;
2
3 @Data
4 public class Teacher {
5
6     private int id;
7     private String name;
8 }

2.查询所有学生信息以及对应的老师信息

(1)SQL语句:

1 select s.id as ‘学生id‘,s.name as ‘学生姓名‘,t.id as ‘老师id‘,t.name as ‘老师姓名‘ from student s ,teacher t where s.tid = t.id;

(2)mybatis中的SQL语句:

  • 子查询

  • 联表查询(推荐)

(2.1)子查询方式

StudentMapper.java接口:

1 List<Student> getStudent();

StudentMapper.xml:

 1 <!--需要查询所有学生信息以及对应的老师信息-->
 2 <resultMap id="StudentTeacher" type="Student">
 3     <result property="id" column="id"></result>
 4     <result property="name" column="name"></result>
 5
 6     <!--复杂的属性,我们需要单独处理, 对象使用association,集合使用collection-->
 7     <!--property属性名 javaType属性类型 column表中的列名-->
 8     <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"></association>
 9 </resultMap>
10
11 <select id="getStudent" resultMap="StudentTeacher">
12     select * from mybatis.student;
13 </select>
14
15 <select id="getTeacher" parameterType="_int" resultType="Teacher">
16     select * from mybatis.teacher where id=#{teacherId};
17 </select>

测试代码:

 1 @Test
 2 public void getStudentTest() {
 3     SqlSession session = MybatisUtils.getSession();
 4
 5     StudentMapper mapper = session.getMapper(StudentMapper.class);
 6
 7     List<Student> studentList = mapper.getStudent();
 8
 9     for (Student student : studentList) {
10         System.out.println(student);
11     }
12
13     session.close();
14 }

(2.2)联表查询方式:(推荐使用,简单易懂)

StudentMapper.java接口:

1 List<Student> getStudent2();

StudentMapper.xml:

 1 <!--方式二:连表查询-->
 2 <select id="getStudent2" resultMap="StudentTeacher2">
 3     select s.id as sid,s.name as sname,t.id as tid,t.name as tname
 4     from student s ,teacher t
 5     where s.tid = t.id;
 6 </select>
 7
 8 <resultMap id="StudentTeacher2" type="Student">
 9     <result property="id" column="sid"></result>
10     <result property="name" column="sname"></result>
11     <association property="teacher" javaType="Teacher">
12         <result property="id" column="tid"></result>
13         <result property="name" column="tname"></result>
14     </association>
15 </resultMap>

测试代码:

 1 @Test
 2 public void getStudent2Test() {
 3     SqlSession session = MybatisUtils.getSession();
 4
 5     StudentMapper mapper = session.getMapper(StudentMapper.class);
 6
 7     List<Student> studentList = mapper.getStudent2();
 8
 9     for (Student student : studentList) {
10         System.out.println(student);
11     }
12
13     session.close();
14 }

三.一对多处理

一个老师对多个学生

1.复杂查询环境搭建

(1)新建子项目mybatis-06

  1. 导入Lombok

  2. 创建Teacher和Student两个实体类

  3. 建立Mapper接口

  4. 建立Mapper.xml文件

  5. 在核心配置文件中绑定注册我们的Mapper接口或Mapper.xml文件!

  6. 测试执行是否成功!

Student.java:

1 import lombok.Data;
2
3 @Data
4 public class Student {
5
6     private int id;
7     private String name;
8     private int tid;
9 }

Teacher.java:

 1 import lombok.Data;
 2
 3 import java.util.List;
 4
 5 @Data
 6 public class Teacher {
 7
 8     private int id;
 9     private String name;
10
11     //一个老师拥有多个学生
12     private List<Student> students;
13 }

SQL语句:

1 select t.id as tid, t.name as tname,s.id as sid, s.name as sname
2 from student s,teacher t
3 where s.tid = t.id;

2.根据ID查询老师信息以及老师对应的学生信息

(1)子查询:

TeacherMapper.java接口:

1 Teacher getTeacher2(@Param("tid") int id);

TeacherMapper.xml:

  • 由于分开来写所以 javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"

    • javaType用于绑定是一个List
    • ofType用于绑定List中的类型
    • select 用于拿到子查询数据为一个List<Student>
    • column中的值为Teacher的id对应子查询为Student的tid
 1 <select id="getTeacher2" resultMap="TeacherStudent2">
 2     select id , name from mybatis.teacher where id = #{tid}
 3 </select>
 4
 5 <resultMap id="TeacherStudent2" type="Teacher">
 6     <result property="id" column="id"></result>
 7     <result property="name" column="name"></result>
 8     <collection property="students" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"></collection>
 9 </resultMap>
10
11 <select id="getStudentByTeacherId" resultType="Student">
12     select * from mybatis.student where tid = #{tid};
13 </select>

测试代码:

 1 @Test
 2 public void getTeacherTest2() {
 3     SqlSession session = MybatisUtils.getSession();
 4
 5     TeacherMapper mapper = session.getMapper(TeacherMapper.class);
 6
 7     Teacher teacher = mapper.getTeacher2(1);
 8
 9     System.out.println(teacher);
10
11     session.close();
12 }

可以看出只有一条数据,select 用于拿到子查询数据为一个List<Student> :

(2)联表查询:(推荐使用,简单易懂)

TeacherMapper.java接口:

1 //根据老师id获得老师信息并获得对应的多个学生信息
2 Teacher getTeacher(@Param("tid") int id);

TeacherMapper.xml:

每次只获得一条数据所以 property="students" ofType="Student" ,每次拼接一条数据最后一次性返回

 1 <!--联表查询方式-->
 2     <select id="getTeacher" resultMap="TeacherStudent">
 3         select t.id as tid, t.name as tname,s.id as sid, s.name as sname
 4         from student s,teacher t
 5         where s.tid = t.id and t.id = #{tid};
 6     </select>
 7
 8     <resultMap id="TeacherStudent" type="Teacher">
 9         <result property="id" column="tid"></result>
10         <result property="name" column="tname"></result>
11         <!--集合的话,使用collection!
12                 JavaType和ofType都是用来指定对象类型的
13                 JavaType是用来指定pojo中属性的类型
14                 ofType指定的是映射到list集合属性中pojo的类型。-->
15         <collection property="students" ofType="Student">
16             <result property="id" column="sid"></result>
17             <result property="name" column="sname"></result>
18             <result property="tid" column="tid"></result>
19         </collection>
20     </resultMap>

测试代码:

 1 @Test
 2 public void getTeacherTest() {
 3     SqlSession session = MybatisUtils.getSession();
 4
 5     TeacherMapper mapper = session.getMapper(TeacherMapper.class);
 6
 7     Teacher teacher = mapper.getTeacher(1);
 8
 9     System.out.println(teacher);
10
11     session.close();
12 }

可以看出拿到了五条数据

四.小结

  1. 关联-association 【一对一和多对一】

  2. 集合-collection【一对多】

  3. JavaType和ofType都是用来指定对象类型的

    • JavaType是用来指定pojo中属性的类型

    • ofType指定的是映射到list集合属性中pojo的类型。

注意说明:

  1. 保证SQL的可读性,尽量通俗易懂

  2. 根据实际要求,尽量编写性能更高的SQL语句

  3. 注意属性名和字段不一致的问题

  4. 注意一对多和多对一 中:字段和属性对应的问题

  5. 尽量使用Log4j,通过日志来查看自己的错误

原文地址:https://www.cnblogs.com/zhihaospace/p/12301067.html

时间: 2024-08-29 17:54:20

7.Mybatis的一对多,多对一处理的相关文章

mybatis 一对一 一对多 多对多

一对一 一对多 多对多 原文地址:https://www.cnblogs.com/cwone/p/11909271.html

mybatis的一对多,多对一,以及多对对的配置和使用

1.本文章是无意中看见易百教程的Mybatis教程才注意到这个问题,平时都仅仅是在用CRUD,忽略了这方面的问题,真实十分羞愧 2.首先我们开始对mybatis的一对多的探究 根据这个应用场景,我们需要获取在查询一个用户信息的时候还要去读取这个用户发布的帖子 现在我们来看一看用户级联文章在JavaBean中的编写方式,这就是一对多在JavaBean中的配置 现在我们再来看一看Mybatis的Mapper该如何编写一对多?很简单,就是在resultMap标签中配置<collection>标签,用

mybatis学习笔记(11)-多对多查询

mybatis学习笔记(11)-多对多查询 mybatis学习笔记11-多对多查询 示例 多对多查询总结 resultMap总结 本文实现多对多查询,查询用户及用户购买商品信息. 示例 查询主表是:用户表 关联表:由于用户和商品没有直接关联,通过订单和订单明细进行关联,所以关联表:orders.orderdetail.items sql SELECT orders.*, user.username, user.sex, user.address, orderdetail.id orderdeta

hibernate 一对多|多对一

一对多:(一个客户对应多个联系人) 客户实体:Customer.java package cn.future.domain; import java.util.HashSet; import java.util.Set; public class Customer { /* * CREATE TABLE `cst_customer` ( `cust_id` BIGINT(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)', `cust_name` VAR

框架 day32 Hibernate,一级缓存,关联关系映射(一对多,多对多)

一级缓存 概念 *在 Session 接口的实现中包含一系列的 Java 集合, 这些 Java集合构成了Session缓存. 只要 Session 实例没有结束生命周期, 存放在它缓存中的对象也不会结束生命周期 *当session的save()方法持久化一个对象时,该对象被载入缓存, 以后即使程序中不再引用该对象,只要缓存不清空,该对象仍然处于生命周期中. 当试图get(). load()对象时,会判断缓存中是否存在该对象,有则返回,此时不查询数据库.没有再查询数据库 *Session 能够在

DjangoORM一对多&多对多操作

简要说明 通过操作对象的方式操作数据库 详细步骤 models.py的结构是: 如果models.py中外键定义没有写 related_name='student_teacher', 可以直接用 studentList = teacher.student_teacher.all() 可以改写成: teacher = Teacher.objects.get(id = 1) studentList = teacher.student_set.all() =======================

PD 15.1 安装 破解 , 简单使用 (一对多,多对多关系生成sql脚本)

  1:运行  PowerDesigner15_Evaluation.exe 默认   2: 安装完毕后,不要执行,下面我们进行 破解 把 PowerDesigner15汉化+注册补丁  下的所有文件,覆盖 PD的安装目录下的文件 然后我们打开 PD,点击 帮助 –> About  看到下面窗口中红色方框,就表示已经破解 + 汉化成功 PD 15.1 安装 破解 , 简单使用 (一对多,多对多关系生成sql脚本)

Hibernate 集合映射 一对多多对一 inverse属性 + cascade级联属性 多对多 一对一 关系映射

1 . 集合映射 需求:购物商城,用户有多个地址. // javabean设计 // javabean设计 public class User { private int userId; private String userName; // 一个用户,对应的多个地址 private Set<String> address; private List<String> addressList = new ArrayList<String>(); //private Str

mybatis的一对多

1.配置文件 db.properties db.driver=com.mysql.jdbc.Driver db.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8 db.username=root db.password=123456 SqlMapConfig.xml 1 <?xml version="1.0" encoding="UTF-8" ?

Mybatis 中一对多,多对一的配置

现在有很多电商平台,就拿这个来说吧.顾客跟订单的关系,一个顾客可以有多张订单,但是一个订单只能对应一个顾客. 一对多的顾客 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd&quo