myBatis的核心配置

MyBatis的設計思路java

ORM(Object Relation Mapping)模型將數據庫存儲數據與POJO對象進行映射,從而簡化數據轉化的複雜度;若是說Hibernate是徹底封裝的ORM框架,則myBatis則是半徹底封裝的ORM框架,由於myBatis須要手動映射SQL返回結果與POJO對象的映射;mysql

java鏈接mysql通常有四種方式,不基於鏈接池的jdbc和基於鏈接池的dbcp, c3p0, jndi:
#1 jdbc:不使用鏈接池,每次進行DB操做都經過java.sql.DriverManager.getConnection獲取一個新的connection,並經過openSession()獲取一個交互session;
#2 dbcp:基於org.apache.commons.dbcp.BasicDataSource並建立connection pool,BasicDataSourceFactory.createDataSource獲取DBCP數據源,而後獲取可重複使用的connection;
#3 c3p0:基於DataSource並建立connection pool,ComboPooledDataSource.getConnection獲取可重複使用的connection。
#4 jndi:基於DataSource並建立connection pool,InitialContext.getConnection獲取connection。spring

myBatis解決了原生JDBC訪問DB的幾大問題:sql

#1 DB Connection頻繁的開啓和關閉會形成資源的浪費,因此使用DB Connection Pool經過重複利用Connection能夠極大下降DB資源的消耗;connection建立session並開啓transaction,session結束後transaction也關閉,並將connection歸還給pool;
#2 使用可配置的方式兼容多種DataSource(jndi, c3p0, dbcp)的鏈接池;
#3 愈來愈多的業務須要根據數據來動態生成sql語句,傳統的preparedStatement都是基於固定的sql來填充參數,mybatis提供if-else等標籤根據業務數據動態生成並組裝sql;
#4 mybatis提供ResultMap等自動映射的方式對查詢結果進行解析,並提供[sql + params]做爲key的方式將查詢結果進行緩存;
#5 mybatis提供<sql />標籤將一些共用的sql片斷抽取出來,供多個地方引用;數據庫

對比MyBatis和Hibernateapache

#1 myBatis中的SQL是在開發的時候就已經寫好的,而且能夠細粒度的優化SQL語句,hibernate則是徹底根據Object生成SQL,性能上會有一些影響;但同時hibernate的DB關聯性低,可移植性高,myBatis因爲定製化了大量的SQL,則在遷移DB的時候須要考慮兼容性;緩存

Mybatis可接編寫原生態sql,可嚴格控制sql執行性能,靈活度高,很是適合對關係數據模型要求不高的軟件開發;但缺點是mybatis沒法作到數據庫無關性,若是須要實現支持多種數據庫則須要自定義多套sql映射文件,myBatis一樣支持經過java bean定義逆向生成CRUD操做對應的SQL。安全

#2 Hibernate提供的是一種全表映射的模型,所以在作關聯查詢的時候hibernate會將相關表的全部字段都加載到內存,而後再將數據封裝成須要的對象;而myBatis會根據resultMap僅僅將須要的數據加載到內存,並自動轉化成須要的對象,能夠極大提高效率。session

#3 Hibernate有一整套DAO對象的狀態管理機制,myBatis則沒有完整的DAO管理機制,須要手動維護DAO對象的數據更新操做;mybatis

#4 Hibernate的ORM映射關係是固定的,若是某些字段或者某些查詢條件須要動態生成則只能經過HQL實現(性能較差),而myBatis自然支持SQL的動態生成,能夠支持table名字或者column名字動態變化的場景;

#5 Hibernate不能有效支持存儲過程,myBatis自然支持存儲過程,store procedure的優點在於將業務邏輯封裝到DB端,更安全穩定、執行性能也高,但劣勢在於bug tracking和可移植性;

在spring中集成myBatis

首先在spring配置文件service.xml中配置 DBCP數據源,TxManager 和SqlSession的封裝。

 

 1 <beans xmlns="http://www.springframework.org/schema/beans">
 2   <bean id="dbcpDataSource"
 3     class="org.apache.commons.dbcp.BasicDataSource">
 4     <property name="driverClassName">
 5       <value>com.mysql.jdbc.Driver</value>
 6     </property>
 7     <property name="url">
 8       <value>jdbc:mysql://localhost:3306/ychenDemo</value>
 9     </property>
