MyBatis框架知識整理

MyBatis框架

1、介紹:

MyBatis其實是Ibatis3.0版本之後的持久化層框架【也就是和數據庫打交道的框架】!   java

和數據庫打交道的技術有:mysql

    原生的JDBC技術---> SpringJdbcTemplate技術git

這些工具都是提供簡單的SQL語句的執行,可是和咱們這裏學的MyBatis框架還有些不一樣,框架是一整套的東西,例如事務控制,查詢緩存,字段映射等等。github

 

咱們用原生JDBC操做數據庫的時候都會通過:spring

 編寫sql---->預編譯---->設置參數----->執行sql------->封裝結果sql

 

咱們之因此不使用原生的JDBC工具,是由於這些工具:數據庫

  1.功能簡單,sql語句編寫在java代碼裏面【一旦修改sql,就須要將javasql都要從新編譯!】這屬於硬編碼高耦合的方式。apache

  2.咱們但願有開發人員本身編寫SQL語句,編程

    而且但願SQL語句與java代碼分離,緩存

 將SQL語句編寫在xml配置文件中,

 實現數據表中記錄到對象之間的映射!

 

sqljava編碼分開,功能邊界清晰,一個專一於業務,一個專一於數據,可使用簡單的XML或註解用於配置和原始映射,將接口和JavaPOJO映射成數據庫中的記錄,完成業務+底層數據庫的媒介!

 

2、Mybatis詳解

1.MyBatis歷史

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

iBatis一詞來源於「internet」和「abatis」的組合,是 一個基於Java的持久層框架。

iBatis提供的持久層框架包括SQL  MapsData  Access  Objects、(DAO

 

2.MyBatis簡介:

MyBatis 是支持定製化 SQL、存儲過程以及高級映射的優秀的持久層框架。

MyBatis 避免了幾乎全部的 JDBC 代碼和手動設置參數以及獲取結果集。

MyBatis可使用簡單的XML或註解用於配置和原始映射,將接口和JavaPOJOPlain Old JavaObjects,普通的Java對象)映射成數據庫中的記錄.

   

3.爲何要使用MyBatis

MyBatis是一個半自動化的輕量級的持久化層框架。

JDBC

– SQL夾在Java代碼塊裏,耦合度高致使硬編碼內傷

維護不易且實際開發需求中sql是有變化,頻繁修改的狀況多見

 

HibernateJPA

長難複雜SQL,對於Hibernate而言處理也不容易

內部自動生產的SQL,不容易作特殊優化。

基於全映射的全自動框架,大量字段的POJO進行部分映射時比較困難。 致使數據庫性能降低。

 

對開發人員而言,核心sql仍是須要本身優化,sqljava編碼分開,功能邊界清晰,一個專一業務、 一個專一數據。

   

4.去哪裏找MyBatis

https://github.com/mybatis/mybatis-3/

或者在百度直接搜索mybatis,而後找到github下的地址下載便可!

 

5.快速寫一個MyBatisHelloWorld

(1).建立數據庫及數據表

CREATE DATABASE mytabis;

CREATE TABLE tbl_employee(

  id INT(11) PRIMARY KEY AUTO_INCREMENT,
  last_name VARCHAR(255),
  gender CHAR(1),
  email VARCHAR(255)

)

   而後插入兩條數據;

 

(2).建立一個動態WEB工程,而後建立與上述數據表對應的實體類:

(3).[參考mybatis官方文檔]加入須要的jar[mybatis所須要的jar包,和數據庫打交道的jar包,以及看打印日誌所須要的log4jjar]

log4j-1.2.17.jar  //固然須要注意的是:log4jjar包是須要log4j.xml文件的

mybatis-3.4.1.jar  

mysql-connector-java-5.1.37-bin.jar 

 

(4).建立mytabis-config.xml文件並將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://localhost:3306/mytabis"/>         <property name="username" value="root"/>         <property name="password" value="123456"/>       </dataSource>     </environment>   </environments>      <!-- 將咱們寫好的sql映射文件必定要註冊到全局配置文件中 -->   <mappers>     <mapper resource="EmployeeMapper.xml"/>   </mappers> </configuration>

  

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

public class MyBatisTest {

@Test
public void test() throws IOException {
//加載配置文件,將配置文件以流的形式傳入
String resource = "mytabis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//獲取SqlSessionFactory實例
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSession sqlSession =null;

try{

    //2.獲取sqlSession實例,能直接執行已經映射的SQL語句
    sqlSession= sqlSessionFactory.openSession();
    //須要兩個參數,第一個參數是sql語句的惟一標識,
    //第二個參數是執行sql要用的參數
    Employee employee =  sqlSession.selectOne("com.neuedu.mybatis.EmployeeMapper.selectEmp",1);

    System.out.println(employee);

}catch(Exception e){


}finally{

sqlSession.close();

}
}
}

  

 (6). 建立sql語句的映射文件EmployeeMapper.xml

