iBatis是眾多OR Mapping工具中的一個。

 

OR Mapping產生源自于面向對象的計算機語言(Object-Oriented Language,例如Java)和

關系型數據庫(Relationship Database)之間的矛盾,即面向對象的操作和SQL語句之間的矛盾。

 

iBatis有Java版本和.NET兩個版本可供選擇。 

 

以下以Java本本為例講解。

 

原理

 

iBatis中需要涉及到以下幾部分

1. Object 面向對象的概念,表示某一類的實例(下圖中的Hashtable,Java/.Net object,Primitive)。

2. Table 數據庫表,用來以關系化的方式存儲Object(下圖中的數據庫部分)。

3. Object到Table的映射信息,例如將哪個Object映射到哪個表,

    Object的哪個屬性映射到表的哪個字段等(下圖中的SqlMap.xml)。

4. iBatis引擎(下圖中SqlMap config 和 SqlMap Statement兩部分之和)。

 

圖表如下

以Insert為例說明

第一步,SqlMap Statement根據SqlMap Config配置自己,配置信息包括數據庫信息,等內容。

第二步,將Java Object傳遞給SqlMap Statement

第三步,SqlMap Statement根據當前傳入Java Object在SqlMap.xml 文件中找到對應的配置信息

第四步,根據SqlMap.xml中的配置信息,自動生成 Insert Sql語句

第五部,針對當前配置的數據庫執行第四步中生成的Sql語句,將數據插入到數據庫中

 

以Select為例說明:

第一步,同上

第二步,將包含部分字段(查詢條件)內容的Java Object傳遞給SqlMap Statement

第三步,同上

第四步,根據SqlMap中的配置信息,生成Select Sql語句

第五部,執行第四步中生成的Sql語句

第六步,根據SqlMap.xml 文件中的配置信息,將第五步中查詢出來的ResultSet抓變為對應對象的列表,之后返回給調用端

 

具體使用

首先是一個SqlMap Config的配置文件,配置了數據庫等信息,例如:

 <?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMapConfig     
    PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"     
    "

<sqlMapConfig>

    <!-- 數據庫等信息 -->

  <transactionManager type="JDBC" commitRequired="false">
    <dataSource type="SIMPLE">
      <property name="JDBC.Driver" value="org.hsqldb.jdbcDriver"/>
      <property name="JDBC.ConnectionURL" value="jdbc:hsqldb:."/>
      <property name="JDBC.Username" value="sa"/>
      <property name="JDBC.Password" value="sa"/>
    </dataSource>
  </transactionManager>

    <!-- SqlMap.sql OR 映射文件的位置 -->

  <sqlMap resource="com/mydomain/data/Account.xml"/>
</sqlMapConfig>

Java Object對象

package com.mydomain.domain;

public class Account {

  private int id;
  private String firstName;
  private String lastName;
  private String emailAddress;

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }

  public String getEmailAddress() {
    return emailAddress;
  }

  public void setEmailAddress(String emailAddress) {
    this.emailAddress = emailAddress;
  }

}

Account對應到數據庫表的映射文件,即com/mydomain/data/Account.xml

 <?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap     
    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"     
    "

<sqlMap namespace="Account">

  <!-- 對類型定義的別名 -->
  <typeAlias alias="Account" type="com.mydomain.domain.Account"/>

  <!-- 數據庫中的字段名和Java Object中的屬性明的對應關系 -->
  <resultMap id="AccountResult" class="Account">
    <result property="id" column="ACC_ID"/>
    <result property="firstName" column="ACC_FIRST_NAME"/>
    <result property="lastName" column="ACC_LAST_NAME"/>
    <result property="emailAddress" column="ACC_EMAIL"/>
  </resultMap>

  <!-- 查詢 SQL語句 -->
  <select id="selectAllAccounts" resultMap="AccountResult">
    select * from ACCOUNT
  </select>

  <!-- 基于ID的查詢Sql語句 -->
  <select id="selectAccountById" parameterClass="int" resultClass="Account">
    select
      ACC_ID as id,
      ACC_FIRST_NAME as firstName,
      ACC_LAST_NAME as lastName,
      ACC_EMAIL as emailAddress
    from ACCOUNT
    where ACC_ID = #id#
  </select>
  
  <!-- 插入SQL語句 -->
  <insert id="insertAccount" parameterClass="Account">
    insert into ACCOUNT (
      ACC_ID,
      ACC_FIRST_NAME,
      ACC_LAST_NAME,
      ACC_EMAIL
    values (
      #id#, #firstName#, #lastName#, #emailAddress#
    )
  </insert>

  <!-- 更新SQL語句 -->
  <update id="updateAccount" parameterClass="Account">
    update ACCOUNT set
      ACC_FIRST_NAME = #firstName#,
      ACC_LAST_NAME = #lastName#,
      ACC_EMAIL = #emailAddress#
    where
      ACC_ID = #id#
  </update>

  <!-- 刪除SQL語句 -->
  <delete id="deleteAccountById" parameterClass="int">
    delete from ACCOUNT where ACC_ID = #id#
  </delete>

</sqlMap>

 

使用代碼:

首先裝在配置文件:

try {
  Reader reader = Resources.getResourceAsReader("com/mydomain/data/SqlMapConfig.xml");
  sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader);
  reader.close();
} catch (IOException e) {
  // Fail fast.
  throw new RuntimeException("Something bad happened while building the SqlMapClient instance." + e, e);
}

各種方法的使用:

