MyBatis自定义映射关系和关联查询实现方法详解
作者:会洗碗的CV工程师 发布时间:2021-12-18 21:25:28
一、使用注解实现自定义映射关系
当POJO属性名与数据库列名不一致时,需要自定义实体类和结果集的映射关系,在MyBatis注解开发中,使用 @Results 定义并使用自定义映射,使用 @ResultMap 使用自定义映射,用法如下:
前戏:为了体验这个效果,我们可以修改一下User实体类代码,如下
package com.example.pojo;
import java.io.Serializable;
public class User implements Serializable {
private int id;
private String username1;
private String sex1;
private String address1;
public User(String programmer, String man, String shangHai) {
this.username1 = programmer;
this.sex1 = man;
this.address1 = shangHai;
}
public User(int i, String programmer_1, String woman, String shenzhen) {
this.id = i;
this.username1 = programmer_1;
this.sex1 = woman;
this.address1 = shenzhen;
}
public User() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername1() {
return username1;
}
public void setUsername1(String username1) {
this.username1 = username1;
}
public String getSex1() {
return sex1;
}
public void setSex1(String sex1) {
this.sex1 = sex1;
}
public String getAddress1() {
return address1;
}
public void setAddress1(String address1) {
this.address1 = address1;
}
@Override
public String toString() {
return "User[ " +
"id=" + id +
", username1='" + username1 + '\'' +
", sex1='" + sex1 + '\'' +
", address1='" + address1 + '\'' +
" ]";
}
}
1. 编写注解方法
// 查询所有用户
@Results(id="userDiyMapper",value = {
@Result(id = true,property = "id",column = "id"),
@Result(property = "username1",column = "username"),
@Result(property = "sex1",column = "sex"),
@Result(property = "address1",column = "address")
})
@Select("select * from user")
List<User> findAll1();
// 根据id查询
@ResultMap("userDiyMapper")
@Select("select * from user where id = #{id}")
User findById(int id);
注意啊:这里property对应的是实体类属性名,column对应的就是数据库表的列名
2. 编写测试方法
@Test
public void testFindAll1(){
List<User> all = userMapper.findAll1();
all.forEach(System.out::println);
System.out.println("---------------------");
System.out.println(userMapper.findById(5));
}
看看能否查询出所有用户和id为5的用户,并且留意对应的属性名
3. 查看运行结果
OK,看来都是符合我们的预期的。
二、使用注解实现一对一关联查询
在MyBatis的注解开发中对于多表查询只支持分解查询,不支持连接查询。
这里我们采用学生表和班级表做对比,所以我们先新建Student实体类和Classes实体类
Classes实体类
package com.example.pojo;
import java.util.List;
public class Classes {
private int cid;
private String className;
private List<Student> studentList;
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public List<Student> getStudentList() {
return studentList;
}
public void setStudentList(List<Student> studentList) {
this.studentList = studentList;
}
@Override
public String toString() {
return "Classes[ " +
"cid=" + cid +
", className='" + className + '\'' +
", studentList=" + studentList +
" ]";
}
}
Student实体类
package com.example.pojo;
public class Student {
private int sid;
private String name;
private int age;
private String sex;
private Classes classes;
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Classes getClasses() {
return classes;
}
public void setClasses(Classes classes) {
this.classes = classes;
}
@Override
public String toString() {
return "Student[ " +
"sid=" + sid +
", name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", classes=" + classes +
" ]";
}
}
1. 编写注解方法
StudentMapper添加查询所有用户
package com.example.mapper;
import com.example.pojo.Student;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
public interface StudentMapper {
@Select("select * from student")
// 自定义映射关系
@Results(id = "studentMapper",value = {
@Result(id = true,property = "sid",column = "sid"),
@Result(property = "name",column = "name"),
@Result(property = "age",column = "age"),
@Result(property = "sex",column = "sex"),
/**
* property:属性名
* column:调用从表方法时传入的参数列
* one:表示该属性是一个对象
* select:调用的是从表方法
* fetchType:加载方式
*/
@Result(property = "classes",column = "classId",
one = @One(select = "com.example.mapper.ClassesMapper.findByCid",
fetchType = FetchType.EAGER)
)
})
List<Student> findAll();
}
ClassesMapper添加根据id查询班级
package com.example.mapper;
import com.example.pojo.Classes;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
public interface ClassesMapper {
// 根据id查询班级
@Select("select * from classes where cid = #{cid}")
Classes findByCid(Integer id);
}
2. 编写测试方法
// 测试一对一查询
@Test
public void testFindAllStudent(){
StudentMapper studentMapper = session.getMapper(StudentMapper.class);
List<Student> all = studentMapper.findAll();
all.forEach(System.out::println);
}
看看能否查询出学生对应的班级,如果可以则查询成功
3. 查看运行结果
OK,看图我们是已经成功查询出每个学生对应的班级的
三、使用注解实现一对多关联查询
在这里我们主要实现查询所有班级的时候把对应的学生列表也查询出来。
1. 编写注解方法
StudentMapper添加根据班级id查询学生
// 根据班级Id查询学生
@Select("select * from student where ClassId = #{classId}")
List<Student> findByClassId(int classId);
Classes添加查询所有班级
// 查询所有班级
@Select("select * from classes")
@Results(id = "classMapper",value = {
@Result(id = true,property = "cid",column = "cid"),
@Result(property = "className",column = "className"),
// many:表示该属性是一个集合
@Result(property = "studentList",column = "cid",
many = @Many(select = "com.example.mapper.StudentMapper.findByClassId",
fetchType = FetchType.LAZY))
})
List<Classes> findAll();
2. 编写测试方法
// 测试一对多查询
@Test
public void findAllClasses(){
ClassesMapper classesMapper = session.getMapper(ClassesMapper.class);
List<Classes> all = classesMapper.findAll();
all.forEach(System.out::println);
}
观察能否查询出班级对应的学生列表
3. 查看运行结果
OK,确实也是可以查询出来了的。
四、注解文件和映射文件开发对比
注解开发更快,映射文件更方便。
MyBatis中更推荐使用映射文件开发,Spring、SpringBoot更推荐注解方式。具体使用要视项目情况而定。它们的优点对比如下:
映射文件:
代码与Sql语句是解耦的,修改时只需修改配置文件,无需修改源码。
Sql语句集中,利于快速了解和维护项目。
级联查询支持连接查询和分解查询两种方式,注解开发只支持分解查询。
注解:
配置简单,开发效率高。
类型安全,在编译期即可进行校验,不用等到运行时才发现错误。
我个人也是比较喜欢映射文件开发,主要更喜欢方便维护和了解。
来源:https://blog.csdn.net/qq_53317005/article/details/129649043


