初識框架之MyBatis
一、什麼是框架
1)傳統 的JDBC程式設計
JDBC作為Java語言連線資料庫的一個重要的技能點,不可否認的是在一個程式中,如果我們需要多次進行與資料庫的互動,那我們所需要的重複操作就就會有很多:
1.載入資料庫驅動
2.獲取資料庫連線(Connection),獲取Statement物件
3.使用Statement操作sql語句
4.如果是查詢的話還需要獲取一個ResultSet物件,並進行處理才能獲取到查詢的資訊
5.關閉資料庫連線
而且每次進行資料庫互動,都需要進行一次類似與以上5個步驟的操作,這樣就會對我們的工作量提升了許多,而且還是沒有必要的。除此之外,我們還需要對以上操作不斷地進行異常的捕捉,在我們工作的專案一般都很複雜,那麼,這些操作是不是可以交給一個類似與第三方的工具進行處理,那我們的工作量不久會減輕好多嗎?
2)持久化與ORM
1.持久化:持久化就是字面上的意思,很好理解,就是要資料以檔案的形式,或者資料庫等等方式永久的儲存就是所謂的持久化。
比較官方的解釋就是:是程式資料在瞬時狀態和持久狀態之間轉換的過程被稱之為持久化。讓物件的生存期超越使用物件的程式的執行期。(瞬時狀態就是記憶體中的資料)
2.ORM(Object Relational Mapping):
編寫程式時,與面向物件的方式處理資料(物件)
儲存資料時,以關係型資料庫方式儲存資料(表)
3)框架的含義與好處:(比如我們在寫簡歷的時候通常都會上網找一些模板來寫,這時候我們就不需要考錄簡歷的排版問題了,我們只需要把其中的內容填寫好。使用框架的原因就類似與它)
- 是一個應用程式的半成品。
- 提供可重用的公共結構。
- 按一定規則組織的一組元件
- 不用再考慮公共性的問題
- 專心在業務實現上
- 結構統一,易於學習,維護
- 新手也可以寫出好程式
二、MyBatis
1)MyBatis的構成
1.SqlSessionFactoryBuilder
SqlSessionFactoryBuilder是利用XML或者Java編碼獲得資源來構建SqlSessionFactory 的,通過它可以構建多個SessionFactory。它的作用僅僅是一個構建器而已,一旦我們構建了SessionFactory,那麼它將毫無意義,應立即回收!
2.SqlSessoinFactory
SqlSessionFactory的作用是建立SqlSession,而SqlSession相當於一個會話,相當於JDBC中的connection物件,每次應用程式需要訪問資料庫,我們就要通SqlSessionFactory建立SqlSession,所以SqlSessionFactory應該在整個應用的生命週期中。而如果我們多次建立同一個資料庫的SqlSessionFactory,則每次建立的SqlSessionFactory會開啟更多的資料庫連線資源,那麼連線資源很開會被耗盡,因此SqlSessionFactory的職責是唯一的。果斷的採取單例模式,在應用中使用同一個SqlSessionFactory對象即可
3.SqlSession
SqlSession是一個會話,相當於JDBC中的一個Connection物件,它的生命週期應該是在請求資料庫處理事務的過程中,且SqlSession是執行緒非安全的物件,涉及多執行緒時要特別的當心,每次建立的SqlSession物件都要及時的關閉它,它長期存在就會使資料庫連線池的活動資源減少,對系統性能影響很大
2)使用MyBatis做簡單的資料庫增刪改查
1.匯入jar包(https://github.com/mybatis/mybatis-3/releases)
以上時官方下載地址,jar包的就匯入方式在這裡就不做介紹了(每個開發工具都有所不同)
如果是使用idea的話也可以匯入pom節點(https://mvnrepository.com/artifact/org.mybatis/mybatis)
除了以上的MyBatis所依賴的包之外我們還需要匯入JDBC的jar包或者pom,這些都可以在官方或者maven倉庫中找到
2.建立表結構
3.準備resources目錄
1>database.properties檔案(不會的就上網找一下,就是幾個資料連線引數)
2>configuration.xml檔案(名字隨便不是固定的,但是必須是xml檔案)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!-- xml檔案的標頭檔案,起到對檔案的約束作用(例如:必須存在哪些節點) --> 3 <!DOCTYPE configuration 4 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 5 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 6 <configuration> 7 <!--指向配置檔案--> 8 <properties resource="database.properties"></properties> 9 <!--宣告別名--> 10 <typeAliases> 11 <!--第一種方法--> 12 <!--<typeAlias type="com.cn.Dao.類名" alias="Monkey"></typeAlias>--> 13 <!--第二種方法,這玩意好用,別名就是其類名--> 14 <package name="com.cn.entity"></package> 15 </typeAliases> 16 <environments default="development"> 17 <environment id="development"> 18 <!--事務管理器:type JDBC or UNSIGNED(託管)--> 19 <transactionManager type="JDBC"></transactionManager> 20 <!--資料來源:type jndi pooled unpooled--> 21 <dataSource type="POOLED"> 22 <!--連線資料庫的4個連線引數--> 23 <property name="driver" value="${driver}"></property> 24 <property name="url" value="${url}"></property> 25 <property name="username" value="${username}"></property> 26 <property name="password" value="${password}"></property> 27 </dataSource> 28 </environment> 29 </environments> 30 <!--指向小配置檔案xml--> 31 <mappers> 32 <package name="com.cn.Dao"></package> 33 </mappers> 34 </configuration>
4.設定掃描路徑+database.properties
以上程式碼中有一個節點<mappers>中指定了一個相對路徑,不難發現,這裡是指定了xml的路徑。但是有一定經驗的會發現,idea中xml檔案不是不可以在java目錄下嗎?當然,預設情況下是不可以的,即便是你放到了java目錄下也不會被識別,更不要說說是使用了。但是上帝在把一扇門關上的同時自然也會給你開啟一扇窗的。只需要在pom.xml檔案中加入著呢一個接單就可以了
1 <build> 2 <resources> 3 <resource> 4 <directory>src/main/java</directory> 5 <includes> 6 <include>**/*.xml</include> 7 </includes> 8 </resource> 9 </resources> 10 </build>
其中resource的節點就是祈禱這個作用的,resource節點是位於<build>節點下的,把<resource>節點放到該節點下就行了
5.生成實體類(這個就不用多說了把)
6.建立dao層的介面,並且宣告相對應的方法
7.生成mapper對映檔案,起名與介面對應(UserDao.xml)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 <!--namespace:該屬性值為本配置檔案所指向的介面的相對路徑--> 6 <mapper namespace="com.cn.Dao.UserDao"> 7 <!--增加語句--> 8 <insert id="addUser" parameterType="User"><!--這裡id為介面中的方法名,parameterType入參的型別(設定了configuration.xml中的別名這裡就是該別名了,否則就是全類名)--> 9 insert into user values(default ,#{name},#{pwd})/*如果介面的入參是物件,那麼這裡的name和pwd就是物件中的屬性名*/ 10 </insert> 11 <!--修改語句--> 12 <update id="updateUser" parameterType="User"> 13 update user set name=#{name},pwd=#{pwd} where id=#{id} 14 </update> 15 <!--刪除語句--> 16 <delete id="delUser" parameterType="int"> 17 delete from user where id=#{id}/*如果介面的入參是基本型別,那麼這裡的id就是其變數名*/ 18 </delete> 19 <!--查詢語句--> 20 <select id="getUser" parameterType="int" resultType="User">/*resultType是返回值的型別*/ 21 select * from user where id=#{id} 22 </select> 23 </mapper>
8.建立工廠
1 package com.cn.util; 2 3 import org.apache.ibatis.session.SqlSessionFactory; 4 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 5 6 import java.io.InputStream; 7 8 public class SqlSessionUtil { 9 private static SqlSessionFactory factory; 10 public static SqlSessionFactory getFactory(){ 11 if (factory==null){ 12 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); 13 //將配置檔案configuration.xml,也就是最外層的配置Mybatis的xml檔案放轉換成流 14 InputStream is = SqlSessionUtil.class.getResourceAsStream("/configuration.xml"); 15 //獲取工廠 16 factory = builder.build(is); 17 } 18 return factory; 19 } 20 }
上邊介紹中說過對於同一個資料庫我們只需要一個工廠就可以了,所以在這裡我們選擇是使用單例模式
9.基於我們初步使用MyBatis,在這裡我們還要建立介面的實現類來完成測試
package com.cn.Dao; import com.cn.entity.User; import com.cn.util.SqlSessionUtil; import org.apache.ibatis.session.SqlSession; public class UserDaoImpl implements UserDao { @Override public void addUser(User user) { //獲取會話(SqlSessoin)物件 SqlSession session = SqlSessionUtil.getFactory().openSession(); try { //把入參傳入該會話的insert房中,其中“addUser為介面中的方法名,也就是小配置檔案中的id屬性” session.insert("addUser", user); //提交事務 session.commit(); } catch (Exception e) { //如果發生異常,回滾事務 session.rollback(); } finally { //最後必須要把此次會話關閉 session.close(); } } @Override public void delUser(int id) { SqlSession session = SqlSessionUtil.getFactory().openSession(); try { session.delete("delUser", id); session.commit(); } catch (Exception e) { session.rollback(); } finally { session.close(); } } @Override public void updateUser(User user) { SqlSession session = SqlSessionUtil.getFactory().openSession(); try { session.update("updateUser", user); session.commit(); } catch (Exception e) { session.rollback(); } finally { session.close(); } } @Override public User getUser(int id) { SqlSession session = SqlSessionUtil.getFactory().openSession(); try { User getUser = (User)session.selectOne("getUser", id); session.commit(); return getUser; } catch (Exception e) { session.rollback(); } finally { session.close(); } return null; } }
10.編寫測試方法
package com.cn.text; import com.cn.Dao.UserDao; import com.cn.Dao.UserDaoImpl; import com.cn.entity.User; import org.junit.Test; public class TextMybatis { UserDao ud= new UserDaoImpl(); @Test public void test1(){ User user=new User(-1,"sjdf","123"); ud.addUser(user); } @Test public void test2(){ User user=new User(1,"山間的風","789132"); ud.updateUser(user); } @Test public void test3(){ ud.delUser(1); } @Test public void test4(){ User user = ud.getUser(1); System.out.println(user.toString()); } }
這裡我使用junit單元測試,其中增刪改大家自行測試