Mybatis --- 建立方法、全局配置

整體介紹:MyBatis其實是Ibatis3.0版本之後的持久化層 框架【也就是和數據庫打交道的框架】!
   
和數據庫打交道的技術有:
     原生的JDBC技術--->Spring的JdbcTemplate技術
     這些工具都是提供簡單的SQL語句的執行,可是和咱們這裏學的MyBatis框架還有些不一樣,
     框架是一整套的東西,例如事務控制,查詢緩存,字段映射等等。
    
咱們用原生JDBC操做數據庫的時候都會通過:
     編寫sql---->預編譯---->設置參數----->執行sql------->封裝結果
咱們之因此不使用原生的JDBC工具,是由於這些工具:
1.功能簡單,sql語句編寫在java代碼裏面【一旦修改sql,就須要將java及sql都要從新編譯!】這屬於硬編碼高耦合的方式。
2.咱們但願有開發人員本身編寫SQL語句,而且但願SQL語句與java代碼分離,將SQL語句編寫在xml配置文件中,實現數據表中記錄到對象之間的映射!
 
sql和java編碼分開,功能邊界清晰,一個專一於業務,一個專一於數據,可使用簡單的XML或註解用於配置和原始映射,將接口和Java的POJO映射成數據庫中的記錄,完成業務+底層數據庫的媒介!
         

1.MyBatis歷史
     原是Apache的一個開源項目iBatis,  2010年6月這 個項目由Apache Software Foundation 遷移
     到了 Google Code,隨着開發團隊轉投Google Code 旗下, iBatis3.x正式改名爲MyBatis ,代碼於 2013年11月遷移到Github(下載地址見後)。

     iBatis一詞來源於「internet」和「abatis」的組合,是 一個基於Java的持久層框架。
     iBatis提供的持久 層框架包括SQL  Maps和Data  Access  Objects、(DAO)

2.MyBatis簡介:
     MyBatis 是支持定製化 SQL、存儲過程以及高級 映射的優秀的持久層框架
     MyBatis 避免了幾乎全部的 JDBC 代碼和手動設置參數以及獲取結果集
     MyBatis可使用簡單的XML或註解用於配置和原 始映射,將接口和
     Java的POJO(Plain Old JavaObjects,普通的Java對象)映射成數據庫中的記錄.
       
       
3.爲何要使用MyBatis?
     MyBatis是一個半自動化的輕量級的持久化層框架。
    
     JDBC
          –     SQL夾在Java代碼塊裏,耦合度高致使硬編碼內傷
          –     維護不易且實際開發需求中sql是有變化,頻繁修改的狀況多見
    
     Hibernate和JPA
          –     長難複雜SQL,對於Hibernate而言處理也不容易
          –     內部自動生產的SQL,不容易作特殊優化。
          –     基於全映射的全自動框架,大量字段的POJO進行部分映射時比較困難。 致使數據庫性能降低。
         
     對開發人員而言,核心sql仍是須要本身優化
     sql和java編碼分開,功能邊界清晰,一個專一業務、 一個專一數據。
            
       
4.去哪裏找MyBatis?
     https://github.com/mybatis/mybatis-3/
     或者在百度直接搜索mybatis,而後找到github下的地址下載便可!

寫一個 MyBatis 的 HelloWorld:
 
- 建立數據庫及數據表並插入數據
    
- 建立一個動態WEB工程,而後建立與上述數據表對應的實體類
 
- [參考mybatis官方文檔]加入須要的jar包[mybatis所須要的jar包,和數據庫打交道的jar包,以及看打印日誌所須要的log4j的jar包]:
     1.log4j-1.2.17.jar    注意:log4j的jar包是須要log4j.xml文件的
     2.mybatis-3.4.1.jar 
     3.mysql-connector-java-5.1.37-bin.jar
    
