Mybatis詳細配置

1.Mybatis簡介
Mybatis是一個優秀的基於Java的持久層框架,它內部封裝了JDBC,是開發者只需關注SQL語句本身,而不用再花費精力去處理注入註冊驅動、創建Connection、配置Statement等繁雜過程。
Mybatis通過XML或註解的方式將要執行的各種statement(statement、preparedStatement等)配置起來,並通過,Java對象和Statement中的SQL的動態參數進行映射生成最終執行的SQL語句,最後由Mybatis框架執行SQL並將結果映射成Java對象並返回。

2.Mybatis與Hibernate
Hibernate框架是提供了全面的數據庫封裝機制的“全自動”ORM,即實現了POJO和數據庫表之間的映射,以及SQL的自動生成和執行。
相對於此,Mybatis只能算作是“半自動”ORM。其着力點,是在POJO類與SQL語句之間的映射關係。也就是說,Mybatis並不會爲程序員自動生成SQL語句。具體的SQL需要程序員自己編寫,然後通過SQL語句映射文件,將SQL所需的參數,以及返回的結果字段映射到指定POJO。因此,Mybatis成爲了“全自動”ORM的一種有益補充。
與Hibernate相比,Mybatis具有以下幾個特點:
(1)在XML文件中配置SQL語句,實現了SQL語句與代碼分離,給程序員的維護帶來了很大的便利。
(2)因爲需要程序員自己去編寫SQL語句,程序員可以結合數據庫自身的特點靈活控制SQL語句,因此能夠實現比Hibernate等全自動ORM框架更高的查詢效率,能夠完成複雜查詢。
(3)簡單,易於學習,易於使用,上手快。

3.Mybatis體系結構

在這裏插入圖片描述

4.Mybatis工作原理

在這裏插入圖片描述

5.Mybatis配置

5.1 jar下載
福利:jar包下載的好地址:https://mvnrepository.com/
(這個網站可以搜索下載jar包)
在這裏插入圖片描述
搜索mybatis–>點擊相應的出處–>點擊要下載的版本–>點擊圖片紅色處下載jar(就不用到處找和csdn積分下載了),下方還有maven的依賴等(十分好用,支持maven阿里雲)。
mysql的jar和log的jar都從這裏下載。

5.2 實體類和數據庫表設置。
// 實體類  數據庫中int類型id用Integer(方便傳參)
public class UserInfo {
	private Integer id;
	private String username; // 用戶名
	private String password; // 密碼
	private String realname; // 真實姓名
	private String sex;      // 性別
	private String address; // 住址
	private String question; // 問題設置
	private String answer; // 問題答案
	private String email; // 郵箱
	private String favorate; // 愛好
	private Integer score; // 成績
	private Date regdate; // 時間
	
	// 省略get和set
	// ...
}

// 數據庫
CREATE TABLE `user_info` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `userName` varchar(16) DEFAULT NULL,
  `password` varchar(16) DEFAULT NULL,
  `realName` varchar(8) DEFAULT NULL,
  `sex` varchar(4) DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  `question` varchar(50) DEFAULT NULL,
  `answer` varchar(50) DEFAULT NULL,
  `email` varchar(50) DEFAULT NULL,
  `favorate` varchar(50) DEFAULT NULL,
  `score` int(4) unsigned DEFAULT '0',
  `regDate` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

/*Data for the table `user_info` */

insert  into `user_info`(`id`,`userName`,`password`,`realName`,`sex`,`address`,`question`,`answer`,`email`,`favorate`,`score`,`regDate`) 
values (1,'tom','123456','湯姆','女','江蘇省蘇州市吳中區','您的出生地是','江蘇蘇州','[email protected]','電腦,手機,相機',0,'2013-07-14'),
(2,'john','123456','約翰','女','江蘇省南京市玄武區','您的出生地是?','江蘇南京','[email protected]','電腦,手機,',0,'2013-07-14'),
(3,'my','123456','my','男','江蘇省南京市玄武區','您的出生地是?','江蘇南京','[email protected]','電腦,手機,',0,'2015-09-16'),
(4,'sj','123456','sj','男','江蘇省南京市玄武區','您的出生地是?','江蘇南京','[email protected]','手機',0,'2015-09-16'),
(5,'lxf','123456','lxf','男','江蘇省南京市玄武區','您父親的生日是?','1950-1-1','[email protected]','手機',0,'2015-09-16'),
(6,'lj','123456','lj','男','江蘇省南京市玄武區','您母親的生日是?','1949-1-1','[email protected]','手機',0,'2015-09-20');
5.3 Dao與Mapper。
public interface UserInfoDao {
        // 查詢所有
	List<UserInfo> selectUserInfo(); 
}

<!-- 與UserInfoDao 對應的Mapper.xml ,文件名隨意,一般放在dao包中 -->
<?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.hsc.po.UserInfoDao">
	<select id="selectUserInfo" resultType="UserInfo">
	    select * from user_info
	</select>
</mapper>

mapper.xml中的配置裏邊:
namespace的作用用於區分命名空間中的同名SQL映射的id(一般開發使用所對應的Dao接口全路徑);
select屬性中的id:必須爲對應Dao接口中的方法名;
resultType爲查詢出來的結果類型。

5.4 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>
<!-- 加載屬性文件 必須在最前面 -->
	<properties resource="com/hsc/db.properties"></properties>
	<!--配置別名,就是上面mapper配置文件中resultType中的別名 -->
	<typeAliases>
		<package name="com.hsc.po"/>
	</typeAliases>
	
	<!-- default和id需要一致,不然會出現獲取session空指針異常 -->
	<environments default="jd">
		<environment id="jd">
		        <!-- 使用jdbc事務管理 -->
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}"/>
				<property name="url" value="${jdbc.url}"/>
				<property name="username" value="${jdbc.username}"/>
				<property name="password" value="${jdbc.password}"/>
			</dataSource>
		</environment>
	</environments>
	
	<mappers>
	   <!-- <package name="com.hsc.po"/> -->
	   <mapper resource="com/hsc/po/userinfomapper.xml"/>
	</mappers>
