Mybatis 學習筆記 1(非原創 自己整理)

關於實體映射文件中namespace,以前的版本是可選的內容,現在被用來與接口綁定,也就是說把接口的實現轉移到xml文件中來了,以後的維護會相當的方便。

 

第一篇的根據id查詢學生的例子中,稍做修改:

建立StudentDAO接口

package cn.pf.ibatis.dao;   

import java.util.List;

import cn.pf.ibatis.domain.Student;  

public interface StudentDAO {  

public Student queryStudentById(int id);  

}

更改 student.xml中的mapper元素namespace屬性

test.java中調用改爲

 

Student student;

StudentDAO studentDAO =session.getMapper(StudentDAO.class);

try {

// student =

// (Student)session.selectOne(

//            "cn.pf.ibatis.domain.StudentMapper.selectStudent",1);

student = studentDAO.queryStudentById(1);

} finally {

session.close();

}

System.out.println(student.toString());

生命週期

SqlSessionFactoryBuilder

用於建立SqlSessionFactory的工具類,在創建SqlSessionFactory以後無需再讓它存在於應用程序中,文檔上說它的生命週期最好在局部方法內,所以在代碼中看到

//根據資源文件內容建立session工廠

SqlSessionFactorysqlMapper =

newSqlSessionFactoryBuilder().build(reader);

沒用引用指向 SqlSessionFactoryBuilder,會被gc回收。

SqlSessionFactory

一旦建立,SqlSessionFactory就應該存在於整個應用程序生命週期,因爲根據資源文件建立SqlSessionFactory對象需要很大的開銷,所以保留在整個應用的生命週期中,最佳實踐中推薦使用spring等依賴注入的框架從而管理SqlSessionFactory的單例生命週期。

SqlSession

每一個線程都應該有自己的SqlSession對象,SqlSession對象不是線程安全的所以不應該被共享,如果使用web框架,應該將SqlSession的生命週期看作HTTP Request的生命週期,在返回HTTP Response的時候關閉SqlSession

引用

SqlSession session =sqlSessionFactory.openSession();

try {

// do work

} finally {

session.close();

}

MapperInstances:

MapperInstances是綁定ibatis映射文件實現的接口,Mapper Instances的生命週期應該與SqlSession一樣,但是Mapper Instances最好在一個方法中被創建,在方法結束時被銷燬。

try {

BlogMapper mapper = session.getMapper(BlogMapper.class);

    // do work  

} finally {  

    session.close();  

}

配置文件

配置文件的層次結構如下:

•configuration

o properties

o settings

o typeAliases

o typeHandlers

o objectFactory

o plugins

o environments

     environment

• transactionManager

       • dataSource

o mappers

1 properties

用來定義外部properties配置文件信息。比如

<properties resource="org/apache/ibatis/example/config.properties"> 

    <property name="username" value="dev_user"/> 

    <property name="password" value="F2Fa3!33TYyg"/>

</properties>

<dataSource type="POOLED"> 

<property name="driver" value="${driver}"/> 

    <property name="url" value="${url}"/> 

    <property name="username" value="${username}"/> 

    <property name="password" value="${password}"/> 

</dataSource>
那麼username和password被替換成dev_user和F2Fa3!33TYyg,而drive和url屬性將讀取 config.properties中的內容從而取得具體值
properties還可以通過SqlSessionFactoryBuilder的build方法作爲參數傳入:

SqlSessionFactory factory =

sqlSessionFactoryBuilder.build(reader, props);

// ... or ...

SqlSessionFactory factory2 =

sqlSessionFactoryBuilder.build(reader, environment,props);

property加載順序:
1、properties元素內部
2、外部properties文件
3、SqlSessionFactoryBuilder的build方法參數
也就是說,build方法參數中的properties優先級高於前兩個,因爲它是最後被加載,所以會覆蓋前兩種加載方法加載的properties值。

2 settings

Setting選項

描述

合法值

默認值

cacheEnabled

是否使用全局緩存

true|false

true

lazyLoadingEnabled

是否使用全局懶加載

true|false

true

multipleResultSetsEnabled

