上篇實現利用mybatis實現單表增刪改查,今天利用mybatis實現多表聯合查詢。
1.創建數據庫mybatis2,建立student、class、student_class三張表
DROP TABLE IF EXISTS `class`; CREATE TABLE `class` ( `class_id` int(11) NOT NULL AUTO_INCREMENT, `class_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`class_id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; -- ---------------------------- -- Records of class -- ---------------------------- INSERT INTO `class` VALUES (1, '一班'); INSERT INTO `class` VALUES (2, '二班'); INSERT INTO `class` VALUES (3, '三班'); -- ---------------------------- -- Table structure for student -- ---------------------------- DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `id` int(5) NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `sex` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; -- ---------------------------- -- Records of student -- ---------------------------- INSERT INTO `student` VALUES (1, '張三', '男'); INSERT INTO `student` VALUES (2, '李四', '女'); INSERT INTO `student` VALUES (3, '王五', '男'); INSERT INTO `student` VALUES (4, '王麻子', '女'); INSERT INTO `student` VALUES (5, ' 趙六', '男'); -- ---------------------------- -- Table structure for student_class -- ---------------------------- DROP TABLE IF EXISTS `student_class`; CREATE TABLE `student_class` ( `sid` int(11) NOT NULL, `cid` int(11) NOT NULL ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; -- ---------------------------- -- Records of student_class -- ---------------------------- INSERT INTO `student_class` VALUES (1, 2); INSERT INTO `student_class` VALUES (2, 2); INSERT INTO `student_class` VALUES (4, 4); INSERT INTO `student_class` VALUES (3, 3); INSERT INTO `student_class` VALUES (5, 3); SET FOREIGN_KEY_CHECKS = 1;
2.在com.domain包下創建實體類
package com.domain; public class Student { private int id; private String name; private String sex; //學生所在的班級 private Class sClass; //getter/setter/toString【已省略】 }
package com.domain; import java.util.List; public class Class { private int class_id; private String class_name; private List<Student> students; //getter/setter/toString }
package com.domain; /** * @author admin * @version 1.0.0 * @ClassName Student_Class.java * @Description TODO * @createTime 2020年01月15日 16:13:00 */ public class Student_Class { private int sid; private int cid; //getter/setter/toString }
package com.domain; /** * @author admin * @version 1.0.0 * @ClassName StudentClass.java * @Description TODO * @createTime 2020年01月15日 18:10:00 */ public class StudentClass { private int id; private String name; private String sex; private int class_id; private String class_name; //getter/setter/toString }
3.在com.dao下創建接口StudentDao
package com.dao; import com.domain.Class; import com.domain.Student; import com.domain.StudentClass; import java.util.List; /** * @author admin * @version 1.0.0 * @ClassName StudentDao.java * @Description TODO * @createTime 2020年01月15日 16:20:00 */ public interface StudentDao { //獲取某學生的學號、姓名以及某學生所在的班級名 一對一關聯查詢 一個學生對應一個班級 List<Student> findByName(String studentName); List<StudentClass> findByName2(String studentName); //獲取指定班級下的所有學生 【班級編號、班級名、學生姓名、性別】 一對多關聯查詢 一個班級對應多個學生 List<Class> findAllStudent(int cid); }
4.創建主約束文件SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <!-- mybatis的主配置文件 --> <configuration> <!-- 配置環境 --> <environments default="mysql"> <!-- 配置mysql的環境--> <environment id="mysql"> <!-- 配置事務的類型--> <transactionManager type="JDBC"></transactionManager> <!-- 配置數據源(連接池) --> <dataSource type="POOLED"> <!-- 配置連接數據庫的4個基本信息 --> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis2?useUnicode=true&characterEncoding=utf8"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <!-- 配置映射文件的位置 --> <mappers> <package name="com.dao"></package> </mappers> </configuration>
5.在com.dao下創建子約束文件studentDao.xml
<?xml version="1.0" encoding="UTF-8"?> <!--mybaits頭約束 --> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--配置約束--> <mapper namespace="com.dao.StudentDao"> <!--1.獲取學生編號、姓名、對應的班級名稱--> <!-- 可以顯示指出列名,如果用"*"代替,則mybatis會自動匹配resultMap中提供的列名 --> <select id="findByName" parameterType="String" resultMap="studentClassMap"> select a.id,a.name,b.class_name from student a,class b, student_class c where a.id=c.sid and b.class_id = c.cid and a.name=#{name} </select> <!--resultMap中的type表示返回什么類型的對象--> <resultMap id="studentClassMap" type="com.domain.Student"> <!--主鍵字段--> <!--property表示com.domain.Student的字段,coloum為表中的字段,進行配置映射--> <id property="id" column="id"/> <!--非主鍵字段--> <result property="name" column="name"/> <!--association字面意思關聯,這里只專門做一對一關聯; property表示是com.domain.Student的屬性名稱 javaType表示該屬性是什么類型對象--> <association property="sClass" javaType="com.domain.Class"> <!-- property 表示com.domain.Class中的屬性; column 表示表中的列名 --> <result property="class_name" column="class_name"/> </association> </resultMap> <!--第二種方式,新建一個類,類似於視圖--> <select id="findByName2" parameterType="String" resultType="com.domain.StudentClass"> select * from student a,class b, student_class c where a.id=c.sid and b.class_id = c.cid and a.name=#{name} </select> <select id="findAllStudent" parameterType="int" resultMap="getClassStudent"> select * from class a left join student_class b on a.class_id=b.cid left join student c on b.sid = c.id where a.class_id = #{class_id} </select> <resultMap id="getClassStudent" type="com.domain.Class"> <id property="class_id" column="class_id"/> <result property="class_name" column="class_name"/> <!-- property表示集合類型屬性名稱,ofType表示集合中的對象是什么類型 --> <collection property="students" ofType="com.domain.Student"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="sex" column="sex"/> </collection> </resultMap> </mapper>
6.編寫測試類test
package com.dao; import com.domain.Class; import com.domain.Student; import com.domain.StudentClass; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.InputStream; import java.util.List; /** * @author admin * @version 1.0.0 * @ClassName test2.java * @Description TODO * @createTime 2020年01月11日 23:22:00 */ public class test2 { private InputStream in; private SqlSession sqlSession; private StudentDao studentDao; @Before//用於在測試方法執行之前執行 public void init() throws Exception { //1.讀取配置文件,生成字節輸入流 in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.獲取SqlSessionFactory工廠對象 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); //3.獲取SqlSession對象 sqlSession = factory.openSession(); //4.獲取dao的代理對象 studentDao = sqlSession.getMapper(StudentDao.class); } @After//用於在測試方法執行之后執行 public void destroy() throws Exception { //提交事務 sqlSession.commit(); //6.釋放資源 sqlSession.close(); in.close(); } @Test public void findByName(){ List<Student> lists = studentDao.findByName("張三"); for(Student s:lists){ System.out.println(s.getId()+" "+s.getName()+" "+s.getsClass().getClass_name()); } } @Test public void findByName2(){ List<StudentClass> lists = studentDao.findByName2("張三"); for(StudentClass s:lists){ System.out.println(s.toString()); } } @Test public void findAllStudent(){ List<Class> lists = studentDao.findAllStudent(2); for(Class c:lists){ System.out.println(c.toString()); } } }
7.小結
以上實現了一對一查詢與一對多查詢,有配置resultMap的方式也可以通過新建一個實體類的方式
mybatis講究一一對應映射進去,得按照人家規則來,熟練程度不如自己封裝一個操作JDBC工具類來的快。