当前位置:   article > 正文

MyBatis实行多表查询几种实现方式_mybatis连表查询

mybatis连表查询

目录

实现多表联查的四种实现方式

本文以以下表举例:

方式一:视图

方式二:存储过程

方式三:配置文件

一对一

一对多

方式四:注解

一对多

一对一

四种方式对比


实现多表联查的四种实现方式

方案一:通过在数据库服务器端创建多表的view,java的dao层读取这个view;

方案二:通过在数据库服务器端创建多表的存储过程,java的dao层调用这个存储过程;

方案三:通过mabatis的xml配置文件方式进行多表联查,在这里需要手动配置映射关系(一对一、一对多

方案四:通过mabatis的注解方式进行多表联查,在这里需要手动配置映射关系(一对一、一对多)

本文以以下表举例:

  

方式一:视图

        在数据库创建联表的视图,Java读取这个视图

1)数据库创建需要查询的视图

  1. CREATE VIEW student_score as
  2. select student.*, score.cname,score.sc
  3. from student
  4. LEFT JOIN score on student.Sid = score.sid

2)pojo层创建映射类

  1. public class View_StudentScore {
  2. private int sid;
  3. private String sname;
  4. private Date birthday;
  5. private String ssex;
  6. private int classid;
  7. private String cname;
  8. private double sc;
  9. public View_StudentScore() {
  10. super();
  11. }
  12. public View_StudentScore(int sid, String sname, Date birthday, String ssex, int classid, String cname, double sc) {
  13. super();
  14. this.sid = sid;
  15. this.sname = sname;
  16. this.birthday = birthday;
  17. this.ssex = ssex;
  18. this.classid = classid;
  19. this.cname = cname;
  20. this.sc = sc;
  21. }
  22. public int getSid() {
  23. return sid;
  24. }
  25. public void setSid(int sid) {
  26. this.sid = sid;
  27. }
  28. public String getSname() {
  29. return sname;
  30. }
  31. public void setSname(String sname) {
  32. this.sname = sname;
  33. }
  34. public Date getBirthday() {
  35. return birthday;
  36. }
  37. public void setBirthday(Date birthday) {
  38. this.birthday = birthday;
  39. }
  40. public String getSsex() {
  41. return ssex;
  42. }
  43. public void setSsex(String ssex) {
  44. this.ssex = ssex;
  45. }
  46. public int getClassid() {
  47. return classid;
  48. }
  49. public void setClassid(int classid) {
  50. this.classid = classid;
  51. }
  52. public String getCname() {
  53. return cname;
  54. }
  55. public void setCname(String cname) {
  56. this.cname = cname;
  57. }
  58. public double getSc() {
  59. return sc;
  60. }
  61. public void setSc(double sc) {
  62. this.sc = sc;
  63. }
  64. @Override
  65. public String toString() {
  66. return "View_StudentScore [sid=" + sid + ", sname=" + sname + ", birthday=" + birthday + ", ssex=" + ssex
  67. + ", classid=" + classid + ", cname=" + cname + ", sc=" + sc + "]";
  68. }
  69. }

3)mapper层

  1. public interface View_StudentScoreMapper {
  2. @Select("select * from View_StudentScore")
  3. public List<View_StudentScore> fundAll();
  4. }

4)测试类

  1. public class Test01 {
  2. public static void main(String[] args) {
  3. SqlSession sqlSession = DaoUtil.getSqlSession();
  4. View_StudentScoreMapper mapper = sqlSession.getMapper(View_StudentScoreMapper.class);
  5. List<View_StudentScore> viewList = mapper.fundAll();
  6. for (View_StudentScore view_StudentScore : viewList) {
  7. System.out.println(view_StudentScore);
  8. }
  9. }
  10. }

5)结果

方式二:存储过程

       在数据库创建联表的存储过程,Java读取这个存储过程

1)在数据库创建存储过程

  1. DELIMITER $$
  2. CREATE
  3. /*[DEFINER = { user | CURRENT_USER }]*/
  4. PROCEDURE `pgm`.`student_score`()
  5. /*LANGUAGE SQL
  6. | [NOT] DETERMINISTIC
  7. | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  8. | SQL SECURITY { DEFINER | INVOKER }
  9. | COMMENT 'string'*/
  10. BEGIN
  11. SELECT student.*, score.cname,score.sc
  12. FROM student
  13. LEFT JOIN score ON student.Sid = score.sid ;
  14. END$$
  15. DELIMITER ;