<?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.neuedu.mybatis.EmployeeMapper">
 <!--

namespace:名稱空間

id:sql語句的惟一標識

resultType:返回值類型

#{id}:接收參數傳遞過來的id值

  -->

<select id="selectEmp" resultType="com.neuedu.mybatis.bean.Employee">
  select id,last_name lastName,gender,email from tbl_employee where id = #{id}
</select>

</mapper>

  

 (7).總結:

HelloWorld簡單版

– 建立一張測試表

–建立對應的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使用者都是使用接口的方式,以下所示:

 

(8).HelloWorld-接口式編程

– 建立一個Dao接口

– 修改Mapper文件

– 測試

 

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

 那如何將二者進行綁定呢?之前sql配置文件的namespace能夠隨便寫,如今就不能隨便寫了,需呀指定爲接口的全限定名!

 而後此時接口和sql配置文件作了綁定,而後還要將select標籤的id和方法名進行綁定,

 

總結:

 1.接口式編程

原生:           Dao  ==================>  DaoImpl

mybatis:         Mapper ================>  xxMapper.xml

2.SqlSession表明和數據庫的一次會話,用完必須關閉。
3.SqlSessionConnection同樣,都是非線程安全的,每次使用都是應該去獲取新的對象,不要將這個對象定義在類變量中使用!
4.mapper接口沒有實現類,可是mybatis這個接口生成一個代理對象
<!--將接口與xml文件進行綁定 -->
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
5.兩個重要的配置文件

   mybatis的全局配置文件:包含數據庫鏈接池信息,事務管理器信息等..系統運行環境信息。

   sql映射文件:保存了每個sql語句的映射信息。

 

3、MyBatis-全局配置文件

MyBatis 的配置文件包含了影響 MyBatis 行爲甚深的設置(settings)和屬性(properties)信息。文檔的頂層結構以下:

 

configuration 配置

properties 屬性

settings 設置

typeAliases 類型命名

typeHandlers 類型處理器

objectFactory 對象工廠

plugins 插件

environments 環境

environment 環境變量

transactionManager 事務管理器

dataSource 數據源

databaseIdProvider 數據庫廠商標識

mappers 映射器

 

  1.爲全局配置文件綁定dtd約束:

 1)聯網會自動綁定

 2)沒網的時候【/org/apache/ibatis/builder/xml/mybatis-3-config.dtd】:解壓mybatis jar包而後在eclipse中綁定

 

  2. properties屬性

  <configuration>

<!--

1.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映射文件必定要註冊到全局配置文件中 -->
  <mappers>
    <mapper resource="EmployeeMapper.xml"/>
  </mappers>

</configuration>

  

 

3.settings包含不少重要的設置項

setting:用來設置每個設置

name:設置項名

value:設置項取值

 

舉例:駝峯式命名

<settings>
      <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

 

4.typeAliases

做用:A type alias is simply a shorter name for a Java type

<!-- typeAliases:別名處理器,能夠爲咱們的java類型起別名,別名不區分大小寫 -->
<typeAliases>

<!-- typeAlias:爲某個java類型起別名
type:指定要起別名的類型全類名;默認別名就是類名小寫;
alias:執行新的別名
-->
<typeAlias type="com.neuedu.mybatis.bean.Employee"/>

<!--
package:爲某個包下的全部類批量起別名
name:指定包名(爲當前包以及下面全部的後代包的每個類都起一個默認別名【類名小寫】)
 -->
<package name="com.neuedu.mybatis.bean"/>

<!-- 批量起別名的狀況下,使用@Alias註解爲某個類型指定新的別名 -->
</typeAliases>

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

 

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 is able to execute different statements depending on your database vendor. The

MyBatis 能夠根據不一樣的數據庫廠商執行不一樣的語句

<databaseIdProvider type="DB_VENDOR">

<property name="SQL Server" value="sqlserver"/>

<property name="DB2" value="db2"/>

<property name="Oracle" value="" />

</databaseIdProvider>

 

TypeDB_VENDOR

–使用MyBatis提供的VendorDatabaseIdProvider解析數據庫 廠商標識。也能夠實現DatabaseIdProvider接口來自定義。

Property-name:數據庫廠商標識