猜你喜欢
- SimpleDateFormat进行日期格式化1.为啥要用SimpleDateFormat众所周知,Java中的日期类是Date,然后日期默
- 1.OkHttp发起网络请求可以通过OkHttpClient发起一个网络请求//创建一个Client,相当于打开一个浏览器 OkHttpCl
- 引言前一段有幸参与到一个智能家居项目的开发,由于之前都没有过这方面的开发经验,所以对智能硬件的开发模式和技术栈都颇为好奇。智能可燃气体报警器
- PostMapping接收json参数后返回404问题描述js中传递json数据给后端,后端可以正常接收参数,但返回404。js
- 1.场景线程池使用DiscardOldestPolicy拒绝策略,阻塞队列使用ArrayBlockingQueue,发现在某些情形下对于得到
- 一、场景Java实现文件上传到服务器本地,并通过url访问有个需求,前端上传文件,需要用开关的方式同时支持上传七牛和服务器本地,方便不同的用
- static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概
- 一、String与Date(java.util.Date)互转 1.1 String -&g
- 在APP项目的开发过程中,经常会用到分享图片的功能,有时候还需要根据当前用户信息获取指定的分享图片,比如要求在用户分享图中显示用户名、Uid
- Webview打开本地图片选择器十分之麻烦,其在安卓系统3x 4x 5x上的行为都不同,处理也不同,所以之前差点崩溃。经过测试和完善,最终其
- 觉得作者写得太好了,不得不收藏一下。对这个例子的理解://类型参数不能用基本类型,T和U其实是同一类型。//每次放新数据都成为新的top,把
- 死锁问题死锁定义多线程编程中,因为抢占资源造成了线程无限等待的情况,此情况称为死锁。死锁举例注意:线程和锁的关系是:一个线程可以拥有多把锁,
- 支付宝今年推出了新的转账接口alipay.fund.trans.uni.transfer(升级后安全性更高,功能更加强大) ,老转账接口al
- 有段时间没有看视频了,昨天晚上抽了点空时间,又看了下鸿洋大神的视频教程,又抽时间写了个学习记录。代码和老师讲的基本一样,网上也有很多相同的博
- Object是所有类的父类,也就是说java中所有的类都是直接或者间接继承自Object类。比如你随便创建一个classA,虽然没有明说,但
- 前言:Android开发中,自定义View实现自己想要的效果已成为一项必备的技能,当然自定义View也是Android开发中比较难的部分,涉
- Kotlin 封装万能SharedPreferences存取任何类型详解/** * author: smart * time: 2016/1
- 这篇文章说明了如何通过Maven配置Spring依赖项。最新的Spring版本可以在Maven Central上找到。Maven中的Spri
- 一、脚本生命周期Unity脚本中的常见必然事件如下表所示名称触发时机用途Awake脚本实例被创建时调用用于游戏对象的初始化,注意Awake的
- 在网上虽然看到了方法,但是处理感觉很复杂,我的办法,老实说,是突然试一下试到的,哈哈QWQOK,开始说明如何整的。效果如上图所示代码如下pa