2)创建pojo解析对象View_StudentScore(与上面相同,不再过多介绍)

3)mapper

  1. public interface StoredProcedureMapper {
  2. public List<View_StudentScore> fundAllByStoredProcedure();
  3. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.ape.mapper.StoredProcedureMapper">
  6. <select id="fundAllByStoredProcedure" resultType="com.ape.pojo.View_StudentScore">
  7. call student_score();
  8. </select>
  9. </mapper>

4)测试类

  1. public class Test01 {
  2. public static void main(String[] args) {
  3. SqlSession sqlSession = DaoUtil.getSqlSession();
  4. StoredProcedureMapper mapper = sqlSession.getMapper(StoredProcedureMapper.class);
  5. List<View_StudentScore> viewList = mapper.fundAllByStoredProcedure();
  6. for (View_StudentScore view_StudentScore : viewList) {
  7. System.out.println(view_StudentScore);
  8. }
  9. }
  10. }

5)运行结果

方式三:配置文件

        在Java端mybatis框架里写联查sql语句,通过orm模型解析,这里需要考虑一对一以及一对多的关系,按本文的student和score表举例,student对于score是一对多的关系,score对于student来说是一对一的关系;

1)pojo

  1. //成绩类
  2. package com.ape.pojo;
  3. public class Score {
  4. private int sid;
  5. private String cname;
  6. private double sc;
  7. private Student student; //一对一
  8. public Score() {
  9. super();
  10. }
  11. public Score(int sid, String cname, double sc, Student student) {
  12. super();
  13. this.sid = sid;
  14. this.cname = cname;
  15. this.sc = sc;
  16. this.student = student;
  17. }
  18. public int getSid() {
  19. return sid;
  20. }
  21. public void setSid(int sid) {
  22. this.sid = sid;
  23. }
  24. public String getCname() {
  25. return cname;
  26. }
  27. public void setCname(String cname) {
  28. this.cname = cname;
  29. }
  30. public double getSc() {
  31. return sc;
  32. }
  33. public void setSc(double sc) {
  34. this.sc = sc;
  35. }
  36. public Student getStudent() {
  37. return student;
  38. }
  39. public void setStudent(Student student) {
  40. this.student = student;
  41. }
  42. @Override
  43. public String toString() {
  44. return "Score [sid=" + sid + ", cname=" + cname + ", sc=" + sc + ", student=" + student + "]";
  45. }
  46. }
  47. //学生类
  48. package com.ape.pojo;
  49. public class Student {
  50. private int sid;
  51. private String sname;
  52. private Date birthday;
  53. private String ssex;
  54. private int classid;
  55. private List<Score> scList;//一对多
  56. public Student() {
  57. super();
  58. }
  59. public Student(int sid, String sname, Date birthday, String ssex, int classid, List<Score> scList) {
  60. super();
  61. this.sid = sid;
  62. this.sname = sname;
  63. this.birthday = birthday;
  64. this.ssex = ssex;
  65. this.classid = classid;
  66. this.scList = scList;
  67. }
  68. @Override
  69. public String toString() {
  70. return "Student [sid=" + sid + ", sname=" + sname + ", birthday=" + birthday + ", ssex=" + ssex + ", classid="
  71. + classid + ", scList=" + scList + "]";
  72. }
  73. public int getSid() {
  74. return sid;
  75. }
  76. public void setSid(int sid) {
  77. this.sid = sid;
  78. }
  79. public String getSname() {
  80. return sname;
  81. }
  82. public void setSname(String sname) {
  83. this.sname = sname;
  84. }
  85. public Date getBirthday() {
  86. return birthday;
  87. }
  88. public void setBirthday(Date birthday) {
  89. this.birthday = birthday;
  90. }
  91. public String getSsex() {
  92. return ssex;
  93. }
  94. public void setSsex(String ssex) {
  95. this.ssex = ssex;
  96. }
  97. public int getClassid() {
  98. return classid;
  99. }
  100. public void setClassid(int classid) {
  101. this.classid = classid;
  102. }
  103. public List<Score> getScList() {
  104. return scList;
  105. }
  106. public void setScList(List<Score> scList) {
  107. this.scList = scList;
  108. }
  109. }

