1. 程式人生 > >初識框架之MyBatis

初識框架之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單元測試,其中增刪改大家自行測試