本篇内容介绍了“MyBatis怎么实现自定义映射关系和关联查询”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
当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 + '\'' + " ]"; } }
// 查询所有用户 @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对应的就是数据库表的列名
@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的用户,并且留意对应的属性名
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 + " ]"; } }
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); }
// 测试一对一查询 @Test public void testFindAllStudent(){ StudentMapper studentMapper = session.getMapper(StudentMapper.class); List<Student> all = studentMapper.findAll(); all.forEach(System.out::println); }
看看能否查询出学生对应的班级,如果可以则查询成功
OK,看图我们是已经成功查询出每个学生对应的班级的
在这里我们主要实现查询所有班级的时候把对应的学生列表也查询出来。
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();
// 测试一对多查询 @Test public void findAllClasses(){ ClassesMapper classesMapper = session.getMapper(ClassesMapper.class); List<Classes> all = classesMapper.findAll(); all.forEach(System.out::println); }
观察能否查询出班级对应的学生列表
OK,确实也是可以查询出来了的。
注解开发更快,映射文件更方便。
MyBatis中更推荐使用映射文件开发,Spring、SpringBoot更推荐注解方式。具体使用要视项目情况而定。它们的优点对比如下:
映射文件:
代码与Sql语句是解耦的,修改时只需修改配置文件,无需修改源码。
Sql语句集中,利于快速了解和维护项目。
级联查询支持连接查询和分解查询两种方式,注解开发只支持分解查询。
注解:
配置简单,开发效率高。
类型安全,在编译期即可进行校验,不用等到运行时才发现错误。
我个人也是比较喜欢映射文件开发,主要更喜欢方便维护和了解。
“MyBatis怎么实现自定义映射关系和关联查询”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。