是否允許返回多個結果集合(需要兼容的驅動)

true|false

true

useColumnLabel

使用列標籤取代列名(不同驅動表現不同)

true|false

true

useGeneratedKeys

允許jdbc自動生成主鍵

true|false

false

defaultExecutorType

配置默認執行方式

SIMPLE| REUSE| BATCH

SIMPLE

defaultStatementTimeout

數據庫超時時間

Any positive

integer

Not Set

 (null)

 

例子:

<settings>

    <setting name="cacheEnabled" value="true"/> 

    <setting name="lazyLoadingEnabled" value="true"/> 

    <setting name="multipleResultSetsEnabled" value="true"/> 

    <setting name="useColumnLabel" value="true"/> 

    <setting name="useGeneratedKeys" value="false"/> 

    <setting name="defaultExecutorType" value="SIMPLE"/> 

    <setting name="defaultStatementTimeout" value="25000"/> 

</settings>

3 typeAliases
java類別名

<typeAliases> 

<typeAlias alias="Author" type="domain.blog.Author"/> 

<typeAlias alias="Blog" type="domain.blog.Blog"/>

</typeAliases> 

 

4 typeHandlers

Handler類型

Java類型

JDBC類型

BooleanTypeHandler

Boolean,boolean

Any compatible

BOOLEAN

ByteTypeHandler

Byte,byte

Any compatible

NUMERIC or BYTE

ShortTypeHandler

Short,short

Any compatible

NUMERIC or SHORT

INTEGER

IntegerTypeHandler

Integer,int

Any compatible

NUMERIC or INTEGER

LongTypeHandler

Long,long

Any compatible

NUMERIC or LONG

INTEGER

FloatTypeHandler

Float,float

Any compatible

NUMERIC or FLOAT

DoubleTypeHandler

Double,double

Any compatible

NUMERIC or DOUBLE

BigDecimalTypeHandler

BigDecimal

Any compatible

NUMERIC or DECIMAL

StringTypeHandler

String

CHAR,VARCHAR

ClobTypeHandler

String

CLOB,LONGVARCHAR

NStringTypeHandler

String

NVARCHAR,NCHAR

NClobTypeHandler

String

NCLOB

ByteArrayTypeHandler

byte[]

Any compatible byte

stream type

BlobTypeHandler

byte[]

BLOB,LONGVARBINARY

DateTypeHandler

Date(java.util)

TIMESTAMP

DateOnlyTypeHandler

Date(java.util)

DATE

TimeOnlyTypeHandler

Date(java.util)

TIME

SqlTimestampTypeHandler

Timestamp(java.sql)

TIMESTAMP

SqlDateTypeHadler

Date(java.sql)

DATE

SqlTimeTypeHandler

Time(java.sql)

TIME

ObjectTypeHandler

Any

OTHER,or unspecified

 

也可以通過實現TypeHandler接口來實現自定義的類型轉換器

//ExampleTypeHandler.java  

public class ExampleTypeHandlerimplements TypeHandler {  

public void setParameter(PreparedStatement ps, int i,

Object parameter,JdbcType jdbcType)  

            throws SQLException{  

        ps.setString(i,(String) parameter);  

    }  

    public Object getResult(  

            ResultSet rs, String columnName)  

            throws SQLException {  

        return rs.getString(columnName);  

    }  

    public Object getResult(CallableStatementcs, int columnIndex)  

            throws SQLException{  

        returncs.getString(columnIndex);  

    }  

}

// MapperConfig.xml  

<typeHandlers>

    <typeHandler handler=

"org.apache.ibatis.example.ExampleTypeHandler"

javaType="string" jdbcType="VARCHAR"/>

</typeHandlers> 

這樣會覆蓋原來ibatis默認的string varchar轉換器

5 objectFactory

ibatis使用objectFactory去創建result object的實例對象,這裏可以自己繼承DefaultObjectFactory類實現自己的ObjectFactory
//ExampleObjectFactory.java

public class ExampleObjectFactoryextends DefaultObjectFactory {  

    public Object create(Class type){  

        return super.create(type);  

    }  

