MyBatis從未入門到放棄
阿新 • • 發佈:2020-12-16
技術標籤: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工程的核心配置檔案
- Maven搜尋 MySQL和MyBatis座標加入到pom.xml
<!-- 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&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&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();
}
}