iBATIS tips
21572 ワード
1、iBATISのプロファイル
2、オブジェクトマッピングファイル
3、アプリケーションの作成
4、主キーの自動生成
5、DB 2保存データの空値問題
6、入力パラメータ
7、Result Map
8、複雑なタイプの属性
9.Mapped Statement結果セットのキャッシュ
10、動的Mapped Statement
11、取引
12、バッチ
13、ページングクエリー
14、Ibator
iBATISはJavaと.NETはどちらの環境でも使用可能であり、データベースの使用が容易になり、iBATISはXML記述ファイルを介してオブジェクトとストレージ・プロシージャ/SQL文との対応関係を決定します.オブジェクトリレーションシップマッピングツールとしてのiBATIS DATA Mapperの最大の利点は簡単です.
iBATIS Data Mapperを使用するには、オブジェクト、XML、SQLに依存し、知らないことをたくさん学ぶ必要はありません.iBATIS Data Maperは、SQLとストレージプロセスのすべての強力な能力を簡単に得ることができます.
Hibernate、Apache OJBのようなORMフレームワークは独自のクエリー言語を持ち、彼らとは異なりiBATISがSQLを直接使用するのは限界があり、つまりデータベース間で使用できないため、各データベースに対してSQL文を調整する必要があるが、大きなメリットもあり、SQLを直接使用することでフレームワークの実現が簡単になる.マッピング効率の可能性は、SQLを直接使用してより高いデータベースアクセス効率を実現し、SQLの特性を直接使用することで、iBATISがアプリケーション環境で開発の要件に適しています.
1、iBATISのプロファイル:
トランザクションマネージャ別名JDBC com.ibatis.sqlmap.engine.transaction.jdbc.JdbcTransactionConfig JTA com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig EXTERNAL com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfigData Source Factory別名SIMPLE com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory DBCP com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory JNDI com.ibatis.sqlmap.engine.datasource.JndiDataSourceFactory
DBPPの構成
JNDI JTA
2、オブジェクトマッピングファイル
簡単に書くこともできます.
SQL文で特殊な記号を使用するために、XMLのCDATAにSQLを入れることができます.
3、アプリケーションの作成
SqlMapClientインタフェースには、次のようなさまざまなデータベース操作方法があります.
sqlMap.queryForObject (“getPerson”, personPk);
sqlMap.update(“updatePerson”, person);
4、主キーの自動生成
ほとんどのデータベースの書き方は次のとおりです.
5、DB 2保存データの空値問題
iBATISはprepareStatementを用いる、mapping定義データ型が表示されない場合には、まずパラメータ値のjavaタイプを用いてprepareStatementに転送するパラメータタイプを決定し、パラメータが値nullの場合Typeを用いる.OTHER .DB 2のドライバの下、Type.OTHERタイプは正しく実行できません.この問題を解決するには、mappingに宣言パラメータ(列)のタイプを表示します.1、beanパラメータについて次のように宣言できます.
insert into USER(USERID)VALES(#userId:VARCHR#) 2、mapパラメータに対して、parameterMapを使用して各パラメータのタイプ を定義できます.
6、入力パラメータ
parameterMap
Inline Parameter Map
基本タイプ入力パラメータ
Mapタイプ入力パラメータ
7、Result Map
暗黙的Result Map
基本タイプのResult(String,Integer,Boolean)
MapタイプのResult
8、複雑なタイプの属性
N+1 Select(1:1)を避ける
複雑なタイプの集合のプロパティ
結合キー値または複数の複雑なパラメータ属性
9.Mapped Statement結果セットのキャッシュ
クエリーstatementでcacheModelプロパティを指定することで、Mapped Statementで得られたクエリー結果をキャッシュできます.
Cache modelは、SQL Map XMLファイルで定義された構成可能キャッシュモードで、cacheModel要素を使用して構成できます.
LRU:最近の最小使用
キャッシュタイプ:
“MEMORY” (com.ibatis.db.sqlmap.cache.memory.MemoryCacheController)
「reference-type」属性のみに作用し、value:STRONG、SOFT、WEAK、デフォルトWEAK.
“LRU” (com.ibatis.db.sqlmap.cache.lru.LruCacheController)
「最近の最小使用」の原則.「cache-size」プロパティのみが機能します.
“OSCACHE” (com.ibatis.db.sqlmap.cache.oscache.OSCacheController)
10、動的Mapped Statement
11、取引
トランザクションはネストできません.commit()またはrollback()を呼び出す前に、同じスレッドから複数回呼び出す.startTransactionは、例外を放出します.すなわち、SqlMapインスタンスごとに、スレッドごとに最大1つのトランザクションしか開かない.SqlMapClientトランザクションは、JavaのThreadLocalを使用してトランザクション・オブジェクトを保存します.これは、トランザクションの処理中にstartTransaction()を呼び出すスレッドごとに、一意のConnectionオブジェクトが得られることを意味します.Connectionオブジェクトをデータ・ソースに戻す(または接続を閉じる)唯一の方法は、commitTransaction()またはrollbackTransaction()メソッドを呼び出すことです.そうしないと、プール内の接続を光で接続し、デッドロックになります.
12、バッチ
13、ページングクエリー
14、Ibator:iBatisの自動生成ツール
http://ibatis.apache.org/ibator.html
提案:Ibatorを使用する場合は、生成されたコードを修正しようとしないで、使用できればいいです.そうしないと、大きなトラブルになります.カスタマイズされた高性能SQLを自分で作成する必要がある場合は、Ibatorは使用しないでください.
2、オブジェクトマッピングファイル
3、アプリケーションの作成
4、主キーの自動生成
5、DB 2保存データの空値問題
6、入力パラメータ
7、Result Map
8、複雑なタイプの属性
9.Mapped Statement結果セットのキャッシュ
10、動的Mapped Statement
11、取引
12、バッチ
13、ページングクエリー
14、Ibator
iBATISはJavaと.NETはどちらの環境でも使用可能であり、データベースの使用が容易になり、iBATISはXML記述ファイルを介してオブジェクトとストレージ・プロシージャ/SQL文との対応関係を決定します.オブジェクトリレーションシップマッピングツールとしてのiBATIS DATA Mapperの最大の利点は簡単です.
iBATIS Data Mapperを使用するには、オブジェクト、XML、SQLに依存し、知らないことをたくさん学ぶ必要はありません.iBATIS Data Maperは、SQLとストレージプロセスのすべての強力な能力を簡単に得ることができます.
Hibernate、Apache OJBのようなORMフレームワークは独自のクエリー言語を持ち、彼らとは異なりiBATISがSQLを直接使用するのは限界があり、つまりデータベース間で使用できないため、各データベースに対してSQL文を調整する必要があるが、大きなメリットもあり、SQLを直接使用することでフレームワークの実現が簡単になる.マッピング効率の可能性は、SQLを直接使用してより高いデータベースアクセス効率を実現し、SQLの特性を直接使用することで、iBATISがアプリケーション環境で開発の要件に適しています.
1、iBATISのプロファイル:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<!-- Always ensure to use the correct XML header as above! -->
<sqlMapConfig>
<!-- The properties (name=value) in the file specified here can be used placeholders
in this config file (e.g. “${driver}”.
The file is relative to the classpath and is completely optional. -->
<properties resource="com/ibatis/SqlMapConfig.properties" />
<!-- These settings control SqlMap configuration details, primarily to do with
transaction management. They are all optional (see the Developer Guide
for more). -->
<settings
cacheModelsEnabled="true"
enhancementEnabled="true"
lazyLoadingEnabled="true"
maxRequests="32"
maxSessions="10"
maxTransactions="5"
useStatementNamespaces="false"
/>
<!-- Type aliases allow you to use a shorter name for long fully
qualified class names. -->
<typeAlias alias="order" type="testdomain.Order"/>
<!-- Configure a datasource to use with this SQL Map using SimpleDataSource.
Notice the use of the properties from the above resource -->
<transactionManager type="JDBC" >
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}"/>
<property name="JDBC.ConnectionURL" value="${url}"/>
<property name="JDBC.Username" value="${username}"/>
<property name="JDBC.Password" value="${password}"/>
<!-- SIMPLE -->
<property name="JDBC.DefaultAutoCommit" value="true" />
<property name="Pool.MaximumActiveConnections" value="10"/>
<property name="Pool.MaximumIdleConnections" value="5"/>
<property name="Pool.MaximumCheckoutTime" value="120000"/>
<property name="Pool.TimeToWait" value="500"/>
<property name="Pool.PingQuery" value="select 1 from ACCOUNT"/>
<property name="Pool.PingEnabled" value="false"/>
<property name="Pool.PingConnectionsOlderThan" value="1"/>
<property name="Pool.PingConnectionsNotUsedFor" value="1"/>
</dataSource>
</transactionManager>
<!-- Identify all SQL Map XML files to be loaded by this SQL map. Notice the paths
are relative to the classpath. For now, we only have one -->
<sqlMap resource="com/ibatis/sample/User.xml" />
<!-- <sqlMap url="file:///c:/config/User.xml " /> -->
</sqlMapConfig>
トランザクションマネージャ別名JDBC com.ibatis.sqlmap.engine.transaction.jdbc.JdbcTransactionConfig JTA com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig EXTERNAL com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfigData Source Factory別名SIMPLE com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory DBCP com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory JNDI com.ibatis.sqlmap.engine.datasource.JndiDataSourceFactory
DBPPの構成
<property name="Pool.MaximumActiveConnections" value="10"/>
<property name="Pool.MaximumIdleConnections" value="5"/>
<property name="Pool.MaximumWait" value="60000"/>
<!--
Use of the validation query can be problematic.If you have difficulty,
try without it.
-->
<property name="Pool.ValidationQuery" value="select 1 from ACCOUNT"/>
<property name="Pool.LogAbandoned" value="false"/>
<property name="Pool.RemoveAbandoned" value="false"/>
<property name="Pool.RemoveAbandonedTimeout" value="50000"/>
JNDI JTA
<transactionManager type="JDBC" >
<dataSource type="JNDI">
<property name="DataSource" value="java:comp/env/jdbc/jpetstore"/>
</dataSource>
</transactionManager>
<transactionManager type="JTA" >
<property name="UserTransaction" value="java:/ctx/con/UserTransaction"/>
<dataSource type="JNDI">
<property name="DataSource" value="java:comp/env/jdbc/jpetstore"/>
</dataSource>
</transactionManager>
2、オブジェクトマッピングファイル
<sqlMap id=”Product”>
<cacheModel id=”productCache” type=”LRU”>
<flushInterval hours=”24”/>
<property name=”size” value=”1000” />
</cacheModel>
<typeAlias alias=”product” type=”com.ibatis.example.Product” />
<parameterMap id=”productParam” class=”product”>
<parameter property=”id”/>
</parameterMap>
<resultMap id=”productResult” class=”product”>
<result property=”id” column=”PRD_ID”/>
<result property=”description” column=”PRD_DESCRIPTION”/>
</resultMap>
<select id=”getProduct” parameterMap=”productParam”
resultMap=”productResult” cacheModel=”product-cache”>
select * from PRODUCT where PRD_ID = ?
</select>
</sqlMap>
簡単に書くこともできます.
<sqlMap id=”Product”>
<select id=”getProduct” parameterClass=” com.ibatis.example.Product”
resultClass=”com.ibatis.example.Product”>
select
PRD_ID as id,
PRD_DESCRIPTION as description
from PRODUCT
where PRD_ID = #id#
</select>
</sqlMap>
SQL文で特殊な記号を使用するために、XMLのCDATAにSQLを入れることができます.
<statement id="getPersonsByAge" parameterClass=”int”
resultClass="examples.domain.Person">
<![CDATA[
SELECT *
FROM PERSON
WHERE AGE > #value#
]]>
</statement>
3、アプリケーションの作成
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
try {
String resource = "com/simple/SqlMapConfig.xml";
Reader reader = Resources.getResourceAsReader(resource);
SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(
"Error initializing TourPlanIBatisConfig class. Cause: " + e);
}
SqlMapClientインタフェースには、次のようなさまざまなデータベース操作方法があります.
sqlMap.queryForObject (“getPerson”, personPk);
sqlMap.update(“updatePerson”, person);
4、主キーの自動生成
<!—Oracle SEQUENCE Example -->
<insert id="insertProduct-ORACLE" parameterClass="com.domain.Product">
<selectKey resultClass="int" keyProperty="id" >
SELECT STOCKIDSEQUENCE.NEXTVAL AS ID FROM DUAL
</selectKey>
insert into PRODUCT (PRD_ID,PRD_DESCRIPTION)
values (#id#,#description#)
</insert>
<!— Microsoft SQL Server IDENTITY Column Example -->
<insert id="insertProduct-MS-SQL" parameterClass="com.domain.Product">
insert into PRODUCT (PRD_DESCRIPTION)
values (#description#)
<selectKey resultClass="int" keyProperty="id" >
SELECT @@IDENTITY AS ID
</selectKey>
</insert>
ほとんどのデータベースの書き方は次のとおりです.
<selectKey>
Cloudscape VALUES IDENTITY_VAL_LOCAL()
DB2 VALUES IDENTITY_VAL_LOCAL()
Derby VALUES IDENTITY_VAL_LOCAL()
HSQLDB CALL IDENTITY()
MySql SELECT LAST_INSERT_ID()
SqlServer SELECT SCOPE_IDENTITY()
SYBASE SELECT @@IDENTITY
ORACLE SELECT CUSTOM_SQL.NEXTVAL AS ID FROM DUAL
5、DB 2保存データの空値問題
iBATISはprepareStatementを用いる、mapping定義データ型が表示されない場合には、まずパラメータ値のjavaタイプを用いてprepareStatementに転送するパラメータタイプを決定し、パラメータが値nullの場合Typeを用いる.OTHER .DB 2のドライバの下、Type.OTHERタイプは正しく実行できません.この問題を解決するには、mappingに宣言パラメータ(列)のタイプを表示します.1、beanパラメータについて次のように宣言できます.
6、入力パラメータ
parameterMap
<parameterMap id=”insert-product-param” class=”com.domain.Product”>
<parameter property=”id” jdbcType=”NUMERIC” javaType=”int” nullValue=”-9999999”/>
<parameter property=”description” jdbcType=”VARCHAR” nullValue=”NO_ENTRY”/>
</parameterMap>
<statement id=”insertProduct” parameterMap=”insert-product-param”>
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?);
</statement>
Inline Parameter Map
<statement id=”insertProduct” parameterClass=”com.domain.Product”>
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)
values (#id#, #description#);
</statement>
:
<statement id=”insertProduct” parameterClass=”com.domain.Product”>
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)
values (#id:NUMERIC#, #description:VARCHAR#);
</statement>
NULL :
<statement id=”insertProduct” parameterClass=”com.domain.Product”>
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)
values (#id:NUMERIC:-999999#, #description:VARCHAR:NO_ENTRY#);
</statement>
基本タイプ入力パラメータ
<statement id=”insertProduct” parameter=”java.lang.Integer”>
select * from PRODUCT where PRD_ID = #value#
</statement>
Mapタイプ入力パラメータ
<statement id=”insertProduct” parameterClass=”java.util.Map”>
select * from PRODUCT
where PRD_CAT_ID = #catId# and PRD_CODE = #code#
</statement>
7、Result Map
<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>
<result property=”id” column=”PRD_ID”/>
<result property=”description” column=”PRD_DESCRIPTION”/>
<result property=”subCode” column=”PRD_SUB_CODE” nullValue=”-999”/>
</resultMap>
暗黙的Result Map
<statement id=”getProduct” resultClass=”com.ibatis.example.Product”>
select
PRD_ID as id,
PRD_DESCRIPTION as description
from PRODUCT
where PRD_ID = #value#
</statement>
基本タイプのResult(String,Integer,Boolean)
<resultMap id=”get-product-result” class=”java.lang.String”>
<result property=”value” column=”PRD_DESCRIPTION”/>
</resultMap>
<statement id=”getProductCount” resultClass=”java.lang.Integer”>
select count(1) as value
from PRODUCT
</statement>
MapタイプのResult
<resultMap id=”get-product-result” class=”java.util.HashMap”>
<result property=”id” column=”PRD_ID”/>
<result property=”code” column=”PRD_CODE”/>
<result property=”description” column=”PRD_DESCRIPTION”/>
<result property=”suggestedPrice” column=”PRD_SUGGESTED_PRICE”/>
</resultMap>
8、複雑なタイプの属性
<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>
<result property=”id” column=”PRD_ID”/>
<result property=”description” column=”PRD_DESCRIPTION”/>
<result property=”category” column=”PRD_CAT_ID” select=”getCategory”/>
</resultMap>
<resultMap id=”get-category-result” class=”com.ibatis.example.Category”>
<result property=”id” column=”CAT_ID”/>
<result property=”description” column=”CAT_DESCRIPTION”/>
</resultMap>
<statement id=”getProduct” parameterClass=”int” resultMap=”get-product-result”>
select * from PRODUCT where PRD_ID = #value#
</statement>
<statement id=”getCategory” parameterClass=”int” resultMap=”get-category-result”>
select * from CATEGORY where CAT_ID = #value#
</statement>
N+1 Select(1:1)を避ける
<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>
<result property=”id” column=”PRD_ID”/>
<result property=”description” column=”PRD_DESCRIPTION”/>
<result property=”category.id” column=”CAT_ID” />
<result property=”category.description” column=”CAT_DESCRIPTION” />
</resultMap>
<statement id=”getProduct” parameterClass=”int” resultMap=”get-product-result”>
select *
from PRODUCT, CATEGORY
where PRD_CAT_ID=CAT_ID
and PRD_ID = #value#
</statement>
複雑なタイプの集合のプロパティ
<resultMap id=”get-category-result” class=”com.ibatis.example.Category”>
<result property=”id” column=”CAT_ID”/>
<result property=”description” column=”CAT_DESCRIPTION”/>
<result property=”productList” column=”CAT_ID” select=” getProductsByCatId”/>
</resultMap>
<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>
<result property=”id” column=”PRD_ID”/>
<result property=”description” column=”PRD_DESCRIPTION”/>
</resultMap>
<statement id=”getCategory” parameterClass=”int” resultMap=”get-category-result”>
select * from CATEGORY where CAT_ID = #value#
</statement>
<statement id=”getProductsByCatId” parameterClass=”int” resultMap=”get-product-result”>
select * from PRODUCT where PRD_CAT_ID = #value#
</statement>
結合キー値または複数の複雑なパラメータ属性
<resultMap id=”get-order-result” class=”com.ibatis.example.Order”>
<result property=”id” column=”ORD_ID”/>
<result property=”customerId” column=”ORD_CST_ID”/>
…
<result property=”payments” column=”{itemId=ORD_ID, custId=ORD_CST_ID}”
select=” getOrderPayments”/>
</resultMap>
<statement id=”getOrderPayments” resultMap=”get-payment-result”>
select * from PAYMENT
where PAY_ORD_ID = #itemId#
and PAY_CST_ID = #custId#
</statement>
9.Mapped Statement結果セットのキャッシュ
クエリーstatementでcacheModelプロパティを指定することで、Mapped Statementで得られたクエリー結果をキャッシュできます.
Cache modelは、SQL Map XMLファイルで定義された構成可能キャッシュモードで、cacheModel要素を使用して構成できます.
<cacheModel id="product-cache" type ="LRU" readOnly=”true” serialize=”false”>
<flushInterval hours="24"/>
<flushOnExecute statement="insertProduct"/>
<flushOnExecute statement="updateProduct"/>
<flushOnExecute statement="deleteProduct"/>
<property name=”cache-size” value=”1000” />
</cacheModel>
LRU:最近の最小使用
<statement id=”getProductList” cacheModel=”product-cache”>
select * from PRODUCT where PRD_CAT_ID = #value#
</statement>
キャッシュタイプ:
“MEMORY” (com.ibatis.db.sqlmap.cache.memory.MemoryCacheController)
「reference-type」属性のみに作用し、value:STRONG、SOFT、WEAK、デフォルトWEAK.
“LRU” (com.ibatis.db.sqlmap.cache.lru.LruCacheController)
「最近の最小使用」の原則.「cache-size」プロパティのみが機能します.
“OSCACHE” (com.ibatis.db.sqlmap.cache.oscache.OSCacheController)
10、動的Mapped Statement
<statement id="dynamicGetAccountList" resultMap="account-result" >
select * from ACCOUNT
<dynamic prepend="WHERE">
<isNotNull prepend="AND" property="firstName">
(ACC_FIRST_NAME = #firstName#
<isNotNull prepend="OR" property="lastName">
ACC_LAST_NAME = #lastName#
</isNotNull>
)
</isNotNull>
<isNotNull prepend="AND" property="emailAddress">
ACC_EMAIL like #emailAddress#
</isNotNull>
<isGreaterThan prepend="AND" property="id" compareValue="0">
ACC_ID = #id#
</isGreaterThan>
</dynamic>
order by ACC_LAST_NAME
</statement>
11、取引
String resource = “com/ibatis/example/sqlMap-config.xml”;
Reader reader = Resources.getResourceAsReader (resource);
SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMap(reader);
public void startTransaction () throws SQLException
public void commitTransaction () throws SQLException
public void endTransaction () throws SQLException
private Reader reader = new Resources.getResourceAsReader(
"com/ibatis/example/sqlMapconfig.xml");
private SqlMapClient sqlMap = XmlSqlMapBuilder.buildSqlMap(reader);
public updateItemDescription (String itemId, String newDescription) throws SQLException {
try {
sqlMap.startTransaction ();
Item item = (Item) sqlMap.queryForObject ("getItem", itemId);
item.setDescription (newDescription);
sqlMap.update ("updateItem", item);
sqlMap.commitTransaction ();
} finally {
sqlMap.endTransaction ();
}
}
トランザクションはネストできません.commit()またはrollback()を呼び出す前に、同じスレッドから複数回呼び出す.startTransactionは、例外を放出します.すなわち、SqlMapインスタンスごとに、スレッドごとに最大1つのトランザクションしか開かない.SqlMapClientトランザクションは、JavaのThreadLocalを使用してトランザクション・オブジェクトを保存します.これは、トランザクションの処理中にstartTransaction()を呼び出すスレッドごとに、一意のConnectionオブジェクトが得られることを意味します.Connectionオブジェクトをデータ・ソースに戻す(または接続を閉じる)唯一の方法は、commitTransaction()またはrollbackTransaction()メソッドを呼び出すことです.そうしないと、プール内の接続を光で接続し、デッドロックになります.
12、バッチ
sqlMap.startBatch();
//…execute statements in between
sqlMap.executeBatch();
13、ページングクエリー
PaginatedList list = sqlMap.queryForPaginatedList (“getProductList”, null, 10);
list.nextPage();
list.previousPage();
14、Ibator:iBatisの自動生成ツール
http://ibatis.apache.org/ibator.html
提案:Ibatorを使用する場合は、生成されたコードを修正しようとしないで、使用できればいいです.そうしないと、大きなトラブルになります.カスタマイズされた高性能SQLを自分で作成する必要がある場合は、Ibatorは使用しないでください.