1. 程式人生 > 實用技巧 >Mybatis 一對多 學習總結04

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檔案。)


學習文章:狂神說