1. 程式人生 > 其它 >MyBatis從未入門到放棄

MyBatis從未入門到放棄

技術標籤:Java

1. 前戲

  • 本地建立ssm資料庫
  • 建立student表
CREATE TABLE `student` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  • 插入兩條資料
INSERT INTO `student` VALUES (1001, '曹操',
'[email protected]', 20); INSERT INTO `student` VALUES (1002, '劉備', '[email protected]', 28);

2. 搭建專案

  • Maven搭建普通的Java專案
Mybatis  // 根目錄,工程名
|---src  // 原始碼
|---|---main  // 主程式
|---|---|---java  // 主程式的Java原始碼
|---|---|---resources  // 主程式的配置檔案
|---|---test  // 測試程式
|---|---|---java  // 測試程式的Java原始碼
|---|--
-|---resources // 測試程式的配置檔案 |---pom.xml // maven工程的核心配置檔案
<!-- MySQL驅動 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.12</version>
</dependency>
<!-- Mybatis驅動 -->
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.6</version> </dependency>
  • 加入編譯外掛
<build>
    <resources>
        <resource>
            <directory>src/main/java</directory><!--所在的目錄-->
            <includes><!--包括目錄下的.properties,.xml 檔案都會掃描到-->
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>
  • src/main/resources下建立連線資料庫的配置檔案config.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">
<configuration>
    <!-- settings控制mybatis全域性行為的 -->
    <settings>
        <!-- 設定Mybatis輸出日誌 -->
        <setting name="logImpl" value="STDOUT_LOGGING" />
    </settings>
    <!-- 環境配置:資料庫的連線資訊
         default: 表示預設使用某個資料庫資訊配置
     -->
    <environments default="develop">
        <!-- environment: 一個數據庫資訊的配置
             id: 唯一值,表示環境的名稱 -->
        <environment id="develop">
            <!-- transactionManager: mybatis的事務型別
                 type: JDBC(表示使用jdbc中的Connection物件的commit、rollback做事務處理) -->
            <transactionManager type="JDBC"/>
            <!-- dataSource: 表示資料來源,連線資料庫的
                 type表示資料來源的型別,POOLED表示使用連線池 -->
            <dataSource type="POOLED">
                <!-- driver、user、password是固定的 -->
                <!-- 資料庫的驅動類名 -->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <!-- 連線資料庫的url字串  -->
                <property name="url" value="jdbc:mysql://localhost:3306/ssm?useSSL=false&amp;serverTimezone=Asia/Shanghai"/>
                <!-- 訪問資料庫的使用者名稱 -->
                <property name="username" value="root"/>
                <!-- 訪問資料庫的密碼 -->
                <property name="password" value="root"/>
            </dataSource>
        </environment>
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
        <environment id="online">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- sql mapper(sql對映檔案)的位置 -->
    <mappers>
        <!-- 一個mapper標籤指定一個檔案的位置
             從類路徑開始的路徑資訊,就是編譯後target/classes開始的操作類配置路徑-->
        <mapper resource="com/buddha/dao/StudentDao.xml"/>
    </mappers>

</configuration>

3. 編寫程式碼

  • src/main/java下建立包com.buddha,並在包下建立兩個目錄domain和dao目錄
  • domain目錄下建立Student類
package com.buddha.domain;

public class Student {
    private Integer id;
    private String name;
    private String email;
    private Integer age;

    public Student() {
    }

    public Student(Integer id, String name, String email, Integer age) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }
}
  • dao目錄下建立StudentDao操作介面
package com.buddha.dao;

import com.buddha.domain.Student;

import java.util.List;

// 介面操作Student表
public interface StudentDao {
    // 查詢student表的所有資料
    public List<Student> selectStudent();
}
  • dao目錄下建立StudentDao.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.buddha.dao.StudentDao">
    <!--
        select: 表示查詢操作
        id: 執行sql語句的唯一標識,mybatis會使用這個id的值來找到要執行的sql語句,可以自定義,但是要求使用介面中的方法名稱
        resultType: 表示結果型別,是sql語句執行後得到的ResultSet,遍歷這個ResultSet得到的Java物件的型別。
                    值寫的是型別的全限定名稱
    -->
    <select id="selectStudent" resultType="com.buddha.domain.Student">
        select id,name,email,age from student order by id
    </select>