- 建立 mybatis-config.xml 文件並將 mybatis 文檔中的內容複製過來,並將數據庫配置信息換成本身的:
    mybatis-config.xml 是總控制文件,EmployeeMapper.xml 是MyBatis的 sql映射文件,在裏面也 sql 語句
    全部的 sql映射文件都會寫到總控文件中
<!DOCTYPE configuration  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
"http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties resource="jdbc.properties"/> <environments default="development"> <environment id="development"> <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> <mapper resource="com/neuedu/mapper/EmployeeMapper.xml" /> </mappers> </configuration>

- 建立測試用例,.複製mybatis官方文檔代碼,代碼以下:java

public class TestMyBatis {
      @Test
      public void test() {
            String resource = "mybatis-config.xml";
            InputStream inputStream = null;
            try {
                  inputStream = Resources.getResourceAsStream(resource);//從配置文件中讀取一個流
            } catch (IOException e) {
                  e.printStackTrace();
            }
            //利用這個流建立一個sqlSessionFactory對象,也就是總控文件建立了這個對象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //和數據庫創建的一次會話,經過openSession,建立一個sqlsession對象
            SqlSession sqlsession = sqlSessionFactory.openSession();
            try {
                  //selectOne查詢一條記錄,第一個參數時sql語句的惟一標識,第二個參數時sql要用的參數
                  //爲了確保惟一標識惟一,因此在前面寫上namespace,由於namesapce惟一
                  //若是第二個參數"4"在數據庫中找不到的話,不會報錯,返回null
                  Object selectOne = sqlsession.selectOne("com.neuedu.MyBatis.EmployeeMapper.selectStudentById",4 );
                  System.out.println(selectOne);
            } finally {
                  sqlsession.close();
            }
      }
}

  - 建立sql語句的映射文件EmployeeMapper.xml;mysql

<mapper namespace="com.neuedu.MyBatis.EmployeeMapper">
<!--
      namespace:名稱空間,隨便起一個名,可是要惟一
      id:sql 語句的惟一標識
      #{id}:接收參數傳遞過來的id值
      resultType:將 sql語句返回成什麼對象
 -->
      <select id="selectStudentById" resultType="com.neuedu.entity.Employee">
            select * from student where id = #{id}
      </select>
</mapper>
 
總結:
– 建立一張測試表
– 建立對應的javaBean
– 建立mybatis配置文件,sql映射文件
– 測試
/**
 * 1.根據xml配置文件(全局配置文件)建立一個SqlSessionFactory對象
 *   有數據源的一些運行環境信息
 * 2.sql映射文件,配置了每個sql,以及sql的封裝規則等。
 * 3.將sql映射文件註冊在全局配置文件中
 * 4.寫代碼:
 *    1)根據全局配置文件獲得SqlSessionFactory
 *    2)使用sqlSession工廠,獲取到sqlSession對象使用它來執行增刪改查!
 *     sqlSession就是表明和數據庫的一次會話!用完要關閉!
 *    3)使用sql的惟一標識告訴MyBatis執行哪一個sql。而sql都是保存
 *      在sql映射文件中的。
 */
 
上面這種開發方式是老版本的Mybatis使用者的開發方式!而新一批的Mybatis使用者都是使用接口的方法

 

 HelloWorld----接口式編程 git

- 新建立一個 mapper包,裏面包含 mapper接口,與 mapper.xml文件相對應
public interface EmployeeMapper {
      /*
       * 增刪改查方法
       * */
      public Employee getEmployeeById(Integer id);

}

- 經過mapper.xml的 namespace 相關聯github

<mapper namespace="com.neuedu.mapper.EmployeeMapper">
<!--
      namespace:將sql映射文件和Mapper接口進行關聯
      id:要和相對應的mapper接口的方法名保持一致
      #{id}:從參數中獲取id
      resultType:將 sql語句返回成什麼對象
 -->

      <!-- public Employee getEmployeeById(Integer id); -->
      <select id="getEmployeeById" resultType="com.neuedu.entity.Employee">
            select * from student where id = #{id}
      </select>