查詢列表,返回List

sqlMapper.queryForList("selectAllAccounts");
查詢對象

(Account) sqlMapper.queryForObject("selectAccountById", id);
插入

sqlMapper.insert("insertAccount", account);
更新

sqlMapper.update("updateAccount", account);
刪除

sqlMapper.delete("deleteAccount", id);

 

在Struts2環境中結合Springframework使用ibatis

 

在Struts2環境中結合Springframework使用ibatis

想要使用ibatis必須首先定義數據源,這里使用DBCP數據源。

DBCP是apache jakarta下面的一個opensouce 名字叫做Database Connection Pool

使用DBCP需要將以下兩個文件拷貝到WEB-INF/lib目錄下:

commons-dbcp.jar

commons-pool.jar


在Spring配置文件中可以使用Ioc的方式配置數據庫連接池(DBCP)


通常將數據庫鏈接信息放在database.properties文件中,該文件通常放在WEB-INF目錄下

文件內容為:

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/teamware
jdbc.username=teamware
jdbc.password=teamware


為了在spring配置文件中讀取這些信息需要如下配置:

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
 <property name="locations">
  <list>
      <value>WEB-INF/database.properties</value>
  </list>
 </property>
</bean>

 

配置數據庫鏈接池:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
 <property name="driverClassName" value="${jdbc.driverClassName}"/>
 <property name="url" value="${jdbc.url}"/>
 <property name="username" value="${jdbc.username}"/>
 <property name="password" value="${jdbc.password}"/>
</bean>

 

其中${}部分內容引用了database.properties文件中的內容。

 

配置ibatis

配置ibatis需要的sqlmap-config.xml和TodoVO.xml

sqlmap-config.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMapConfig     
    PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"     
    "
http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
 <sqlMap resource="com/jpleasure/teamware/vo/TodoVO.xml" />

</sqlMapConfig>

 

TodoVO.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap     
    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"     
    "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="TodoVO">

  <typeAlias alias="TodoVO" type="com.jpleasure.teamware.vo.TodoVO"/>

  <resultMap id="TodoVOResult" class="TodoVO">
    <result property="startDate" column="start_date"/>
    <result property="startTime" column="start_time"/>
    <result property="endDate" column="end_date"/>
    <result property="endTime" column="end_time"/>
   
    <result property="status" column="status"/>
    <result property="priority" column="priority"/>
    <result property="category" column="category"/>
   
 <result property="title" column="title"/>
 <result property="content" column="content"/>
  </resultMap>

  <select id="selectAllTodoVOs" resultMap="TodoVOResult">
    select * from todo
  </select>

</sqlMap>

 

 

package com.jpleasure.teamware.dao;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.ibatis.sqlmap.client.SqlMapClient;
import com.jpleasure.teamware.vo.TodoVO;

public class TodoDao {
 private SqlMapClient sqlMap = null;
 
 public SqlMapClient getSqlMap() {
  return sqlMap;
 }

 public void setSqlMap(SqlMapClient sqlMap) {
  this.sqlMap = sqlMap;
 }

 public List<TodoVO> listAll() {

  List todos = new ArrayList();
  try {
   todos = sqlMap.queryForList("selectAllTodoVOs");
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

  return todos;
 }

 public TodoVO insert(TodoVO todo) {
  return todo;
 }

 public TodoVO update(TodoVO todo) {
  return todo;
 }

 public TodoVO delete(TodoVO todo) {
  return todo;
 }
}

配置DAO

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC
 "-//SPRING//DTD BEAN//EN"
 "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
 <bean id="todo" class="com.jpleasure.teamware.action.TodoAction"
  singleton="false">
  <property name="todoLogic" ref="todoLogic"></property>
 </bean>
 <bean id="todoLogic"
  class="com.jpleasure.teamware.logic.TodoLogic">
  <property name="todoDao" ref="todoDao"></property>
 </bean>
 <bean id="todoDao" class="com.jpleasure.teamware.dao.TodoDao">
  <property name="sqlMap" ref="sqlMapClient"></property>
 </bean>

</beans>

 

使用DAO

package com.jpleasure.teamware.logic;

import java.util.List;

import com.jpleasure.teamware.dao.TodoDao;
import com.jpleasure.teamware.vo.TodoVO;

public class TodoLogic {
 
 /****************************************
  * TodoDao
  ****************************************/
 
 
 private TodoDao todoDao;
 
 public TodoDao getTodoDao() {
  return todoDao;
 }

 public void setTodoDao(TodoDao todoDao) {
  this.todoDao = todoDao;
 }

 /****************************************
  * Logic Method
  ****************************************/
 
 public List<TodoVO> listAll() {
  List<TodoVO> todos = todoDao.listAll();
 
  return todos;
 }
 
 public TodoVO insert(TodoVO todo) {
  return todo;
 }
 
 public TodoVO update(TodoVO todo) {
  return todo;
 }
 public TodoVO delete(TodoVO todo) {
  return todo;
 }
}

 

 

由于使用了Spring配置的DBCP,所以其中的數據庫鏈接部分不需要再配置。

 

只需要配置使用的映射文件即可。

 

spring中配置ibatis

<bean id="sqlMapClient"
 class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
 <property name="configLocation" value="sqlmap-config.xml"/>
 <property name="dataSource" ref="dataSource" />
</bean>

 

使用Ibatis做數據庫訪問
定義DAO



ExtJS教程- Hibernate教程-Struts2 教程-Lucene教程