MyBatis
一、入門
1.前言
https://mybatis.org/mybatis-3/zh/index.html
mybatis3有比較豐富的中文官方檔案,一切應該以檔案為主,
參考視頻:狂神說Java-Mybatis
作為一款優秀的持久層框架,MyBatis幾乎免除了所有的JDBC代碼,十分方便,
但是由于檔案某些時候閱讀起來確實有一定的門檻,因此對其做一定的筆記也是必要的,
前置內容:
- Java
- maven
- MySQL
- JDBC
- JavaWeb中持久化層的一些知識,如POJO
環境:
- Java11
- IDEA 2019.3.3
- MySQL8
- mybatis3
2.入門
2.1 路徑
本文使用Maven創建Mybais專案,專案路徑如下,

在IDEA創建Maven專案后,將其src刪去,同時在該專案下創建Module即可,這時IDLE會自動在兩個pom.xml中寫入兩者的關系,即在父pom.xml中寫入:
<modules> <module>mybatis-01</module> </modules>在子pom.xml中寫入:
<parent> <artifactId>MyBaitsLearn</artifactId> <groupId>com.duzhuan</groupId> <version>1.0-SNAPSHOT</version> </parent>
這是一種使用習慣,父pom.xml的配置子pom.xml可以繼承,
如果不明文標出,一般認為下面對于pom.xml的操作都是對父pom.xml的操作,
2.2 依賴
<!--jdbc-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<!--JUnit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>

確認這個子專案里有依賴,
2.3 創建資料庫
create database if not exists `mybatis`;
use `mybatis`;
create table if not exists `User`(
`id` INT(20) not null primary key,
`name` VARCHAR(20) default null,
`pwd` varchar(20) default null
)ENGINE=INNODB default CHARSET = UTF8;
insert into `User`(`id`,`name`,`pwd`)
values (1,'admin','123456'),
(2,'Jax','123456'),
(3,'Jinx','123455'),
(4,'Query','123456'),
(5,'biubiu','123456');
2.4 POJO
路徑