一对一

score作为主表,student作为子表,存在一对一关系映射,使用association标签

2)mapper:

  1. package com.ape.mapper;
  2. import java.util.List;
  3. import com.ape.pojo.Score;
  4. public interface ScoreMapper {
  5. public List<Score> fundAllScore();
  6. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.ape.mapper.ScoreMapper">
  6. <resultMap type="com.ape.pojo.Score" id="score_student_map">
  7. <result property="sid" column="sid" />
  8. <result property="cname" column="cname" />
  9. <result property="sc" column="sc" />
  10. <association property="student"
  11. javaType="com.ape.pojo.Student">
  12. <id column="sid" property="sid" />
  13. <result property="sname" column="sname" />
  14. <result property="birthday" column="birthday" />
  15. <result property="ssex" column="Ssex" />
  16. <result property="classid" column="classid" />
  17. </association>
  18. </resultMap>
  19. <select id="fundAllScore" resultMap="score_student_map">
  20. select
  21. score.*,student.sname,student.birthday,student.Ssex,student.classid
  22. from score LEFT JOIN student on student.Sid = score.sid
  23. </select>
  24. </mapper>

3)测试类:

  1. package com.ape.test;
  2. import java.util.List;
  3. import org.apache.ibatis.session.SqlSession;
  4. import com.ape.dao.DaoUtil;
  5. import com.ape.mapper.ScoreMapper;
  6. import com.ape.pojo.Score;
  7. public class Test02 {
  8. public static void main(String[] args) {
  9. SqlSession sqlSession = DaoUtil.getSqlSession();
  10. ScoreMapper mapper = sqlSession.getMapper(ScoreMapper.class);
  11. List<Score> fundAllScore = mapper.fundAllScore();
  12. for (Score Score : fundAllScore) {
  13. System.out.println(Score);
  14. }
  15. }
  16. }

4)结果:

一对多

student作为主表,score作为子表,存在一对多关系映射,使用collection标签

2)mapper:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.ape.mapper.StudentMapper">
  6. <resultMap type="com.ape.pojo.Student" id="student_score_map">
  7. <result property="sid" column="sid" />
  8. <result property="sname" column="sname" />
  9. <result property="birthday" column="birthday" />
  10. <result property="ssex" column="ssex" />
  11. <result property="classid" column="classid" />
  12. <collection property="scList" ofType="com.ape.pojo.Score">
  13. <id property="sid" column="sid" />
  14. <result property="cname" column="cname" />
  15. <result property="sc" column="sc" />
  16. </collection>
  17. </resultMap>
  18. <select id="fundAllStudent" resultMap="student_score_map">
  19. select
  20. student.*,score.cname,score.sc from student
  21. LEFT JOIN score on
  22. student.Sid = score.sid;
  23. </select>
  24. </mapper>
  1. package com.ape.mapper;
  2. import java.util.List;
  3. import com.ape.pojo.Student;
  4. public interface StudentMapper {
  5. public List<Student> fundAllStudent();
  6. }

3)测试类:

  1. package com.ape.test;
  2. import java.util.List;
  3. import org.apache.ibatis.session.SqlSession;
  4. import com.ape.dao.DaoUtil;
  5. import com.ape.mapper.StudentMapper;
  6. import com.ape.pojo.Student;
  7. public class Test03 {
  8. public static void main(String[] args) {
  9. SqlSession sqlSession = DaoUtil.getSqlSession();
  10. StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
  11. List<Student> AllStudent = mapper.fundAllStudent();
  12. for (Student student : AllStudent) {
  13. System.out.println(student);
  14. }
  15. }
  16. }

4)结果

方式四:注解

1)依旧使用方式三的pojo

一对多

student为主表时,存在一对多关系,使用@Many注解