    public Object create(Class type, ListconstructorArgTypes,  

             ListconstructorArgs) {  

        return super.create(type, constructorArgTypes,constructorArgs);  

    }  

    public void setProperties(Properties properties) {  

        super.setProperties(properties);  

    }  

}

//MapperConfig.xml

<objectFactory type="org.apache.ibatis.example.ExampleObjectFactory">

    <property name="someProperty" value="100"/>

</objectFactory>  

6 plugins
ibatis允許插件截斷以下方法調用
Executor(update,query,flushStatements,commit,rollback,getTransaction,close,isClosed)
ParameterHandler(getParameterObject,setParameters)
ResultSetHandler(handleResultSets,handleOutputParameters)
StatementHandler(prepare,parameterize,batch,update,query)
必須在理解這些方法的基礎上很小心的使用插件,不然很容易破壞ibatis的核心
//ExamplePlugin.java

@Intercepts({@Signature(type= Executor.class, method = "update",

       args= {MappedStatement.class,Object.class})})  

public class ExamplePlugin implements Interceptor {  

    public Object intercept(Invocationinvocation) throws Throwable {  

        return invocation.proceed();  

    }  

    public Object plugin(Object target){  

        return Plugin.wrap(target, this);  

    }  

    public void setProperties(Properties properties) {  

    }  

//MapperConfig.xml

<plugins>

    <plugin interceptor="org.apache.ibatis.example.ExamplePlugin">

        <property name="someProperty" value="100"/>

    </plugin>

</plugins>

7 environments

這個是ibatis 3非常好的一個配置,允許配置多個不懂運行環境參數,不過每個SqlSessionFactory只可以在一種環境下被創建。

利用SqlSessionFactory的build函數

SqlSessionFactoryfactory =

sqlSessionFactoryBuilder.build(reader,environment);

SqlSessionFactoryfactory =

sqlSessionFactoryBuilder.build(reader,environment,properties);

如果不知名environment參數,則應用默認的環境參數

SqlSessionFactoryfactory = sqlSessionFactoryBuilder.build(reader);

SqlSessionFactoryfactory =

sqlSessionFactoryBuilder.build(reader,properties);

xml中如下配置:

<environmentsdefault="MySQL">

    <environment id="MySQL">

       <transactionManager type="JDBC" />

        <dataSourcetype="POOLED">

           <property name="driver"value="${driver}" />

           <property name="url" value="${url}"/>

           <property name="username"value="${username}" />

           <property name="password"value="${password}" />

       </dataSource>

    </environment>

</environments>

幾個注意點:

默認environment id:development

事務控制類型:JDBC

  JDBC:根據jdbc控制事務的提交和回滾
   MANAGED:將事務控制轉交給容器
數據源類型:POOLED

  UNPOOLED:不使用池技術,在請求到來時直接打開或者關閉數據庫連接
        必須配置的參數:driver、url、username、password
        可選參數:使用driver.xxx來配置,如:driver.encoding=UTF8
   POOLED:使用數據庫連接池

類型

描述

默認值

poolMaximumActiveConnections

同一時間內最大連接數

10

poolMaximumIdleConnections

連接最大空閒數目

 

poolMaximumCheckoutTime

連接被每個任務佔用的最大時間

20000ms

poolTimeToWait

連接池中無可用連接時,線程的等待時間

20000ms

poolPingQuery

數據庫連接狀態檢測語句,類似於ping的功能

NO PING QUERY SET

poolPingEnabled

是否允許ping檢測

false

poolPingConnectionsNotUsedFor

對超過指定空閒時間的數據庫連接進

行狀態監測

0 (必須在poolPingEnabled設置true情況下)

JNDI:

     initial_context:可選

      data_source:JNDI數據庫名稱.使用env.xxx配置可選參數,

如:env.encoding=UTF8

8 mappers

配置實體映射文件的路徑

<mappers> 

    <mapper resource="org/apache/ibatis/builder/AuthorMapper.xml"/> 

    <mapper resource="org/apache/ibatis/builder/BlogMapper.xml"/> 

    <mapper resource="org/apache/ibatis/builder/PostMapper.xml"/> 

</mappers>

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