</mapper>

- sqlSession 對象表示服務器和數據庫的一次會話,是一個非線程安全的,因此不能定義在類中,定義在類中,多線程的狀況下會有多個線程共用,一次使用獲取一次 ,保證時線程安全的spring

private SqlSessionFactory getSqlSessionFactory(){
     String resource = "mybatis-config.xml";
     InputStream inputStream = null;
     try {
           inputStream = Resources.getResourceAsStream(resource);//從配置文件中讀取一個流
     } catch (IOException e) {
           e.printStackTrace();
     }
     //利用這個流建立一個sqlSessionFactory對象
     SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

     return sqlSessionFactory;
}

 - 測試sql

@Test
public void test01(){
      //1.獲取sqlSessionFactory對象
      SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
      //2.利用sqlSessionFactory建立一個session對象,表示和數據庫的一次會話
      SqlSession session = sqlSessionFactory.openSession();
      //3.用session對象獲取mapper接口的代理對象
      //由於sql映射文件給相應的接口建立了一個代理對象,因此mapper接口類不須要實現類
      EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
      //經過mapper接口的代理對象就能夠對數據庫進行增刪改查操做
      Employee employee = mapper.getEmployeeById(4);
      System.out.println(employee);
      session.close();
}

 之前都是須要爲接口寫一個實現類,可是此時,mybatis提供了接口能夠與sql配置文件動態綁定!數據庫

如何將二者進行綁定?之前sql配置文件的namespace能夠隨便寫,如今就不能隨便寫了,須要指定爲接口的全限定名!
此時接口和sql配置文件作了綁定,還要將select標籤的id和方法名進行綁定
 
總結:
1.接口式編程
         原生:                  Dao  ==================>  DaoImpl
        mybatis:         xxMapper ================>  xxMapper.xml
2.SqlSession表明和數據庫的一次會話,用完必須關閉。
3.SqlSession和Connection同樣,都是非線程安全的,每次使用都是應該去獲取新的對象,不要將這個對象定義在類變量中使用!
4.mapper接口沒有實現類,可是mybatis這個接口生成一個代理對象
<!--將接口與xml文件進行綁定 -->
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
5.兩個重要的配置文件
- mybatis的全局配置文件( mybatis-config.xml):包含數據庫鏈接池信息,事務管理器信息等..系統運行環境信息。
- sql映射文件( EmployeeMapper.xml):保存了每個sql語句的映射信息。
 

Mybatis的全局配置文件
 
MyBatis 的配置文件包含了影響 MyBatis 行爲甚深的設置(settings)和屬性(properties)信息。文檔的頂層結構順序以下:
- configuration 配置
- properties 屬性:加載properties文件
- settings 設置
- typeAliases 類型命名
- typeHandlers 類型處理器
- objectFactory 對象工廠
- plugins 插件
- environments 環境
- environment 環境變量
- transactionManager 事務管理器
- dataSource 數據源
- databaseIdProvider 數據庫廠商標識
- mappers 映射器
 
dtd文檔規定了以上順序不能變
 
具體介紹:
1.configuration 爲全局配置文件綁定dtd約束:
     1)聯網會自動綁定
     2)沒網的時候【/org/apache/ibatis/builder/xml/mybatis-3-config.dtd】:解壓mybatis 的jar包而後在eclipse中綁定
     Window-->Preference-->XML-->XML Catalog
 