</mapper>
<!--
    sql對映檔案,寫sql語句的,mybatis會執行這些sql
    1. 指定約束檔案
    <!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    mybatis-3-mapper.dtd是約束檔案的名稱,副檔名是dtd
    2. 約束檔案作用:限制,檢查在當前檔案中出現的標籤,屬性必須符合mybatis的要求
    3. mapper 是當前檔案的根標籤,必須的。
       namespace 叫做名稱空間,唯一值,可以是自定義的字串。要求你使用dao介面的全限定名稱
    4. 在當前檔案中,可以使用特定的標籤,表示資料庫的特定操作
       <select>: 表示執行查詢,放的是查詢語句
       <update>: 表示執行更新,放的是更新語句
       <insert>: 表示執行插入,放的是插入語句
       <delete>: 表示執行刪除,放的是刪除語句
-->

4. 編寫測試程式碼

  • src/test/resources目錄下新增配置檔案config.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">
<configuration>
    <!-- settings控制mybatis全域性行為的 -->
    <settings>
        <!-- 設定Mybatis輸出日誌 -->
        <setting name="logImpl" value="STDOUT_LOGGING" />
    </settings>
    <!-- 環境配置:資料庫的連線資訊
         default: 表示預設使用某個資料庫資訊配置
     -->
    <environments default="develop">
        <!-- environment: 一個數據庫資訊的配置
             id: 唯一值,表示環境的名稱 -->
        <environment id="develop">
            <!-- transactionManager: mybatis的事務型別
                 type: JDBC(表示使用jdbc中的Connection物件的commit、rollback做事務處理) -->
            <transactionManager type="JDBC"/>
            <!-- dataSource: 表示資料來源,連線資料庫的
                 type表示資料來源的型別,POOLED表示使用連線池 -->
            <dataSource type="POOLED">
                <!-- driver、user、password是固定的 -->
                <!-- 資料庫的驅動類名 -->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <!-- 連線資料庫的url字串  -->
                <property name="url" value="jdbc:mysql://localhost:3306/ssm?useSSL=false&amp;serverTimezone=Asia/Shanghai"/>
                <!-- 訪問資料庫的使用者名稱 -->
                <property name="username" value="root"/>
                <!-- 訪問資料庫的密碼 -->
                <property name="password" value="root"/>
            </dataSource>
        </environment>
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
        <environment id="online">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- sql mapper(sql對映檔案)的位置 -->
    <mappers>
        <!-- 一個mapper標籤指定一個檔案的位置
             從類路徑開始的路徑資訊,就是編譯後target/classes開始的操作類配置路徑-->
        <mapper resource="com/buddha/dao/StudentDao.xml"/>
    </mappers>

</configuration>
  • src/test/java下建立com.buddha,並建立測試類TestStudent類
package com.buddha;

import com.buddha.domain.Student;
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.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestStudent {
    @Test
    public void testSelectStudent() throws IOException {
        // 訪問mybatis讀取student資料
        // 1. 定義mybatis主配置檔案的名稱,從類路徑的根開始(target/classes)
        String config = "config.xml";
        // 2. 讀取這個config表示的檔案
        InputStream is = Resources.getResourceAsStream(config);
        // 3. 建立SqlSessionFactoryBuilder物件
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 4. 建立SqlSessionFactory物件
        SqlSessionFactory build = builder.build(is);
        // 5. [重要]從SqlSessionFactory中獲取SqlSession物件
        SqlSession sqlSession = build.openSession();
        // 6. [重要]指定要執行的sql語句標識,sql對映檔案中的名稱空間 + "." + id
        String sqlId = "com.buddha.dao.StudentDao" + "." + "selectStudent";
        // 7. 通過sqlId找到sql語句,然後執行sql語句
        List<Student> studentList = sqlSession.selectList(sqlId);
        // 8. 輸出結果
        // studentList.forEach(stu -> System.out.println(stu));
        for (Student stu : studentList) {
            System.out.println(stu);
        }
        // 9. 關閉SqlSession物件
        sqlSession.close();
    }
}

5. 增刪改查

package com.buddha.dao;

import com.buddha.domain.Student;

import java.util.List;

public interface StudentDao {
    // 查詢
    public List<Student> selectStudent();

    // 插入
    public int insertStudent(Student student);

    // 更新
    public int updateStudent(Student student);