Property-value:爲標識起一個別名,方便SQL語句使用

 

  mybatis的全局配置文件配置了這個以後,咱們只須要在sql映射文件中經過在執行語句的標籤上加一個屬性databaseId便可!

<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="dev_mysql">
  <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.user}"/>
      <property name="password" value="${jdbc.passowrd}"/>
    </dataSource>
  </environment>
  <environment id="dev_mysql">
    <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>

 

 8.mapper映射

<!-- mappers:將sql映射註冊到全局配置中 -->
<mappers>

<!-- mapper:註冊一個sql映射

 註冊配置文件:

 resource:引用類路徑下的sql映射文件

 mybatis/mapper/EmployeeMapper.xml

 url:引用網絡路徑下或者磁盤路徑下的sql映射文件

 url="file:///var/mappers/AuthorMapper.xml"

 

   註冊接口

  class:引用(註冊)接口

  1.有sql映射文件,映射文件名必須和接口同名,而且放在與接口同一個目錄下;

  2.沒有sql映射文件,全部的sql都是利用註解寫在接口上;

推薦:

    比較重要的,複雜的Dao接口咱們來寫sql映射文件

    不重要,見到的Dao接口爲了開發快速可使用註解

 -->

    <mapper resource="mybatis/mapper/EmployeeMapper.xml"/>

    <mapper class="com.neuedu.mybatis.mapper.EmployeeMapperAnnotation"/>

<!-- 批量註冊:

 1.註解版確定是沒問題的

 2.可是對於Mapper.xml映射文件和接口分開的,就須要保證在同一個包下且文件名相同了,不然找不到 -->

    <package name="com.neuedu.mybatis.mapper"/>

</mappers>

 

9.最後就是全局配置文件中標籤其實是有順序的!

 

4、MyBatis-映射文件

映射文件指導着MyBatis如何進行數據庫增刪改查, 有着很是重要的意義;

 

cache –命名空間的二級緩存配置

cache-ref – 其餘命名空間緩存配置的引用。

resultMap  –  自定義結果集映射

parameterMap – 已廢棄!老式風格的參數映射

sql  –抽取可重用語句塊。

insert – 映射插入語句

update – 映射更新語句

delete – 映射刪除語句

select – 映射查詢語句

 

1.先看增刪改查標籤

  接口類:

 public interface EmployeeMapper {

    public Employee getEmployeeById(Integer id);

    public void addEmp(Employee employee);

    public void updateEmp(Employee employee);

    public void deleteEmp(Integer id);

 }

  在其對應的sql映射文件中:   

<!--parameterType:能夠省略  ,且該sql語句最後不用寫分號-->
<insert id="addEmp" parameterType="com.neuedu.mybatis.bean.Employee">
  insert into tbl_employee(last_name,email,gender)
  values(#{lastName},#{gender},#{email})
</insert>

<!-- public void updateEmp(Employee employee); -->
<update id="updateEmp">
  update tbl_employee
  set last_name=#{lastName},email=#{email},gender=#{gender}
  where id = #{id}
</update>

<!-- public void deleteEmp(Integer id); -->
<delete id="deleteEmp">
  delete from tbl_employee where id = #{id}
</delete>

編寫測試單元:

/**

 * 測試增刪改

 * 1.mybatis容許增刪改直接定義如下類型返回值

 *   Integer、Long、Boolean

 *   增刪改返回的是影響的多少行,只要影響0行以上就會返回true,0行如下就會返回false!

 *   直接在接口上寫這些包裝類或者基本類型就好,

 *   不必在sql映射文件中寫resultType,並且在sql映射文件中也沒有resultType標籤!

 * 2.咱們須要手動提交數據

    *sqlSessionFactory.openSession();===>手動提交

  *sqlSessionFactory.openSession(true);===>自動提交

 */

@Test
public void test02() {

String resource = "mytabis-config.xml";

InputStream inputStream;

SqlSession openSession = null;

try {

inputStream = Resources.getResourceAsStream(resource);

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

//1.獲取到的sqlSession不會自動提交數據,須要手動提交
openSession = sqlSessionFactory.openSession();

EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);

mapper.addEmp(new Employee(null,"hah","email","1"));

//手動提交
openSession.commit();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}finally{

//關閉會話

openSession.close();

}
}

 

2.獲取自增主鍵值

<!--parameterType:能夠省略  ,且該sql語句最後不用寫分號;

獲取自增主鍵的值:

   mysql支持自增主鍵:自增主鍵值的獲取,mybatis也是利用statement.getGeneratedKeys()

   useGeneratedKeys = "true";使用自增主鍵獲取主鍵值策略

   keyProperty:指定對應的主鍵屬性,也就是mybatis獲取到主鍵值之後,將

 這個值封裝給javaBean的哪一個屬性