</configuration>

// db.properties,用的是mysql8,所以driver是如下
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/digital
jdbc.username=root
jdbc.password=****

主配置文件名可以隨意命名,主要完成以下幾個功能:

(1)註冊存放DB連接四要素的屬性文件
(2)註冊實體類的全限定性類名的別名
(3)配置Mybatis運行環境,即數據源與事務管理器
(4)註冊映射文件
在設置別名typeAliases時,除了自定義的類型的別名外,Mybatis還提供了內置的類型別名:
基本類型(所以前面實體類的id要用Integer):
在這裏插入圖片描述
常用包裝類型:
在這裏插入圖片描述

Mybatis的事務管理:JDBC、MANAGED
jdbc:使用jdbc的事務管理機制。即,通過Connection的commit()方法提交,通過rollback()方法回滾。但默認情況下,Mybatis將自動提交功能關閉了,改爲了手動提交。即程序中需要顯示的對事物進行提交和回滾。從日誌的的輸出信息中可以看到。
在這裏插入圖片描述
MANAGED:由容器來管理事務的整個生命週期(如Spring容器)。

dataSource標籤:

該標籤用於配置Mybatis使用的數據源類型與數據庫連接基本屬性。常見有類型有:UNPOOLED、POOLED、JDNI等。
UNPOOLED:不使用連接池。即每次請求,都會爲其創建一個DB連接,使用完畢後,會馬上將連接關閉。
POOLED:使用數據庫連接池來維護連接。
JNDI:數據源可以定義到應用的外部,通過JNDI容器獲取數據庫連接。

使用“<mapper class= ”指定映射文件時要注意的是:
(1)映射文件名(mapper.xml)要與Dao接口名稱相同
(2)映射文件要與接口在同一包中
(3)映射文件中“mapper”的namespace屬性值爲Dao接口的全類名(接口的全路徑)

一般可以使用package來指定包名來指定其包下多個mapper.xml;但需要滿足幾個條件:
(1)dao使用mapper動態代理實現(上面的配置就是)
(2)映射文件名要與Dao接口名稱相同
(3)映射文件要與接口在同一包中
(4)映射文件中mapper的namesapce屬性值爲dao接口的全類名

5.5 獲取SqlSession的工具類
public class SqlSessionUtil {
	
	private static SqlSessionFactory sessionFactory;
	
	public static SqlSession getSqlSession() {
		try {
		        // 流關閉了嗎??
			InputStream iStream = Resources.getResourceAsStream("com/hsc/mybatisconfig.xml");
			System.out.println(iStream.toString());
			if (sessionFactory == null) {
				sessionFactory = new SqlSessionFactoryBuilder().build(iStream);
			}
			return sessionFactory.openSession();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}

相關API詳解:
Dao中需要通過SqlSession對象來操作DB。而SqlSession對象的創建,需要其工廠對象SqlSessionFactory。SqlSessionFactory對象,需要通過其構建器對象SqlSessionFactoryBuilder的build()方法,在加載了主配置文件的輸入流對象後創建。

Resources類:
顧名思義就是資源,用於讀取資源文件。其有很多方法通過加載並解析資源文件,返回不同類型的IO流對象。
在這裏插入圖片描述

SqlSessionFactoryBuilder類:
SqlSessionFactory的創建,需要使用SqlSessionFactoryBuilder對象的build()方法。由於SqlSessionFactoryBuilder對象在創建完工廠對象後,就完成了其歷史使用,即可被銷燬。所以,一般會將該SqlSessionFactoryBuilder對象創建爲一個方法內的局部對象,方法結束,對象銷燬。其被重載的build()方法較多:
在這裏插入圖片描述

SqlSessionFactory接口:
SqlSessionfactory接口對象是一個重量級對象(系統開銷大的對象),是線程安全的,所以一個應用只需要一個該對象即可。創建SqlSession需要使用SqlSessionFactory接口的openSession()方法。
(1)openSession(true):創建一個有自動提交功能的SqlSession
(2)openSession(false):創建一個非自動提交功能的SqlSession,需要手動提交
(3)openSession():同openSession(false)

SqlSession接口:
SqlSession接口對象用於執行持久化操作。一個SqlSession對應着一次數據庫回話,一次回話以SqlSession對象的創建開始,以SqlSession對象的關閉結束。
SqlSession接口對象是線程不安全的,所以每次數據庫回話結束前,需要馬上調用其close()方法,將其關閉。再次需要回話,再次創建。而在關閉時會判斷當前的SqlSession是否被提交:若沒有被提交,則會執行回滾後關閉;若已提交,則直接將SqlSession關閉。所以,SqlSession無需手工回滾。

上面工具類裏邊提到了IO流關閉了嗎?
我們來看SqlSessionFactoryBuilder對象的build()方法會自動將輸入流關閉。
在這裏插入圖片描述

6 測試

public class Test{
    public SqlSession session;
	public UserInfoDao dao;
	
	@Before
	public void setProa() {
		session = SqlSessionUtil.getSqlSession();
		dao = session.getMapper(UserInfoDao.class);
	}
	
	@After
    public void close(){
        if (session != null) {
            session.close();
            session = null;
        }
    }
	
	@Test
	public void test02() {
		List<UserInfo> list = dao.selectUserInfo();
		System.out.println(list.size());
	}
}

運行結果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章