    // 刪除
    public int deleteStudent(Student student);
}
<?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.buddha.dao.StudentDao">
    <!-- 查詢 -->
    <select id="selectStudent" resultType="com.buddha.domain.Student">
        select id,name,email,age from student order by id
    </select>

    <!-- 插入 -->
    <insert id="insertStudent">
        INSERT INTO student VALUES (#{id},#{name},#{email},#{age})
    </insert>

    <!-- 更新 -->
    <update id="updateStudent">
        UPDATE student SET age = #{age} WHERE id = #{id}
    </update>

    <delete id="deleteStudent">
        DELETE FROM student WHERE id = #{id}
    </delete>
</mapper>
package com.buddha;

import com.buddha.domain.Student;
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.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestStudent {
    @Test
    public void testSelectStudent() throws IOException {
        // 訪問mybatis讀取student資料
        // 1. 定義mybatis主配置檔案的名稱,從類路徑的根開始(target/classes)
        String config = "config.xml";
        // 2. 讀取這個config表示的檔案
        InputStream is = Resources.getResourceAsStream(config);
        // 3. 建立SqlSessionFactoryBuilder物件
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 4. 建立SqlSessionFactory物件
        SqlSessionFactory build = builder.build(is);
        // 5. [重要]從SqlSessionFactory中獲取SqlSession物件
        SqlSession sqlSession = build.openSession();
        // 6. [重要]指定要執行的sql語句標識,sql對映檔案中的名稱空間 + "." + id
        String sqlId = "com.buddha.dao.StudentDao" + "." + "selectStudent";
        // 7. 通過sqlId找到sql語句,然後執行sql語句
        List<Student> studentList = sqlSession.selectList(sqlId);
        // 8. 輸出結果
        // studentList.forEach(stu -> System.out.println(stu));
        for (Student stu : studentList) {
            System.out.println(stu);
        }
        // 9. 關閉SqlSession物件
        sqlSession.close();
    }

    @Test
    public void testInsertStudent() throws IOException {
        String config = "config.xml";
        InputStream is = Resources.getResourceAsStream(config);
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory build = builder.build(is);
        SqlSession sqlSession = build.openSession();
        String sqlId = "com.buddha.dao.StudentDao" + "." + "insertStudent";
        Student stu = new Student(1005, "大喬", "[email protected]", 18);
        int i = sqlSession.insert(sqlId, stu);
        sqlSession.commit();
        System.out.println("插入資料影響行數:" + i);
        sqlSession.close();
    }

    @Test
    public void testUpdateStudent() throws IOException {
        String config = "config.xml";
        InputStream is = Resources.getResourceAsStream(config);
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory build = builder.build(is);
        SqlSession sqlSession = build.openSession();
        String sqlId = "com.buddha.dao.StudentDao" + "." + "updateStudent";
        Student stu = new Student();
        stu.setId(1005);
        stu.setAge(25);
        int i = sqlSession.update(sqlId, stu);
        sqlSession.commit();
        System.out.println("更新資料影響行數:" + i);
        sqlSession.close();
    }

    @Test
    public void testDeleteStudent() throws IOException {
        String config = "config.xml";
        InputStream is = Resources.getResourceAsStream(config);
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory build = builder.build(is);
        SqlSession sqlSession = build.openSession();
        String sqlId = "com.buddha.dao.StudentDao" + "." + "deleteStudent";
        Student stu = new Student();
        stu.setId(1005);
        int i = sqlSession.delete(sqlId, stu);
        sqlSession.commit();
        System.out.println("刪除資料影響行數:" + i);
        sqlSession.close();
    }
}

6. 優化公共部分程式碼

package com.buddha.utils;

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 java.io.IOException;
import java.io.InputStream;

public class MyBatisUtils {
    private static SqlSessionFactory factory = null;
    static {
        String config = "config.xml";
        try {
            InputStream is = Resources.getResourceAsStream(config);
            factory = new SqlSessionFactoryBuilder().build(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession() {
        SqlSession sqlSession = null;
        if (factory != null) {
            sqlSession = factory.openSession();
        }
        return sqlSession;
    }
}
package com.buddha;

import com.buddha.domain.Student;
import com.buddha.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.io.IOException;
import java.util.List;

public class TestStudent {
    @Test
    public void testSelectStudent() throws IOException {
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        String sqlId = "com.buddha.dao.StudentDao" + "." + "selectStudent";
        List<Student> studentList = sqlSession.selectList(sqlId);
        for (Student stu : studentList) {
            System.out.println(stu);
        }
        sqlSession.close();
    }
}

7. 動態代理機制

package com.buddha;

import com.buddha.dao.StudentDao;
import com.buddha.domain.Student;
import com.buddha.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.io.IOException;
import java.util.List;

public class TestStudent {
    @Test
    public void testSelectStudent() throws IOException {
        /**
         * 使用MyBatis的動態代理機制,使用sqlSession.getMapper(dao介面)
         * getMapper能獲取dao介面對於實現類物件
         */
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);
        // 呼叫dao的方法,執行資料庫的操作
        List<Student> students = dao.selectStudent();
        for (Student student : students) {
            System.out.println(student);
        }
        sqlSession.close();
    }
}