2)mapper

  1. package com.ape.mapper;
  2. import java.util.List;
  3. import org.apache.ibatis.annotations.Many;
  4. import org.apache.ibatis.annotations.Param;
  5. import org.apache.ibatis.annotations.Result;
  6. import org.apache.ibatis.annotations.Results;
  7. import org.apache.ibatis.annotations.Select;
  8. import com.ape.pojo.Score;
  9. import com.ape.pojo.Student;
  10. public interface StudentAnnotationMapper {
  11. @Select("select * from student")
  12. @Results({
  13. @Result(column = "sid",property = "sid"),
  14. @Result(column = "sname",property = "sname"),
  15. @Result(column = "birthday",property = "birthday"),
  16. @Result(column = "ssex",property = "ssex"),
  17. @Result(column = "classid",property = "classid"),
  18. @Result(property = "scList",column ="sid",many = @Many(select = "com.ape.mapper.StudentAnnotationMapper.fundScoreById") )
  19. })
  20. public List<Student> fundAllStudent();
  21. @Select("select * from score where sid = #{sid}")
  22. public Score fundScoreById(@Param("sid")int sid);
  23. }

3)测试类:

  1. package com.ape.test;
  2. import java.util.List;
  3. import org.apache.ibatis.session.SqlSession;
  4. import com.ape.dao.DaoUtil;
  5. import com.ape.mapper.StudentAnnotationMapper;
  6. import com.ape.mapper.StudentMapper;
  7. import com.ape.pojo.Student;
  8. public class Test04 {
  9. public static void main(String[] args) {
  10. SqlSession sqlSession = DaoUtil.getSqlSession();
  11. StudentAnnotationMapper mapper = sqlSession.getMapper(StudentAnnotationMapper.class);
  12. List<Student> AllStudent = mapper.fundAllStudent();
  13. for (Student student : AllStudent) {
  14. System.out.println(student);
  15. }
  16. }
  17. }

4)结果

一对一

score为主表时,存在一对一关系,使用@One注解

2)mapper

  1. package com.ape.mapper;
  2. import java.util.List;
  3. import org.apache.ibatis.annotations.Many;
  4. import org.apache.ibatis.annotations.Param;
  5. import org.apache.ibatis.annotations.Result;
  6. import org.apache.ibatis.annotations.Results;
  7. import org.apache.ibatis.annotations.Select;
  8. import com.ape.pojo.Score;
  9. import com.ape.pojo.Student;
  10. public interface ScoreAnnotationMapper {
  11. @Select("select * from score")
  12. @Results({
  13. @Result(column = "sid",property = "sid"),
  14. @Result(column = "cname",property = "cname"),
  15. @Result(column = "sc",property = "sc"),
  16. @Result(property = "student",column ="sid",one = @One(select = "com.ape.mapper.ScoreAnnotationMapper.fundStudentById") )
  17. })
  18. public List<Score> fundAllScore();
  19. @Select("select * from student where sid = #{sid}")
  20. public Student fundStudentById(@Param("sid")int sid);
  21. }

3)测试类:

  1. package com.ape.test;
  2. import java.util.List;
  3. import org.apache.ibatis.session.SqlSession;
  4. import com.ape.dao.DaoUtil;
  5. import com.ape.mapper.ScoreAnnotationMapper;
  6. import com.ape.pojo.Score;
  7. public class Test05 {
  8. public static void main(String[] args) {
  9. SqlSession sqlSession = DaoUtil.getSqlSession();
  10. ScoreAnnotationMapper mapper = sqlSession.getMapper(ScoreAnnotationMapper.class);
  11. List<Score> allScore = mapper.fundAllScore();
  12. for (Score score : allScore) {
  13. System.out.println(score);
  14. }
  15. }
  16. }

4)结果

四种方式对比

数据库创建视图方式数据库创建存储过程方式mybatis配置文件方式mybatis注解方式
动态SQL的处理Java层处理动态SQL的处理需要到数据库服务器处理Java层处理Java层处理
模糊查询处理Java层处理数据库服务器处理Java层处理Java层处理
性能Java层读取一次如果存储过程含有逻辑,这部分逻辑会分担到数据库服务器,增加服务器负担;只读取一次Java层只读取一次,并且需要理映射问题

多条数据的情况下,会产生java端多次访问数据库服务器,性能最低

(极不推荐)

优缺点     

不需要考虑级联带来的映射问题(一对一,一对多)

需要增加pojo类

不需要考虑级联带来的映射问题(一对一,一对多)

需要增加pojo类

需要考虑级联的问题,不用增加pojo类作者没看出来这个存在优点......
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/391773
推荐阅读
相关标签
  

闽ICP备14008679号