10     <property name="username">
11       <value>root</value>
12     </property>
13     <property name="password">
14       <value>password</value>
15     </property>
16   </bean>
17 
18   <bean id="mybatisTxManager"
19     class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
20     <property name="dataSource" ref="dbcpDataSource" />
21   </bean>
22 
23   <bean id="sqlSessionFactory"
24     class="org.mybatis.spring.SqlSessionFactoryBean">
25     <property name="dataSource" ref="dbcpDataSource" />
26     <property name="configLocation"
27       value="mybatis/mybatis-config.xml"></property>
28   </bean>
29 
30   <bean id="myBatisBaseMapper"
31     class="org.mybatis.spring.mapper.MapperFactoryBean" abstract="true"
32     lazy-init="true">
33     <property name="sqlSessionFactory" ref="sqlSessionFactory" />
34   </bean>
35 
36   <bean id="userMapper" parent="myBatisBaseMapper">
37     <property name="mapperInterface"
38       value="ychen.demo_mybatis.mapper.UserMapper" />
39   </bean>
40 
41   <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
42     <constructor-arg index="0" ref="sqlSessionFactory" />
43   </bean>
44 </beans>

mybatis提供兩種DB操做的接口:
-1 經過sqlSessionTemplate提供統一接口,並在參數中指定statementID和parameterList的方式;

 1 public List<Person> getPersonById(Long personId) {
 2     Map<String, Long> params = Maps.newHashMap();
 3     params.put("personId", personId);
 4     List<Person> result = template.selectList("getPersonById", params);
 5     return result;
 6 }
 7 
 8 >>>>>>>>>>>>>
 9 <mapper namespace="personMapper">
10   <select id="getPersonById" resultType="com.ychen.Person">
11     SELECT * FROM person WHERE id = #{personId}
12   </select>
13 </mapper>

-2 經過定義mapper interface,並使用SqlSessionFactoryBean和MapperFactoryBean動態代理的方式生成mapper實現類,mapper interface中能夠自定義多個DB訪問接口,內部實現依舊是轉換成sqlSessionTemplate統一接口的方式,只是封裝性更好。

 1 @Component
 2 public interface UserMapper {
 3     void insert(UserEntity user);
 4     UserEntity getOne(Long id);
 5 }
 6 
 7 >>>>>>>>>
 8 <mapper namespace="ychen.demo_mybatis.mapper.UserMapper">
 9   <select id="getOne" parameterType="Long" resultMap="BaseResultMap">
10     SELECT  <include refid="Base_Column_List" />
11     FROM payment_session
12     WHERE id = #{id}
13   </select>
14 </mapper>
15 
16 >>>>>>>>>
17 UserMapper userMapper = 
18     applicationContext.getBean("userMapper", UserMapper.class);
19   UserEntity userEntity = userMapper.getOne(1L);

構建sqlSessionFactory所需的myBatis-config.xml配置

 1 <configuration>
 2   <!-- resource屬性引入外部定義的key/value變量,也可經過property標籤訂義內部變量 -->
 3   <properties resource="org/mybatis/example/mybatis-config.properties"> 
 4     <property name="username" value="dev_user"/> 
 5     <property name="password" value="F2Fa3!33TYyg"/> 
 6   </properties>
 7   <!-- 定義mybatis的運行變量 -->
 8   <settings>
 9     <setting name="cacheEnabled" value="true"/>