2. properties屬性
<configuration>
     <!--
          mybatis可使用properties來引入外部properties配置文件的內容
          resource:引入類路徑下的資源
          url:引入網絡路徑或者磁盤路徑下的資源
     -->
     <properties resource="jdbc.properties"></properties>
          <environments default="development">
               <environment id="development">
                     <transactionManager type="JDBC"/>
                     <dataSource type="POOLED">
                          <property name="driver" value="${jdbc.driver}"/>
                          <property name="url" value="${jdbc.url}"/>
                          <property name="username" value="${jdbc.user}"/>
                           <property name="password" value="${jdbc.passowrd}"/>
                     </dataSource>
               </environment>
          </environments>
          <!-- 將咱們寫好的sql映射文件必定要註冊到全局配置文件中,文件用/,類用.,也就是若是是class就用.分隔 -->
          <mappers>
                <mapper resource="EmployeeMapper.xml"/>
          </mappers>
</configuration>
 
3.settings包含不少重要的設置項
    setting:用來設置每個設置
    - name:設置屬性名
    - value:設置屬性值
<!-- settings標籤能夠設置多個屬性值 -->
<settings>
      <!-- setting標籤負責每個屬性的設置 -->
      <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
    - mapUnderscoreToCamelCase 能夠將數據庫中帶下劃線的名稱,與類中駝峯式命名的名稱對應起來
      好比,在數據庫中名稱爲 user_name,在實體類中名稱爲userName,value值是true的話,也能夠對應上
 
4.typeAliases:起別名
<!-- typeAliases能夠爲多個類起別名 -->
<typeAliases>
      <!-- 別名處理器,能夠爲某個java類型設置別名
      默認是該類名的首字母小寫,別名不區分大小寫
      alias:能夠經過該屬性單獨指定別名-->
      <!-- <typeAlias type="com.neuedu.entity.Employee" alias="asd"/> -->
      <!-- 用package能夠批量爲類起別名 -->
      <!-- 批量起別名的狀況下,使用@Alias註解爲某個實體類指定新的別名 -->
      <package name="com.neuedu.entity"/>
</typeAliases>

雖然有這麼多的別名可使用:可是建議仍是使用全類名,看SQL語句是怎麼被封裝爲JAVA 對象的時候簡單!apache

 

5.typeHandlers:類型處理器
       類型處理器:負責如何將數據庫的類型和java對象類型之間轉換的工具類
 
6.environments:環境們
<!--
    environments:環境們,mybatis能夠配置多種環境,default指定使用某種環境。能夠達到快速切換環境。
    environment:配置一個具體的環境信息;必須有兩個標籤;id表明當前環境的惟一標識
    transactionManager:事務管理器
    type:事務管理器的類型;type="[JDBC|MANAGED]"),這兩個都是別名,在Configuration類中能夠查看具體類!可是Spring對事務的控制纔是最終的管理方案!
         固然也能夠自定義事務管理器:只須要和人家同樣實現TransactionFactory接口,type指定爲全類名。
    dataSource:數據源
    type:type="[UNPOOLED|POOLED|JNDI]"
    自定義數據源:實現DataSourceFactory接口,type也是全類名

    可是咱們也說了,不管是事務管理器的配置仍是數據源的配置咱們都會使用spring來作,這裏只須要了解一下便可!
    -->
<environments default="development">
      <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                    <property name="driver" value="${jdbc.driver}"/>
                    <property name="url" value="${jdbc.url}"/>
                    <property name="username" value="${jdbc.user}"/>
                    <property name="password" value="${jdbc.passowrd}"/>
             </dataSource>
       </environment>
       <environment id="development">
             <transactionManager type="JDBC"/>
             <dataSource type="POOLED">
                    <property name="driver" value="${jdbc.driver}"/>
                    <property name="url" value="${jdbc.url}"/>
                    <property name="username" value="${jdbc.user}"/>
                    <property name="password" value="${jdbc.passowrd}"/>
             </dataSource>
        </environment>
</environments>

 

7.databaseIdProvider環境
   MyBatis 能夠根據不一樣的數據庫廠商執行不一樣的語句
<databaseIdProvider type="DB_VENDOR">
      <property name="SQL Server" value="sqlserver"/>
      <property name="DB2" value="db2"/>
      <property name="Oracle" value="oracle"/>
      <property name="MySQL" value="mysql"/>