-->

<insert id="addEmp" parameterType="com.neuedu.mybatis.bean.Employee"
   useGeneratedKeys="true" keyProperty="id">
  insert into tbl_employee(last_name,email,gender)
  values(#{lastName},#{gender},#{email})
</insert>

 

五:參數處理

   單個參數:mybatis不會作特殊處理

         #{參數名}: 取出參數值

 

   多個參數:mybatis會作特殊處理

         多個參數會被封裝成一個map

  key:param1...paramN,或者參數的索引也能夠

  value:傳入的參數值

  #{}就是從map中獲取指定的key的值

  

  異常:

org.apache.ibatis.binding.BingdingException:

Parameter 'id' not found.

Available parameters are [1,0,param1,param2]

  操做:

   方法:public Employee getEmployeeAndLastName(Integer id,String lastName);

   取值:#{id},#{lastName}

   

命名參數:明確指定封裝參數時mapkey:@param("id")

       多個參數會被封裝成一個map,

        key:使用@Param註解指定的值

value:參數值

#{指定的key}取出對應的參數值

 

POJO:

   若是多個參數正好是咱們業務邏輯的數據模型,咱們就能夠直接傳入pojo;

    #{屬性名}:取出傳入的pojo的屬性值

 

Map:

   若是多個參數不是業務模型中的數據,沒有對應的pojo,不常用,爲了方便,咱們也能夠傳入map

    #{key}:取出map中對應的值

    

ListSet

   #這裏面的值也會被封裝到map集合中:

    key:collection

值:對應的參數值

 

#{collection[0]}#{list[0]}

 

6、參數值的獲取

 一、#{}和${}的異同

#{}:能夠獲取map中的值或者pojo對象屬性的值

${}: 能夠獲取map中的值獲取pojo對象屬性的值

 

eg: select * from tbl_employee where id = ${id} and last_name = #{lastName}

    preparing:select * from tbl_employee where id = 2 and last_name = ?

  

  區別:

     #{}:是以預編譯的形式,將參數設置到sql語句中,PreparedStatement;防止sql注入

  ${}:取出的值直接拼裝在sql語句中,會有安全問題;

  大多狀況下,咱們取參數的值都應該去使用#{};

 

 原生JDBC不支持佔位符的地方咱們就可使用${}進行取值,好比分表、排序;按照年份分表拆分

  eg: select * from ${year}_salary where xxx;[表名不支持預編譯]

     select * from tbl_employee order by ${f_name} ${order} :排序是不支持預編譯的!

 

二、select元素

Select元素來定義查詢操做。

Id:惟一標識符。

    – 用來引用這條語句,須要和接口的方法名一致

  parameterType:參數類型。

    –能夠不傳,MyBatis會根據TypeHandler自動推斷

  resultType:返回值類型。

    – 別名或者全類名,若是返回的是集合,定義集合中元素的類型。不能和resultMap同時使用  

 

(1).返回類型爲一個List

eg:public List<Employee> getEmpsByLastNameLike(String lastName);

 <!-- resultType:若是返回的是一個集合,要寫集合中元素的類型 -->
 <selecct id="getEmpsByLastNameLike" resultType="com.neuedu.mybatis.bean.Employee">
    select * from tbl_employee where lastName  like #{lastName}
 </select>

  

(2).返回記錄爲一個Map

 

 <!-- 返回一條記錄的map:key就是列名,值就是對應的值 -->

  public Map<String,Object> getEmpByIdReturnMap(Integer id);

  <select id="getEmpByIdReturnMap" resultType="map">

        select * from tbl_employee where id = #{id}

  </select>

 

 

(3).返回爲一個ResultMap

<!-- resultMap:自定義結果集映射規則 -->

public  Employee getEmployeById(Integer id);

 <!-- 自定義某個javaBean的封裝規則

    type:自定義規則的java類型

id:惟一id方便引用

 -->

 <resultMap type="com.neuedu.mybatis.bean.Employee" id = "myEmp">

<!--

指定主鍵列的封裝規則

id定義主鍵列會有底層優化

column:指定是哪一列

property:指定對應的javaBean屬性

-->

<id column="id" property = "id">

<!-- 定義普通列封裝規則 -->

<result column="last_name" property="lastName"/>

<!--其它不指定的列只要屬性名和列名會自動封裝,咱們只要寫resultMap就把所有的映射規則都寫上 -->

 </resultMap>

<!--只須要在映射的地方映射一下就能夠了 -->
相關文章
相關標籤/搜索