Mybatis 一對多 學習總結04
1、Mybatis 元件的宣告週期
宣告週期是元件的重要問題,Mybatis也常用語多執行緒環境,錯誤使用會造成多執行緒併發問題,為正確編寫Mybatis應用程式,我們要掌握Mybatis元件的宣告週期。
宣告週期就是每一個物件應該存活的時間,比如一些物件一次用完後要關閉,使它被java虛擬機器(JVM)銷燬,以避免繼續佔用資源,我們根據每一個元件作用去確定其宣告週期。
1、SqlSessionFactoryBuilder
SqlSessionFactoryBuilder的作用在於建立SqlSessionFactory,之後就失去了作用。所以最佳作用域是方法作用域(也就是區域性方法變數)
2、SqlSessionFactory
SqlSessionFactory可以被認為是一個資料庫連線池,作用是建立SqlSession介面物件。Mybatis本質是對java資料庫的操作,所以SqlSessionFactory生命週期存在於整個Mybatis應用中。
SqlSessionFactory是一個對資料庫的連線池,所以佔據資料連線資源,多個的話不利於對資料庫資源的控制。所以往往希望SqlSessionFactory作為單列。最佳作用域是應用作用域。
3、SqlSession
Session相當於一個數據庫連線(connection)物件,執行多條SQL,然後commit、rollback等方法。最佳作用域請求或方法作用域。
4、Mapper
Mapper是一個介面,有SqlSession所建立,由於session關閉它的資料連線資源也會消失,宣告週期小於Sqlsession。
Mapper代表的是一個請求的業務處理,一旦完成相關的業務,就應該廢棄它。
2、一對多
多對一處理:如一群學生有一個老師。
1、資料庫
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, '秦老師'); 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');
2、實體類
Student.java
package com.pojo;
public class Student {
private Integer id;
private String name;
private Teacher teacher;
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public Teacher getTeacher() {
return teacher;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", teacher=" + teacher +
'}';
}
}
Teacher.java
package com.pojo;
import lombok.Data;
import lombok.ToString;
@Data // 相當於:get、set方法
@ToString // 相當於:toStrong方法
public class Teacher {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Teacher{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
3、介面student
student(介面)
package com.dao.student;
import com.pojo.Student;
import java.util.List;
public interface student {
public List<Student> getStudents2();
}
4、實現類 xml檔案
多對一實現:
先用sql查詢出結果,在通過結果集對映(resultMap),結果集中使用association對裡面的類進行對映,
studentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dao.student.student"> <!-- 對映器 名稱空間:對映到那個類的地址 -->
<!-- 1. 直接查詢出結果,進行結果集的對映-->
<!--resultMap:將結果對映到pojo上 , id為:StudentTeacher2-->
<select id="getStudents2" resultMap="StudentTeacher2" >
select s.id sid, s.name sname , t.name tname
from student s,teacher t
where s.tid = t.id
</select>
<!--名(id)為:StudentTeacher2, 對映到實體類:Student-->
<resultMap id="StudentTeacher2" type="Student">
<!--id標籤標示主鍵,實體類id,對應資料表中的:sid-->
<id property="id" column="sid"/>
<result property="name" column="sname"/>
<!--關聯物件property 關聯物件在Student實體類中的屬性-->
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
</mapper>
5、註冊Mapper
mybatis-config.xml
<mappers>
<mapper resource="com/dao/student/studentMapper.xml"/>
</mappers>
6、測試
MyTest.java
import com.dao.student.student;
import com.dao.userMapper;
import com.pojo.Student;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import utils.MybatisUtils;
import java.util.List;
public class MyTest {
@Test
public void selectUser() {
SqlSession session = MybatisUtils.getSession();
userMapper mapper = session.getMapper(userMapper.class);
student mapper1 = session.getMapper(student.class);
List<Student> students2 = mapper1.getStudents2();
for (Student stu : students2) {
System.out.println(
/*這裡使用了lombok註解出get、set方法後,使用get方法會報紅,但不影響程式*/
"學生名:"+stu.getName() + "老師:"+stu.getTeacher().getName()
);
}
session.close();
}
}
7、執行中出現的異常
studentMapper mapper1 = session.getMapper(studentMapper.class)
如果studentMapper報紅,出現異常:Cannot resolve symbol 'studentMapper'
解決方法:將studentMapper修改成student即可(注意studentMapper.xml裡面的namespace要正確、和要到配置檔案中註冊studentMapper.xml檔案。)