10     <setting name="lazyLoadingEnabled" value="true"/>
11     <setting name="multipleResultSetsEnabled" value="true"/>
12     <setting name="useColumnLabel" value="true"/>
13     <setting name="useGeneratedKeys" value="false"/>
14     <setting name="autoMappingBehavior" value="PARTIAL"/>
15     <!-- SIMPLE|REUSE|BATCH -->
16     <setting name="defaultExecutorType" value="SIMPLE"/>
17     <setting name="defaultStatementTimeout" value="25"/>
18     <setting name="defaultFetchSize" value="100"/>
19     <setting name="safeRowBoundsEnabled" value="false"/>
20     <setting name="mapUnderscoreToCamelCase" value="false"/>
21     <setting name="localCacheScope" value="SESSION"/>
22     <setting name="jdbcTypeForNull" value="OTHER"/>
23     <setting name="lazyLoadTriggerMethods" 
24       value="equals,clone,hashCode,toString"/>
25   </settings>
26   <!-- 定義經常使用類型的簡寫別名,同時mybatis爲java經常使用類型提供了缺省別名 -->
27   <typeAliases>
28     <typeAlias type="leo.chen.domain.UserAccount" alias="UserAccount" />
29     <typeAlias type="leo.chen.domain.SpecialCar" alias="SpecialCar" />
30   </typeAliases>
31   <!-- 處理參數和返回結果在java-type和db-type間的轉換,同時myBatis提供經常使用類型的handler -->
32   <!-- 經過繼承BaseTypeHandler類或者實現TypeHandler接口,能夠定製化轉換方法 -->
33   <typeHandlers>
34     <typeHandler handler="com.active.services.endurance.mybatis.UUIDTypeHandler" 
35       javaType="java.util.UUID" jdbcType="VARCHAR"/>
36   </typeHandlers>
37   <!-- myBatis建立結果對象實例時使用默認的工廠類實現,經過objectFactory能夠替換默認的工廠 -->
38   <objectFactory type="leo.chen.manager.CustomizedObjectFactory">
39     <property name="property1" value="value1">
40   </objectFactory>
41   <!-- 用於對mybatis處理流程中某些方法的擴展處理,如緩存一致性,如分頁 -->
42   <plugins>
43     <plugin interceptor="org.mybatis.example.validationPlugin"> 
44       <property name="isThrowExp" value="true"/> 
45     </plugin> 
46   </plugins>
47   <!-- 定義mybatis的執行環境,包括事務管理、數據源等配置 -->
48   <environments default="development">
49     <environment id="development"> 
50       <transactionManager type="JDBC"> </transactionManager> 
51       <dataSource type="POOLED"> 
52         <property name="driver" value="${driver}"/> 
53         <property name="url" value="${url}"/> 
54         <property name="username" value="${username}"/> 
55         <property name="password" value="${password}"/> 
56         <property name="defaultTransactionlsoltionLevel" value="${txLevel}"/>
57         <property name="poolMaximumActiveConnection" value="10"/>
58         <property name="poolMaximumldleConnection" value="10"/>
59         <property name="poolMaximumCheckoutTime" value="20000"/>
60         <property name="poolTimeToWait" value="20000"/>
61         <property name="poolPingQuery" value="NOPINGQUERYSET"/>
62         <property name="poolPingEnabled" value="false"/> 
63         <property name="poolPingConnectionsNotUsedFor" value="0"/> 
64       </dataSource> 
65     </environment>
66   </environments>
67   <!-- 數據庫廠商標識 -->
68   <databaseIdProvider type=""></databaseIdProvider>
69   <!-- 定義mapper映射文件 -->
70   <mappers>
71     <mapper resource="mybatis/productMapper.xml" />
72   </mappers>
73 </configuration>

#1 mybatis提供兩種事務管理配置,JDBC和MANAGED,前者使用正常的JDBC的事務管理,也就是對java.sql.Connection事務管理的封裝,依賴於從data source獲取的鏈接來管理實務;後者將事務管理交由WEB容器進行管理,也就是說調用ManagedTransaction的commit和rollback並不會有任何動做;若是myBatis跟spring集成,則不須要配置此項。

#2 mybatis提供三種數據源的的配置,POOLED, UNPOOLED和JNDI,POOLED是在UNPOOLED的封裝上添加了connection緩存管理的實現,UNPOOLED的實現僅僅是打開和關閉鏈接;而JNDI則是經過jndi服務查找代理的data source實現;若是myBatis跟spring集成,則也不須要配置此項。

#3 localCacheScope表示設置一級緩存的使用範圍,缺省爲SESSION,若是設置爲STATEMENT則表示一級緩存僅限於一次statement使用,也就是禁用緩存。鑑於mybatis一級緩存實現不完整,容易形成數據一致性問題,所以建議使用STATEMENT。

#4 <plugins>標籤容許在mybatis內部的四個大的處理流程中插入自定義的處理方法:
-1 Executor:處理mybatis的整個流程和二級緩存的使用
-2 ParameterHandler:處理mybatis對sql傳入參數的賦值,
-3 StatementHandler:處理mybatis與db進行交互的規則和一級緩存的修改,
-4 ResultSetHandler:處理mybatis對結果集的映射規則;
具體的實現類須要實現Interceptor接口及對應的方法。

1 public interface Interceptor {   
2    //經過invocation.getTarget()能夠定製不一樣階段的plugin
3    Object intercept(Invocation invocation) throws Throwable;       
4    Object plugin(Object target);    
5    void setProperties(Properties properties);
6 }
相關文章
相關標籤/搜索