環(huán)境:
- JDK1.8
- Mysql 5.7
- maven 3.6.1
- IDEA
回顧:
- JDBC
- Mysql
- Java基礎(chǔ)
- Maven
- Junit
SSM框架:配置文件的。 最好的方式:看官網(wǎng)文檔;
1、簡(jiǎn)介
1.1、什么是Mybatis

1569633932712
- MyBatis 是一款優(yōu)秀的持久層框架
- 它支持定制化 SQL、存儲(chǔ)過程以及高級(jí)映射。
- MyBatis 避免了幾乎所有的 JDBC 代碼和手動(dòng)設(shè)置參數(shù)以及獲取結(jié)果集。
- MyBatis 可以使用簡(jiǎn)單的 XML 或注解來配置和映射原生類型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 對(duì)象)為數(shù)據(jù)庫(kù)中的記錄。
- MyBatis 本是apache的一個(gè)開源項(xiàng)目iBatis, 2010年這個(gè)項(xiàng)目由apache software foundation 遷移到了google code,并且改名為MyBatis 。
- 2013年11月遷移到Github。
如何獲得Mybatis?
-
maven倉(cāng)庫(kù):
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.2</version> </dependency>
1.2、持久化
數(shù)據(jù)持久化
- 持久化就是將程序的數(shù)據(jù)在持久狀態(tài)和瞬時(shí)狀態(tài)轉(zhuǎn)化的過程
- 內(nèi)存:斷電即失
- 數(shù)據(jù)庫(kù)(Jdbc),io文件持久化。
- 生活:冷藏. 罐頭。
為什么需要需要持久化?
有一些對(duì)象,不能讓他丟掉。
內(nèi)存太貴了
1.3、持久層
Dao層,Service層,Controller層….
- 完成持久化工作的代碼塊
- 層界限十分明顯。
1.4 為什么需要Mybatis?
- 幫助程序猿將數(shù)據(jù)存入到數(shù)據(jù)庫(kù)中。
- 方便
- 傳統(tǒng)的JDBC代碼太復(fù)雜了。簡(jiǎn)化??蚣?。自動(dòng)化。
- 不用Mybatis也可以。更容易上手。 技術(shù)沒有高低之分
- 優(yōu)點(diǎn):
- 簡(jiǎn)單易學(xué)
- 靈活
- sql和代碼的分離,提高了可維護(hù)性。
- 提供映射標(biāo)簽,支持對(duì)象與數(shù)據(jù)庫(kù)的orm字段關(guān)系映射
- 提供對(duì)象關(guān)系映射標(biāo)簽,支持對(duì)象關(guān)系組建維護(hù)
- 提供xml標(biāo)簽,支持編寫動(dòng)態(tài)sql。
最重要的一點(diǎn):使用的人多!
Spring SpringMVC SpringBoot
2、第一個(gè)Mybatis程序
思路:搭建環(huán)境-->導(dǎo)入Mybatis-->編寫代碼-->測(cè)試!
2.1、搭建環(huán)境
搭建數(shù)據(jù)庫(kù)
CREATE DATABASE `mybatis`;
USE `mybatis`;
CREATE TABLE `user`(
`id` INT(20) NOT NULL PRIMARY KEY,
`name` VARCHAR(30) DEFAULT NULL,
`pwd` VARCHAR(30) DEFAULT NULL
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `user`(`id`,`name`,`pwd`) VALUES
(1,'狂神','123456'),
(2,'張三','123456'),
(3,'李四','123890')
新建項(xiàng)目
新建一個(gè)普通的maven項(xiàng)目
刪除src目錄
-
導(dǎo)入maven依賴
<!--導(dǎo)入依賴--> <dependencies> <!--mysql驅(qū)動(dòng)--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <!--mybatis--> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.2</version> </dependency> <!--junit--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies>
2.2、創(chuàng)建一個(gè)模塊
-
編寫mybatis的核心配置文件
<?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核心配置文件--> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> </configuration> -
編寫mybatis工具類
//sqlSessionFactory --> sqlSession public class MybatisUtils { private static SqlSessionFactory sqlSessionFactory; static{ try { //使用Mybatis第一步:獲取sqlSessionFactory對(duì)象 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } //既然有了 SqlSessionFactory,顧名思義,我們就可以從中獲得 SqlSession 的實(shí)例了。 // SqlSession 完全包含了面向數(shù)據(jù)庫(kù)執(zhí)行 SQL 命令所需的所有方法。 public static SqlSession getSqlSession(){ return sqlSessionFactory.openSession(); } }
2.3、編寫代碼
-
實(shí)體類
package com.kuang.pojo; //實(shí)體類 public class User { private int id; private String name; private String pwd; public User() { } public User(int id, String name, String pwd) { this.id = id; this.name = name; this.pwd = pwd; } 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 getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", pwd='" + pwd + '\'' + '}'; } } -
Dao接口
public interface UserDao { List<User> getUserList(); } -
接口實(shí)現(xiàn)類由原來的UserDaoImpl轉(zhuǎn)變?yōu)橐粋€(gè) Mapper配置文件.
<?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"> <!--namespace=綁定一個(gè)對(duì)應(yīng)的Dao/Mapper接口--> <mapper namespace="com.kuang.dao.UserDao"> <!--select查詢語句--> <select id="getUserList" resultType="com.kuang.pojo.User"> select * from mybatis.user </select> </mapper>
2.4、測(cè)試
注意點(diǎn):
org.apache.ibatis.binding.BindingException: Type interface com.kuang.dao.UserDao is not known to the MapperRegistry.
MapperRegistry是什么?
核心配置文件中注冊(cè) mappers
-
junit測(cè)試
@Test public void test(){ //第一步:獲得SqlSession對(duì)象 SqlSession sqlSession = MybatisUtils.getSqlSession(); //方式一:getMapper UserDao userDao = sqlSession.getMapper(UserDao.class); List<User> userList = userDao.getUserList(); for (User user : userList) { System.out.println(user); } //關(guān)閉SqlSession sqlSession.close(); }
你們可以能會(huì)遇到的問題:
- 配置文件沒有注冊(cè)
每個(gè)Mapper.xml都需要在Mybatis核心配置文件中注冊(cè) - 綁定接口錯(cuò)誤。
- 方法名不對(duì)
- 返回類型不對(duì)
- Maven導(dǎo)出資源問題
Caused by: java.io.IOException: Could not find resource mybatis.mapper
<!--報(bào)找不到配置文件的,可以試試下面的pom 來防止資源導(dǎo)出失敗-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
提示:
在之前版本的 MyBatis 中,**命名空間(Namespaces)**的作用并不大,是可選的。 但現(xiàn)在,隨著命名空間越發(fā)重要,你必須指定命名空間。
命名空間的作用有兩個(gè),一個(gè)是利用更長(zhǎng)的全限定名來將不同的語句隔離開來,同時(shí)也實(shí)現(xiàn)了你上面見到的接口綁定。就算你覺得暫時(shí)用不到接口綁定,你也應(yīng)該遵循這里的規(guī)定,以防哪天你改變了主意。長(zhǎng)遠(yuǎn)來看,只要將命名空間置于合適的 Java 包命名空間之中,你的代碼會(huì)變得更加整潔,也有利于你更方便地使用 MyBatis。
命名解析:為了減少輸入量,MyBatis 對(duì)所有具有名稱的配置元素(包括語句,結(jié)果映射,緩存等)使用了如下的命名解析規(guī)則。
- 全限定名(比如 “com.mypackage.MyMapper.selectAllThings)將被直接用于查找及使用。
- 短名稱(比如 “selectAllThings”)如果全局唯一也可以作為一個(gè)單獨(dú)的引用。 如果不唯一,有兩個(gè)或兩個(gè)以上的相同名稱(比如 “com.foo.selectAllThings” 和 “com.bar.selectAllThings”),那么使用時(shí)就會(huì)產(chǎn)生“短名稱不唯一”的錯(cuò)誤,這種情況下就必須使用全限定名。
作用域(Scope)和生命周期
SqlSessionFactoryBuilder
這個(gè)類可以被實(shí)例化、使用和丟棄,一旦創(chuàng)建了 SqlSessionFactory,就不再需要它了。因此 SqlSessionFactoryBuilder 實(shí)例的最佳作用域是方法作用域(也就是局部方法變量)。 你可以重用 SqlSessionFactoryBuilder 來創(chuàng)建多個(gè) SqlSessionFactory實(shí)例,但最好還是不要一直保留著它,以保證所有的 XML 解析資源可以被釋放給更重要的事情。
SqlSessionFactory
SqlSessionFactory 一旦被創(chuàng)建就應(yīng)該在應(yīng)用的運(yùn)行期間一直存在,沒有任何理由丟棄它或重新創(chuàng)建另一個(gè)實(shí)例。使用 SqlSessionFactory 的最佳實(shí)踐是在應(yīng)用運(yùn)行期間不要重復(fù)創(chuàng)建多次,多次重建SqlSessionFactory 被視為一種代碼“壞習(xí)慣”。因此SqlSessionFactory 的最佳作用域是應(yīng)用作用域。有很多方法可以做到,最簡(jiǎn)單的就是使用單例模式或者靜態(tài)單例模式。
SqlSession
每個(gè)線程都應(yīng)該有它自己的 SqlSession 實(shí)例。SqlSession的實(shí)例不是線程安全的,因此是不能被共享的,所以它的最佳的作用域是請(qǐng)求或方法作用域。絕對(duì)不能將 SqlSession 實(shí)例的引用放在一個(gè)類的靜態(tài)域,甚至一個(gè)類的實(shí)例變量也不行。也絕不能將 SqlSession 實(shí)例的引用放在任何類型的托管作用域中,比如 Servlet 框架中的 HttpSession。如果你現(xiàn)在正在使用一種 Web 框架,考慮將 SqlSession 放在一個(gè)和 HTTP 請(qǐng)求相似的作用域中。**換句話說,每次收到 HTTP 請(qǐng)求,就可以打開一個(gè) SqlSession,返回一個(gè)響應(yīng)后,就關(guān)閉它。** 這個(gè)關(guān)閉操作很重要,為了確保每次都能執(zhí)行關(guān)閉操作,你應(yīng)該把這個(gè)關(guān)閉操作放到 finally 塊中。