插件Lombok
1. 在idea里面安装
2.在项目中.xml里导入Lombok的jar包
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
3.在你要偷懒的实体类上加注解即可
@Getter and @Setter
@FieldNameConstants
@ToString
@EqualsAndHashCode
@AllArgsConstructor, @RequiredArgsConstructor and @NoArgsConstructor
@Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger, @CustomLog
@Data
@Builder
@SuperBuilder
@Singular
@Delegate
@Value
@Accessors
@Wither
@With
@SneakyThrows
@val
@var
experimental @var
@UtilityClass
Lombok config system
Code inspections
Refactoring actions (lombok and delombok)
实例:
基本够用:
@Date:无参构造、get、set、tostring、hashcode、equals
@AllArgsConstructor
@NoArgsConstructor
sql查询一对多:
- 对个学生,对应一个老师
- 对于学生这边而言,就是一个多对一的现象,即从学生这边关联一个老师!
- 对于老师而言,集合,一个老师,有很多学生【一对多】
CREATE TABLE `teacher` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO teacher(`id`, `name`) VALUES (1, '秦老师');
INSERT INTO teacher(`id`, `name`) VALUES (2, '陈老师');
CREATE TABLE `student` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fktid` (`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('6', '大明', '2');
小技巧:对应的接口有多个时可以这么写
放心:只要你对应的包一样,target里面它们会被打包在同一包下
测试环境搭建
- 导入lombok
- 新建实体类Teacher,Student
@Data
public class Teacher {
private int id;
private String name;
}
@Data
//少一个有参构造
public class Student {
private int id;
private String name;
//学生需要关联一个老师
private Teacher t;
}
- 建立Mapper接口
- 建立Mapper.xml文件
按照查询嵌套处理
<!--
思路:
1.查询所有的学生信息
2.根据查询出来的学生的tid,寻找对应的老师
-->
<select id="getStudent" resultMap="StudentTeacher">
SELECT * FROM student
</select>
<resultMap id="StudentTeacher" type="Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!--复杂的属性我们需要单独处理 对象:association 集合:collection-->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from teacher where id=#{id}
</select>
按照结果嵌套处理 (推荐)
<select id="getStudent2" resultMap="StudentTeacher2">
SELECT s.id sid,s.name sname,t.name tname
FROM student s,teacher t
WHERE s.tid=t.id;
</select>
<resultMap id="StudentTeacher2" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
- 在核心配置文件中绑定注册我们的Mapper接口或者文件【方式很多,随心选】
- 测试查询是否能够成功
回顾MySql多对一查询方式:
- 子查询(按照查询嵌套处理)
- 链表查询(按照结果嵌套处理)
多对一(其实…一样)
实例题目:
一对多的理解:
一个老师拥有多个学生
如果对于老师这边,就是一个一对多的现象,即从一个老师下面拥有一群学生(集合)
搭建环境
- 实体类编写
@Data
public class Student {
private int id;
private String name;
private int tid;
}
```java
@Data
public class Teacher {
private int id;
private String name;
//一个老师多个学生
private List<Student> students;
}
**
按结果嵌套处理
**
接口
//获取指定老师,及老师下的所有学生
public Teacher getTeacher(int id);
接口对应的Mapper配置文件
<mapper namespace="com.kuang.mapper.TeacherMapper">
<!--
思路:
1. 从学生表和老师表中查出学生id,学生姓名,老师姓名
2. 对查询出来的操作做结果集映射
1. 集合的话,使用collection!
JavaType和ofType都是用来指定对象类型的
JavaType是用来指定pojo中属性的类型
ofType指定的是映射到list集合属性中pojo的类型。
-->
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid, s.name sname , t.name tname, t.id tid
from student s,teacher t
where s.tid = t.id and t.id=#{id}
</select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="name" column="tname"/>
<collection property="students" ofType="Student">
<result property="id" column="sid" />
<result property="name" column="sname" />
<result property="tid" column="tid" />
</collection>
</resultMap>
</mapper>
将Mapper文件注册到MyBatis-config文件中
<mappers>
<mapper resource="mapper/TeacherMapper.xml"/>
</mappers>
测试
@Test
public void testGetTeacher(){
SqlSession session = MybatisUtils.getSession();
TeacherMapper mapper =session.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher(1);
System.out.println(teacher.getName());
System.out.println(teacher.getStudents());
}
结果:
/**查到了我们要的的三个属性 老师id name 和他对应的学生
* Teacher(id=1, name=秦老师, students=[
* Student(id=1, name=null, tid=1),
* Student(id=2, name=null, tid=1),
* Student(id=3, name=null, tid=1),
* Student(id=4, name=null, tid=1),
* Student(id=5, name=null, tid=1)])
*/
按查询嵌套处理
TeacherMapper接口编写方法
public Teacher getTeacher2(int id);
编写接口对应的Mapper配置文件
<select id="getTeacher2" resultMap="TeacherStudent2">
select * from teacher where id = #{id}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<!--column是一对多的外键 , 写的是一的主键的列名-->
<collection property="students" javaType="ArrayList"ofType="Student" column="id" select="getStudentByTeacherId"/>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
select * from student where tid = #{id}
</select>
将Mapper文件注册到MyBatis-config文件中
<mappers>
<mapper resource="mapper/TeacherMapper.xml"/>
</mappers>
测试:
@Test
public void testGetTeacher2(){
SqlSession session = MybatisUtils.getSession();
TeacherMapper mapper =session.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher2(1);
System.out.println(teacher.getName());
System.out.println(teacher.getStudents());
}
小结
1、关联-association【多对一】
2、集合-collection【一对多】
3、所以association是用于一对一和多对一,而collection是用于一对多的关系
4、JavaType和ofType都是用来指定对象类型的
- JavaType是用来指定实体类中属性的类型
- ofType指定的是映射到List或者集合属性中pojo的类型,泛型中的约束类型。
注意说明:
1、保证SQL的可读性,尽量通俗易懂
2、根据实际要求,尽量编写性能更高的SQL语句
3、注意属性名和字段不一致的问题
4、注意一对多和多对一 中:字段和属性对应的问题
5、尽量使用Log4j,通过日志来查看自己的错误
一对多和多对一对于很多人来说是难点,一定要大量的做练习理解!
面试高频:
- MySql引擎
- InnoDB底层原理
- 索引
- 索引优化