一.概述
1.1 簡介
MyBatis是定製化SQL,存儲過程以及高級映射的優先的持久層框架。MyBatis避免了幾乎所有的JDBC代碼和手動設置參數以及獲取結果集。MyBatis可以使用簡單的XML或註解用於配置和原始映射,將接口和Java的POJO(Plain Old Java Objects,普通的Java對象)映射成數據庫中的記錄。
1.2 爲什麼使用MyBatis?
- JDBC
(1)SQL夾在Java代碼塊中,耦合度高導致硬編碼內傷
(2)維護不易且實際開發需求中SQL是有變化,頻繁修改的情況多見
- Hibernate
(1)長難複雜SQL,對於Hibernate而言處理也不容易
(2)內部自動生產的SQL,不容易做特殊優化
(3)基於全映射的全自動框架,大量字段的POJO進行部分映射時比較苦難,導致數據庫性能下載。
對於開發人員而言,核心SQL還是需要自己優化的。SQL和Java編碼分來,功能邊界清晰,一個專注於業務,一個專注於數據,MyBatis就可以滿足這個需求。
- MyBatis是一個半自動化的持久化層框架:
(1)MyBatis將重要的步驟抽取出來可以人工定製,其他步驟自動化
(2)重要步驟都是寫在配置文件中(好維護)
(3)完全解決數據庫優化問題
(4)MyBatis底層就是對原生JDBC的一個簡單封裝
(5)即將Java編碼與SQL抽取出來,還不會失去自動化功能,半自動的持久化
(6)一個輕量級的框架
1.3 去哪裏找MyBatis?
二.HelloWorld實驗代碼
1.基礎環境搭建
(1)創建一個Java工程
(2)創建測試庫,測試表,以及封裝數據的JavaBean,和操作數據庫的dao
創建數據庫表:
創建JavaBean:Employee(封裝表的數據)
package com.test.bean;
public class Employee {
private Integer id;
private String empname;
private String email;
private Integer gender;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getEmpname() {
return empname;
}
public void setEmpname(String empname) {
this.empname = empname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Employee [id=" + id + ", empname=" + empname + ", email="
+ email + ", gender=" + gender + "]";
}
}
創建一個Dao接口,用來操作數據庫:
package com.test.dao;
import com.test.bean.Employee;
public interface EmployeeDao {
//按照員工id查詢
public Employee getEmpById(Integer id);
}
2.用MyBatis操作數據庫
1)導包
//數據庫驅動
mysql-connector-java-5.1.37-bin.jar
mybatis-3.4.1.jar
//建議導入日誌包,這樣在MyBatis在關鍵環節就有日誌打印(log4j),依賴於類路徑下一個log4j.xml配置文件
//log4j-1.2.17.jar
2)寫配置(兩個配置文件,全局配置文件和dao接口的實現文件)
(1)第一個配置文件(稱爲MyBatis的全局配置文件,知道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>
<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://localhost3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
</environments>
</configuration>
(2)第二個配置文件(編寫每一個方法都如何向數據庫發送sql語句,如何執行,相當於接口的實現類):
將mapper標籤的namespaces屬性改爲接口的全類名;
<?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:名稱空間,寫接口的全類名,相當於告訴MyBatis是實現哪個接口 -->
<mapper namespace="com.test.dao.EmployeeDao">
<!-- public Employee getEmpById(Integer id); -->
<!-- select標籤用來定義一個查詢操作 ,
id:方法名,相當於這個配置是對於某個方法的實現
resultType:指定方法運行後的返回值類型,查詢操作必須指定的
#{屬性名}:代表取出傳遞過來的某個參數的值-->
<select id="getEmpById" resultType="com.test.bean.Employee">
select * from t_employee where id=#{id}
</mapper>
(3)寫的dao接口的實現文件,MyBatis默認是不知道的,需要在全局配置文件中註冊;
<!-- 引用我們自己編寫的每一個接口的實現文件 -->
<mappers>
<!-- resource:從類路徑下找資源 -->
<mapper resource="EmployeeDao.xml"/>
</mappers>
3)測試
package com.test.test;
import java.io.IOException;
import java.io.InputStream;
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 com.test.bean.Employee;
import com.test.dao.EmployeeDao;
public class MyBatisTest {
@Test
public void test() throws IOException {
//1.根據全局配置文件創建出一個SqlSessionFactory
//SqlSessionFactory是SqlSession工廠,負責創建SqlSession對象
//SqlSession:sql會話,代表和數據庫的一次會話
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFcatory=new SqlSessionFactoryBuilder().build(inputStream);
//2.獲取和數據庫的一次會話;getConnection()
SqlSession session=sqlSessionFcatory.openSession();
EmployeeDao empDao=null;
Employee em=null;
try{
//3.使用SqlSession操作數據庫,獲取到dao接口的實現
empDao= session.getMapper(EmployeeDao.class);
em= empDao.getEmpById(1);
}finally{
session.close();
}
System.out.println(em);
}
}
注意:
-
在上面的實驗時進行查詢操作,在mapper標籤中進行增刪改操作的時候,增刪改不用寫返回值類型,增刪改是返回影響多少行
mybatis自動判斷,如果是數字(int,long)。如果是boolean值,影響0行就自動封裝false
- 如果按照上面實驗測試方法執行,增刪改執行成功,但是在數據庫中數據並沒有操作成功,要自己設置手動提交。
session.commit();
細節:
1)獲取到的是接口的代理對象,MyBatis自動創建的
2)SqlSessionFactory創建SqlSession對象,工廠類只創建一次。SqlSession相當於connection和數據庫進行交互的,和數據庫的一次會話,就應該創建一個新的SqlSession