</databaseIdProvider>
Type: DB_VENDOR
– 使用MyBatis提供的VendorDatabaseIdProvider解析數據庫 廠商標識。也能夠實現DatabaseIdProvider接口來自定義。
  Property-name:數據庫廠商標識
  Property-value:爲標識起一個別名,方便SQL語句使用
 
在mybatis的全局配置文件配置了這個以後,咱們只須要在sql映射文件中經過在執行語句的標籤上加一個屬性 databaseId便可!
databaseId 與 value 值對應
<select id="getEmployeeById" resultType="emp">
       select * from tbl_employee where id = #{id}
</select>
<select id="getEmployeeById" resultType="emp" databaseId="mysql">
       select * from tbl_employee where id = #{id}
</select>
<select id="getEmployeeById" resultType="emp" databaseId="oracle">
       select * from tbl_employee where id = #{id}
</select>
這樣在執行不一樣數據庫的時候,就會執行不一樣數據庫的語句了
固然如上所示:當有指定了databaseId屬性的和沒有指定databaseId屬性的,都有的狀況下那就按着有指定databaseId屬性的sql語句執行!
<environments default="development">
      <environment id="development">
            <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>

      <environment id="dev_oracle">
            <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>

 

8.mapper映射編程

<!-- mappers:將sql映射註冊到全局配置中 -->
     <mappers>
     <!-- mapper:註冊一個sql映射
          註冊配置文件:
               resource:引用類路徑下的sql映射文件  mybatis/mapper/EmployeeMapper.xml
               url:引用網絡路徑下或者磁盤路徑下的sql映射文件  url="file:///var/mappers/AuthorMapper.xml"

          註冊接口
               class:引用(註冊)接口:
                    1.有sql映射文件,映射文件名必須和接口同名,而且放在與接口同一個目錄下(能夠在conf下見一個同名的包,放在裏面);
                    2.沒有sql映射文件,全部的sql都是利用註解寫在接口方法上;
                    推薦:
                        比較重要的,複雜的Dao接口咱們來寫sql映射文件
                        不重要,見到的Dao接口爲了開發快速可使用註解
      -->
      <!-- <mapper class="com.neuedu.mapper.EmployeeMapper"/> -->
     <mapper resource="com/neuedu/mapper/EmployeeMapper.xml"/>
      <!-- 批量註冊:
           對於sql 映射文件和接口須要保證在同一個包下,且名字必須相同 -->
      <package name="com.neuedu.mapper"/>
</mappers>
class:當映射文件和接口文件不在同一目錄下時,用註解
可是不建議使用註解,建議使用sql映射文件
public interface EmployeeMapper {
      /*
       * 增刪改查方法
       * */
      @Select("select * from student where id = #{id}")
      public Employee getEmployeeById(Integer id);

}

 

9.最後就是全局配置文件中標籤其實是有順序的!
    
使用自定義的數據源
- 導包:C3P0
- 新建類繼承 UnpooledDataSourceFactory
- 提供無參構造器,並將 dataSource屬性設置成想要鏈接的數據庫鏈接池
public class C3P0DateSource extends UnpooledDataSourceFactory{

      public C3P0DateSource() {
            this.dataSource = new ComboPooledDataSource();
      }
}
- 在總控文件 mybatis-config.xml 中修改 dataSource 路徑
   將 property 中的 name 換作 C3P0 中的寫法
<environments default="development">
      <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="com.neuedu.datasource.C3P0DateSource">
                  <property name="driverClass" value="${jdbc.driver}" />
                  <property name="jdbcUrl" value="${jdbc.url}" />
                  <property name="user" value="${jdbc.username}" />
                  <property name="password" value="${jdbc.password}" />
            </dataSource>
      </environment>
</environments>
相關文章
相關標籤/搜索