代碼
package com.duzhuan.pojo;
/**
* @Autord: HuangDekai
* @Date: 2020/9/9 14:11
* @Version: 1.0
* @since: jdk11
*/
public class User {
private int id;
private String name;
private String password;
public User() {
}
public User(int id, String name, String password) {
this.id = id;
this.name = name;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}
2.5 簡配組態檔
路徑

簡單決議
<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value=https://www.cnblogs.com/duzhuan/p/"${driver}"/>
xml檔案頭不提,
所有的配置都應該在<configuration>標簽內,這是一個可以暫且用來展示功能的組態檔,很顯然的是現在沒有任何功能,而且與官網復制下來的相比,缺少了mappers及其子標簽,
先一行一行看,<environments>標簽,顯然,可以配置多套環境,default表示的是默認是使用哪套環境,通過觀看<enviroments>可以看到有id屬性,顯然,<envireonments default="environment的id",
transactionManager,事務管理器,具體可查看官網檔案-配置-事務管理器,這里只需要讓transactionManager的值為JDBC,
dataSource,資料源,大多數 MyBatis 應用程式會按示例中的例子來配置資料源,雖然資料源配置是可選的,但如果要啟用延遲加載特性,就必須配置資料源,有三種內建的資料源型別(也就是 type="[UNPOOLED|POOLED|JNDI]"),之后深入了解可以通過查詢檔案,這里使用POOLED,即使用連接池,其默認設定鏈接數量是10,暫不深入了解,
關于properties:
driver– 這是 JDBC 驅動的 Java 類全限定名(并不是 JDBC 驅動中可能包含的資料源類),url– 這是資料庫的 JDBC URL 地址,username– 登錄資料庫的用戶名,password– 登錄資料庫的密碼,
因此,若是要簡單地使用組態檔,可以先如下設定:
<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value=https://www.cnblogs.com/duzhuan/p/"com.mysql.jdbc.Driver"/>
其中&是在xml中&的轉義字符,
2.6 UserMapper
路徑

相當于JavaWeb里的UserDao介面,在MyBatis中稱其為Mapper,
UserMapper代碼為:
package com.duzhuan.dao;
import com.duzhuan.pojo.User;
import java.util.List;
/**
* @Autord: HuangDekai
* @Date: 2020/9/9 19:42
* @Version: 1.0
* @since: jdk11
*/
public interface UserMapper {
List<User> getUserList();
}
2.7 UserMapper.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.duzhuan.dao.UserMapper">
<select id="getUserList" resultType="com.duzhuan.pojo.User">
select * from mybatis.user
</select>
</mapper>
L1-L4為xml檔案頭
mapper是根標簽,只允許有一個,namespace,命名空間,其值等于要系結的介面的全限定名,顯然一個Mapper.xml只會系結一個介面,
select顯然是一個用于執行SQL查詢陳述句的標簽,其中id等于的是namespace中 系結的介面中的方法的名字,
`
resultType為結果的型別的全限定名,select * from mybatis.user是執行的SQL,

值得一提的是,類似于回傳值為List<User>這種串列的,resultType也是填寫具體的物體類,
在資料庫中執行select * from mybatis.user時回傳的是:

到此仍未使用MyBatis去獲取資料庫里的資料,并且上面某些配置存在一些比較顯然的問題,但先按下不表,繼續,
2.8 MybatisUtils
這個類用于封裝一些固定步驟,
路徑

代碼
package com.duzhuan.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;
/**
* @Autord: HuangDekai
* @Date: 2020/9/9 21:38
* @Version: 1.0
* @since: jdk11
*/
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
可以參照官方檔案中從SqlSessionFactory中獲取SqlSession:
從 XML 中構建 SqlSessionFactory
每個基于 MyBatis 的應用都是以一個 SqlSessionFactory 的實體為核心的,SqlSessionFactory 的實體可以通過 SqlSessionFactoryBuilder 獲得,而 SqlSessionFactoryBuilder 則可以從 XML 組態檔或一個預先配置的 Configuration 實體來構建出 SqlSessionFactory 實體,
從 XML 檔案中構建 SqlSessionFactory 的實體非常簡單,建議使用類路徑下的資源檔案進行配置, 但也可以使用任意的輸入流(InputStream)實體,比如用檔案路徑字串或 file:// URL 構造的輸入流,MyBatis 包含一個名叫 Resources 的工具類,它包含一些實用方法,使得從類路徑或其它位置加載資源檔案更加容易,
String resource = "org/mybatis/example/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
2.9 創建測驗樣例
路徑

UserMapperTest代碼
package com.duzhuan.dao;
import com.duzhuan.pojo.User;
import com.duzhuan.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
/**
* @Autord: HuangDekai
* @Date: 2020/9/9 21:56
* @Version: 1.0
* @since: jdk11
*/
public class UserMapperTest {
@Test
public void getUserListTest(){
SqlSession sqlSession= MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = userMapper.getUserList();
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
}
2.10 可能遇到的錯誤
2.10.1 Error:java: 錯誤: 不支持發行版本 5






最好將上述位置的Java版本設為一致,
2.10.2
經典錯誤
porg.apache.ibatis.binding.BindingException: Type interface com.duzhuan.dao.UserMapper is not known to the MapperRegistry.類似于Servlet需要在web.xml中注冊一樣,Mapper也需要在mybatis-config.xml中注冊,
在mybatis-config.xml的根標簽里添加:
<mappers>
<mapper class="com.duzhuan.dao.UserMapper"></mapper>
</mappers>

建立關系的方式多種多樣,這里僅用class="Mapper全限定名"用來舉例,同時,比如這種用法要求:

- Mapper與Mapper.xml同名
- Mapper與Mapper.xml同目錄
2.10.3
經典錯誤
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.duzhuan.dao.UserMapper.getUserList一般情況下,是因為Maven生成的target檔案夾中沒有Mapper對應的Mapper.xml,

只要把UserMapper.xml檔案復制粘貼過去一般就能解決,
但是這是Maven造成的問題,maven默認只復制java代碼檔案,對xml、properties等不復制,而且,每次都要復制粘貼過去也很麻煩,因此解決問題的正道應該是修改maven的配置,
在父pom.xml主標簽里加入:
<build>
<resources>
<resource>
<directory>src/main/resource/</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java/</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
2.11 輸出結果及修正

在我們的資料庫中,密碼這一欄位的欄位名為pwd:

在POJO中,很顯然地,其屬性名為password:

從SQL上說,在此處select * from mybatis.user可以類似看為:
select `id`,`name`,`password` from mybatis.user
當然,在SQL這樣是不能執行的,只是Mybatis將其處理成全都是null的欄位,具體操作有待研究,
這時修改pojo的屬性及其 getter and setter方法名為pwd無疑是簡單的,但是MyBatis也有許多解決辦法,
修改 UserMapper.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.duzhuan.dao.UserMapper">
<resultMap id="UserMap" type="com.duzhuan.pojo.User">
<result column="pwd" property="password"/>
</resultMap>
<select id="getUserList" resultMap="UserMap">
select * from mybatis.user
</select>
</mapper>
增加了resultMap標簽及其子標簽,其中id是resultMap的id,在11行中resultMap的值就是需要的resultMap的id,
type中是要映射的物體類的全限定名或別名,
column的值是資料庫的欄位名,property的值要映射的物體類中的屬性的名稱,
這樣,就相當于有如下SQL:
select `id`,`name`,`pwd`as`password` from mybatis.user
當然,MyBatis做的要多得多,比如省略了人工撰寫JDBC代碼,將從資料庫拿到的資料放入POJO中的操作,
結果:

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/363.html
標籤:Java
上一篇:取近似值
下一篇:MySQL挑戰:建立10萬連接
