iBATIS - 快速指南



iBATIS - 概述

iBATIS是一個持久化框架,它自動對映Java、.NET和Ruby on Rails中的SQL資料庫和物件。透過將SQL語句打包在XML配置檔案中,對映與應用程式邏輯解耦。

iBATIS是一個輕量級的框架和持久化API,適用於持久化POJO(普通舊Java物件)。

iBATIS是一種資料對映器,負責在類屬性和資料庫表列之間對映引數和結果。

iBATIS與其他持久化框架(如Hibernate)的一個顯著區別在於,iBATIS強調使用SQL,而其他框架通常使用自定義查詢語言,如Hibernate查詢語言(HQL)或Enterprise JavaBeans查詢語言(EJB QL)。

iBATIS設計理念

iBATIS帶有以下設計理念:

  • 簡單性 - iBATIS被廣泛認為是當今最簡單的持久化框架之一。

  • 快速開發 - iBATIS盡其所能促進超快速開發。

  • 可移植性 - iBATIS可以應用於幾乎任何語言或平臺,例如Java、Ruby和C# for Microsoft .NET。

  • 獨立介面 - iBATIS提供資料庫獨立的介面和API,幫助應用程式的其餘部分獨立於任何與持久化相關的資源。

  • 開源 - iBATIS是免費的開源軟體。

iBATIS的優勢

iBATIS提供以下優勢:

  • 支援儲存過程 - iBATIS以儲存過程的形式封裝SQL,使業務邏輯保持在資料庫之外,應用程式更容易部署和測試,並且更具可移植性。

  • 支援內聯SQL - 不需要預編譯器,您可以完全訪問SQL的所有功能。

  • 支援動態SQL - iBATIS提供基於引數動態構建SQL查詢的功能。

  • 支援O/RM - iBATIS支援許多與O/RM工具相同的功能,例如延遲載入、聯接獲取、快取、執行時程式碼生成和繼承。

iBATIS在開發面向資料庫的應用程式時使用JAVA程式語言。在繼續學習之前,請確保您瞭解過程式和麵向物件程式設計的基礎知識 - 控制結構、資料結構和變數、類、物件等。

要詳細瞭解JAVA,您可以參考我們的JAVA 教程

iBATIS - 環境

在開始實際開發工作之前,您需要為iBATIS設定一個合適的環境。本章說明如何為iBATIS設定一個工作環境。

iBATIS安裝

執行以下簡單步驟,在您的Linux機器上安裝iBATIS:

  • 下載iBATIS下載最新版本的iBATIS。

  • 解壓縮下載的檔案以從捆綁包中提取.jar檔案,並將它們儲存在適當的lib目錄中。

  • 在提取的.jar檔案(s)上適當地設定PATH和CLASSPATH變數。

$ unzip ibatis-2.3.4.726.zip
inflating: META-INF/MANIFEST.MF
   creating: doc/
   creating: lib/
	
   creating: simple_example/
   creating: simple_example/com/
   creating: simple_example/com/mydomain/
   creating: simple_example/com/mydomain/data/
   creating: simple_example/com/mydomain/domain/
	
   creating: src/
	
  inflating: doc/dev-javadoc.zip
  inflating: doc/user-javadoc.zip
  
  inflating: jar-dependencies.txt
  inflating: lib/ibatis-2.3.4.726.jar
  inflating: license.txt
  inflating: notice.txt
  inflating: release.txt
  
$pwd
/var/home/ibatis
$set PATH=$PATH:/var/home/ibatis/
$set CLASSPATH=$CLASSPATH:/var/home/ibatis\
      /lib/ibatis-2.3.4.726.jar

資料庫設定

使用以下語法在任何MySQL資料庫中建立一個EMPLOYEE表:

mysql> CREATE TABLE EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

建立SqlMapConfig.xml

考慮以下內容:

  • 我們將使用JDBC訪問資料庫testdb

  • MySQL的JDBC驅動程式是“com.mysql.jdbc.Driver”。

  • 連線URL是“jdbc:mysql://:3306/testdb”。

  • 我們將分別使用“root”和“root”作為使用者名稱和密碼。

  • 所有操作的SQL語句對映將在“Employee.xml”中描述。

基於上述假設,我們必須建立一個名為SqlMapConfig.xml的XML配置檔案,其內容如下。在這裡,您需要提供iBatis所需的所有配置:

重要的是SqlMapConfig.xml和Employee.xml這兩個檔案都應該位於類路徑中。目前,我們將保持Employee.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>
   <settings useStatementNamespaces="true"/>
	
   <transactionManager type="JDBC">
      <dataSource type="SIMPLE">
		
         <property name="JDBC.Driver" value="com.mysql.jdbc.Driver"/>
         <property name="JDBC.ConnectionURL" value="jdbc:mysql://:3306/testdb"/>
         <property name="JDBC.Username" value="root"/>
         <property name="JDBC.Password" value="root"/>
			
      </dataSource>
   </transactionManager>
	
   <sqlMap resource="Employee.xml"/> 
</sqlMapConfig>

您也可以使用SqlMapConfig.xml檔案設定以下可選屬性:

<property name="JDBC.AutoCommit" value="true"/>
<property name="Pool.MaximumActiveConnections" value="10"/>
<property name="Pool.MaximumIdleConnections" value="5"/>
<property name="Pool.MaximumCheckoutTime" value="150000"/> 
<property name="Pool.MaximumTimeToWait" value="500"/> 
<property name="Pool.PingQuery" value="select 1 from Employee"/> 
<property name="Pool.PingEnabled" value="false"/>

iBATIS - 建立操作

要使用iBATIS執行任何建立、讀取、更新和刪除(CRUD)操作,您需要為該表建立一個普通舊Java物件(POJO)類。此類描述將“建模”資料庫錶行的物件。

POJO類將具有執行所需操作所需的所有方法的實現。

假設我們在MySQL中具有以下EMPLOYEE表:

CREATE TABLE EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

Employee POJO類

我們將如下在Employee.java檔案中建立一個Employee類:

public class Employee {
   private int id;
   private String first_name; 
   private String last_name;   
   private int salary;  

   /* Define constructors for the Employee class. */
   public Employee() {}
  
   public Employee(String fname, String lname, int salary) {
      this.first_name = fname;
      this.last_name = lname;
      this.salary = salary;
   }
} /* End of Employee */

您可以定義方法來設定表中的各個欄位。下一章將說明如何獲取各個欄位的值。

Employee.xml檔案

要使用iBATIS定義SQL對映語句,我們將使用<insert>標籤,並在該標籤定義內,我們將定義一個“id”,該“id”將在IbatisInsert.java檔案中用於對資料庫執行SQL INSERT查詢。

<?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="Employee"> 

   <insert id="insert" parameterClass="Employee">
      insert into EMPLOYEE(first_name, last_name, salary)
      values (#first_name#, #last_name#, #salary#)

      <selectKey resultClass="int" keyProperty="id">
         select last_insert_id() as id
      </selectKey>
   </insert> 

</sqlMap>

這裡parameterClass -可以根據需要取值為字串、int、float、double或任何類物件。在本例中,我們在呼叫SqlMap類的insert方法時將傳遞Employee物件作為引數。

如果您的資料庫表使用IDENTITY、AUTO_INCREMENT或SERIAL列,或者您已定義SEQUENCE/GENERATOR,則可以在<insert>語句中使用<selectKey>元素來使用或返回該資料庫生成的value。

IbatisInsert.java檔案

此檔案將具有應用程式級別的邏輯,用於在Employee表中插入記錄:

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

import java.io.*;
import java.sql.SQLException;
import java.util.*;

public class IbatisInsert{
   public static void main(String[] args)throws IOException,SQLException{
      Reader rd = Resources.getResourceAsReader("SqlMapConfig.xml");
      SqlMapClient smc = SqlMapClientBuilder.buildSqlMapClient(rd);

      /* This would insert one record in Employee table. */
      System.out.println("Going to insert record.....");
      Employee em = new Employee("Zara", "Ali", 5000);

      smc.insert("Employee.insert", em);

      System.out.println("Record Inserted Successfully ");
   }
} 

編譯和執行

以下是編譯和執行上述軟體的步驟。在進行編譯和執行之前,請確保已正確設定PATH和CLASSPATH。

  • 如上所示建立Employee.xml。
  • 如上所示建立Employee.java並編譯它。
  • 如上所示建立IbatisInsert.java並編譯它。
  • 執行IbatisInsert二進位制檔案以執行程式。

您將獲得以下結果,並且將在EMPLOYEE表中建立一個記錄。

$java IbatisInsert
Going to insert record.....
Record Inserted Successfully

如果檢查EMPLOYEE表,它應該顯示以下結果:

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
|  1 | Zara       | Ali       |   5000 |
+----+------------+-----------+--------+
1 row in set (0.00 sec)

iBATIS - 讀取操作

在上一章中,我們討論瞭如何使用iBATIS對錶執行CREATE操作。本章說明如何使用iBATIS讀取表。

我們在MySQL中具有以下EMPLOYEE表:

CREATE TABLE EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

此表只有一條記錄,如下所示:

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
|  1 | Zara       | Ali       |   5000 |
+----+------------+-----------+--------+
1 row in set (0.00 sec)

Employee POJO類

要執行讀取操作,我們將如下修改Employee.java中的Employee類:

public class Employee {
   private int id;
   private String first_name; 
   private String last_name;   
   private int salary;  

   /* Define constructors for the Employee class. */
   public Employee() {}
  
   public Employee(String fname, String lname, int salary) {
      this.first_name = fname;
      this.last_name = lname;
      this.salary = salary;
   }

   /* Here are the method definitions */
   public int getId() {
      return id;
   }
	
   public String getFirstName() {
      return first_name;
   }
	
   public String getLastName() {
      return last_name;
   }
	
   public int getSalary() {
      return salary;
   }
	
} /* End of Employee */

Employee.xml檔案

要使用iBATIS定義SQL對映語句,我們將新增<select>標籤到Employee.xml檔案中,並在該標籤定義內,我們將定義一個“id”,該“id”將在IbatisRead.java檔案中用於對資料庫執行SQL SELECT查詢。

<?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="Employee">

   <insert id="insert" parameterClass="Employee">
      INSERT INTO EMPLOYEE(first_name, last_name, salary)
      values (#first_name#, #last_name#, #salary#)

      <selectKey resultClass="int" keyProperty="id">
         select last_insert_id() as id
      </selectKey>
   </insert>
	
   <select id="getAll" resultClass="Employee">
      SELECT * FROM EMPLOYEE
   </select>
	
</sqlMap>

在這裡,我們沒有對SQL SELECT語句使用WHERE子句。我們將在下一章演示如何將WHERE子句與SELECT語句一起使用,以及如何將值傳遞給該WHERE子句。

IbatisRead.java檔案

此檔案具有應用程式級別的邏輯,用於從Employee表中讀取記錄:

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

import java.io.*;
import java.sql.SQLException;
import java.util.*;

public class IbatisRead{
   public static void main(String[] args)throws IOException,SQLException{
      Reader rd = Resources.getResourceAsReader("SqlMapConfig.xml");
      SqlMapClient smc = SqlMapClientBuilder.buildSqlMapClient(rd);

      /* This would read all records from the Employee table. */
      System.out.println("Going to read records.....");
      List <Employee> ems = (List<Employee>)
         smc.queryForList("Employee.getAll", null);
      Employee em = null;
		
      for (Employee e : ems) {
         System.out.print("  " + e.getId());
         System.out.print("  " + e.getFirstName());
         System.out.print("  " + e.getLastName());
         System.out.print("  " + e.getSalary());
         em = e; 
         System.out.println("");
      }    
		
      System.out.println("Records Read Successfully ");
   }
} 

編譯和執行

以下是編譯和執行上述軟體的步驟。在進行編譯和執行之前,請確保已正確設定PATH和CLASSPATH。

  • 如上所示建立Employee.xml。
  • 如上所示建立Employee.java並編譯它。
  • 如上所示建立IbatisRead.java並編譯它。
  • 執行IbatisRead二進位制檔案以執行程式。

您將獲得以下結果,並且將從EMPLOYEE表中讀取一條記錄,如下所示:

Going to read records.....
   1  Zara  Ali  5000
Record Reads Successfully

iBATIS - 更新操作

在上一章中,我們討論瞭如何使用iBATIS對錶執行READ操作。本章說明如何使用iBATIS更新表中的記錄。

我們在MySQL中具有以下EMPLOYEE表:

CREATE TABLE EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

此表只有一條記錄,如下所示:

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
|  1 | Zara       | Ali       |   5000 |
+----+------------+-----------+--------+
1 row in set (0.00 sec)

Employee POJO類

要執行更新操作,您需要如下修改Employee.java檔案:

public class Employee {
   private int id;
   private String first_name; 
   private String last_name;   
   private int salary;  

   /* Define constructors for the Employee class. */
   public Employee() {}
  
   public Employee(String fname, String lname, int salary) {
      this.first_name = fname;
      this.last_name = lname;
      this.salary = salary;
   }

   /* Here are the required method definitions */
   public int getId() {
      return id;
   }
	
   public void setId(int id) {
      this.id = id;
   }
	
   public String getFirstName() {
      return first_name;
   }
	
   public void setFirstName(String fname) {
      this.first_name = fname;
   }
	
   public String getLastName() {
      return last_name;
   }
   public void setlastName(String lname) {
      this.last_name = lname;
   }
	
   public int getSalary() {
      return salary;
   }
	
   public void setSalary(int salary) {
      this.salary = salary;
   }

} /* End of Employee */

Employee.xml檔案

要使用iBATIS定義SQL對映語句,我們將新增<update>標籤到Employee.xml中,並在該標籤定義內,我們將定義一個“id”,該“id”將在IbatisUpdate.java檔案中用於對資料庫執行SQL UPDATE查詢。

<?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="Employee">

   <insert id="insert" parameterClass="Employee">
      INSERT INTO EMPLOYEE(first_name, last_name, salary)
      values (#first_name#, #last_name#, #salary#)

      <selectKey resultClass="int" keyProperty="id">
         select last_insert_id() as id
      </selectKey>
   </insert>

   <select id="getAll" resultClass="Employee">
      SELECT * FROM EMPLOYEE
   </select>

   <update id="update" parameterClass="Employee">
      UPDATE EMPLOYEE
      SET    first_name = #first_name#
      WHERE  id = #id#
   </update>
	
</sqlMap>

IbatisUpdate.java檔案

此檔案具有應用程式級別的邏輯,用於將記錄更新到Employee表中:

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

import java.io.*;
import java.sql.SQLException;
import java.util.*;

public class IbatisUpdate{
   public static void main(String[] args)
   throws IOException,SQLException{
      Reader rd = Resources.getResourceAsReader("SqlMapConfig.xml");
      SqlMapClient smc = SqlMapClientBuilder.buildSqlMapClient(rd);

      /* This would update one record in Employee table. */
      System.out.println("Going to update record.....");
      Employee rec = new Employee();
      rec.setId(1);
      rec.setFirstName( "Roma");
      smc.update("Employee.update", rec );
      System.out.println("Record updated Successfully ");

      System.out.println("Going to read records.....");
      List <Employee> ems = (List<Employee>)
         smc.queryForList("Employee.getAll", null);
      Employee em = null;
		
      for (Employee e : ems) {
         System.out.print("  " + e.getId());
         System.out.print("  " + e.getFirstName());
         System.out.print("  " + e.getLastName());
         System.out.print("  " + e.getSalary());
         em = e; 
         System.out.println("");
      }    

      System.out.println("Records Read Successfully ");
   }
} 

編譯和執行

以下是編譯和執行上述軟體的步驟。在進行編譯和執行之前,請確保已正確設定PATH和CLASSPATH。

  • 如上所示建立Employee.xml。
  • 如上所示建立Employee.java並編譯它。
  • 如上所示建立IbatisUpdate.java並編譯它。
  • 執行IbatisUpdate二進位制檔案以執行程式。

您將獲得以下結果,並且將更新EMPLOYEE表中的記錄,稍後將從EMPLOYEE表中讀取同一記錄。

Going to update record.....
Record updated Successfully
Going to read records.....
   1  Roma  Ali  5000
Records Read Successfully

iBATIS - 刪除操作

本章說明如何使用iBATIS從表中刪除記錄。

我們在MySQL中具有以下EMPLOYEE表:

CREATE TABLE EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

假設此表有兩條記錄,如下所示:

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
|  1 | Zara       | Ali       |   5000 |
|  2 | Roma       | Ali       |   3000 |
+----+------------+-----------+--------+
2 row in set (0.00 sec)

Employee POJO類

要執行刪除操作,您無需修改Employee.java檔案。讓我們保持它與上一章中的狀態。

public class Employee {
   private int id;
   private String first_name; 
   private String last_name;   
   private int salary;  

   /* Define constructors for the Employee class. */
   public Employee() {}
  
   public Employee(String fname, String lname, int salary) {
      this.first_name = fname;
      this.last_name = lname;
      this.salary = salary;
   }

   /* Here are the required method definitions */
   public int getId() {
      return id;
   }
	
   public void setId(int id) {
      this.id = id;
   }
	
   public String getFirstName() {
      return first_name;
   }
	
   public void setFirstName(String fname) {
      this.first_name = fname;
   }
	
   public String getLastName() {
      return last_name;
   }
	
   public void setlastName(String lname) {
      this.last_name = lname;
   }
	
   public int getSalary() {
      return salary;
   }
	
   public void setSalary(int salary) {
      this.salary = salary;
   }

} /* End of Employee */

Employee.xml檔案

要使用iBATIS定義SQL對映語句,我們將新增<delete>標籤到Employee.xml中,並在該標籤定義內,我們將定義一個“id”,該“id”將在IbatisDelete.java檔案中用於對資料庫執行SQL DELETE查詢。

<?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="Employee">

   <insert id="insert" parameterClass="Employee">
      INSERT INTO EMPLOYEE(first_name, last_name, salary)
      values (#first_name#, #last_name#, #salary#)

      <selectKey resultClass="int" keyProperty="id">
         select last_insert_id() as id
      </selectKey>
   </insert>

   <select id="getAll" resultClass="Employee">
      SELECT * FROM EMPLOYEE
   </select>

   <update id="update" parameterClass="Employee">
      UPDATE EMPLOYEE
      SET    first_name = #first_name#
      WHERE  id = #id#
   </update>

   <delete id="delete" parameterClass="int">
      DELETE FROM EMPLOYEE
      WHERE  id = #id#
   </delete>

</sqlMap>

IbatisDelete.java檔案

此檔案具有應用程式級別的邏輯,用於從Employee表中刪除記錄:

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

import java.io.*;
import java.sql.SQLException;
import java.util.*;

public class IbatisDelete{
   public static void main(String[] args)
   throws IOException,SQLException{
      Reader rd = Resources.getResourceAsReader("SqlMapConfig.xml");
      SqlMapClient smc = SqlMapClientBuilder.buildSqlMapClient(rd);

      /* This would delete one record in Employee table. */
      System.out.println("Going to delete record.....");
      int id = 1;

      smc.delete("Employee.delete", id );
      System.out.println("Record deleted Successfully ");

      System.out.println("Going to read records.....");
      List <Employee> ems = (List<Employee>)
         smc.queryForList("Employee.getAll", null);
      Employee em = null;
		
      for (Employee e : ems) {
         System.out.print("  " + e.getId());
         System.out.print("  " + e.getFirstName());
         System.out.print("  " + e.getLastName());
         System.out.print("  " + e.getSalary());
         em = e; 
         System.out.println("");
      }    

      System.out.println("Records Read Successfully ");
   }
} 

編譯和執行

以下是編譯和執行上述軟體的步驟。在進行編譯和執行之前,請確保已正確設定PATH和CLASSPATH。

  • 如上所示建立Employee.xml。
  • 如上所示建立Employee.java並編譯它。
  • 如上所示建立IbatisDelete.java並編譯它。
  • 執行IbatisDelete二進位制檔案以執行程式。

您將獲得以下結果,並且ID = 1的記錄將從EMPLOYEE表中刪除,其餘記錄將被讀取。

Going to delete record.....
Record deleted Successfully
Going to read records.....
   2  Roma  Ali  3000
Records Read Successfully

iBATIS - 結果對映

resultMap 元素是 iBATIS 中最重要和最強大的元素。使用 iBATIS ResultMap,您可以減少高達 90% 的 JDBC 程式碼,在某些情況下,它允許您執行 JDBC 甚至不支援的操作。

ResultMaps 的設計使得簡單的語句根本不需要顯式的結果對映,而更復雜的語句只需要描述關係所絕對必要的對映。

本章僅對 iBATIS ResultMaps 做了一個簡單的介紹。

我們在MySQL中具有以下EMPLOYEE表:

CREATE TABLE EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

此表包含以下兩條記錄 -

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
|  1 | Zara       | Ali       |   5000 |
|  2 | Roma       | Ali       |   3000 |
+----+------------+-----------+--------+
2 row in set (0.00 sec)

Employee POJO類

要使用 iBATIS ResultMap,您無需修改 Employee.java 檔案。讓我們保持它與上一章相同。

public class Employee {
   private int id;
   private String first_name; 
   private String last_name;   
   private int salary;  

   /* Define constructors for the Employee class. */
   public Employee() {}
  
   public Employee(String fname, String lname, int salary) {
      this.first_name = fname;
      this.last_name = lname;
      this.salary = salary;
   }

   /* Here are the required method definitions */
   public int getId() {
      return id;
   }
	
   public void setId(int id) {
      this.id = id;
   }
	
   public String getFirstName() {
      return first_name;
   }
	
   public void setFirstName(String fname) {
      this.first_name = fname;
   }
	
   public String getLastName() {
      return last_name;
   }
	
   public void setlastName(String lname) {
      this.last_name = lname;
   }
	
   public int getSalary() {
      return salary;
   }
	
   public void setSalary(int salary) {
      this.salary = salary;
   }

} /* End of Employee */

Employee.xml檔案

在這裡,我們將修改 Employee.xml 以引入 <resultMap></resultMap> 標籤。此標籤將具有一個 id,該 id 是在我們的 <select> 標籤的 resultMap 屬性中執行此 resultMap 所必需的。

<?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="Employee">

   <!-- Perform Insert Operation -->
	
   <insert id="insert" parameterClass="Employee">
      INSERT INTO EMPLOYEE(first_name, last_name, salary)
      values (#first_name#, #last_name#, #salary#)

      <selectKey resultClass="int" keyProperty="id">
         select last_insert_id() as id
      </selectKey>
   </insert>

   <!-- Perform Read Operation -->
   <select id="getAll" resultClass="Employee">
      SELECT * FROM EMPLOYEE
   </select>

   <!-- Perform Update Operation -->
   <update id="update" parameterClass="Employee">
      UPDATE EMPLOYEE
      SET    first_name = #first_name#
      WHERE  id = #id#
    </update>

   <!-- Perform Delete Operation -->
   <delete id="delete" parameterClass="int">
      DELETE FROM EMPLOYEE
      WHERE  id = #id#
   </delete>

   <!-- Using ResultMap -->
   <resultMap id="result" class="Employee">
      <result property="id" column="id"/>
      <result property="first_name" column="first_name"/>
      <result property="last_name" column="last_name"/>
      <result property="salary" column="salary"/>
   </resultMap> 
	
   <select id="useResultMap" resultMap="result">
      SELECT * FROM EMPLOYEE
      WHERE id=#id#
   </select>

</sqlMap>

IbatisResultMap.java 檔案

此檔案包含應用程式級別的邏輯,用於使用 ResultMap 從 Employee 表中讀取記錄 -

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

import java.io.*;
import java.sql.SQLException;
import java.util.*;

public class IbatisResultMap{
   public static void main(String[] args)
   throws IOException,SQLException{
      Reader rd = Resources.getResourceAsReader("SqlMapConfig.xml");
      SqlMapClient smc = SqlMapClientBuilder.buildSqlMapClient(rd);

      int id = 1;
      System.out.println("Going to read record.....");
      Employee e = (Employee)smc.queryForObject ("Employee.useResultMap", id);

      System.out.println("ID:  " + e.getId());
      System.out.println("First Name:  " + e.getFirstName());
      System.out.println("Last Name:  " + e.getLastName());
      System.out.println("Salary:  " + e.getSalary());
      System.out.println("Record read Successfully ");
   }
} 

編譯和執行

以下是編譯和執行上述軟體的步驟。在進行編譯和執行之前,請確保已正確設定PATH和CLASSPATH。

  • 如上所示建立Employee.xml。
  • 如上所示建立Employee.java並編譯它。
  • 建立如上所示的 IbatisResultMap.java 並編譯它。
  • 執行 IbatisResultMap 二進位制檔案以執行程式。

您將獲得以下結果,該結果是對 EMPLOYEE 表的讀取操作。

Going to read record.....
ID:  1
First Name:  Zara
Last Name:  Ali
Salary:  5000
Record read Successfully

iBATIS - 儲存過程

您可以使用 iBATIS 配置呼叫儲存過程。首先,讓我們瞭解如何在 MySQL 中建立儲存過程。

我們在MySQL中具有以下EMPLOYEE表:

CREATE TABLE EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

讓我們在 MySQL 資料庫中建立以下儲存過程 -

DELIMITER $$

   DROP PROCEDURE IF EXISTS `testdb`.`getEmp` $$
   CREATE PROCEDURE `testdb`.`getEmp` 
   (IN empid INT)
	
   BEGIN
      SELECT * FROM EMPLOYEE
      WHERE ID = empid;
   END $$

DELIMITER;

讓我們考慮 EMPLOYEE 表包含以下兩條記錄 -

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
|  1 | Zara       | Ali       |   5000 |
|  2 | Roma       | Ali       |   3000 |
+----+------------+-----------+--------+
2 row in set (0.00 sec)

Employee POJO類

要使用儲存過程,您無需修改 Employee.java 檔案。讓我們保持它與上一章相同。

public class Employee {
   private int id;
   private String first_name; 
   private String last_name;   
   private int salary;  

   /* Define constructors for the Employee class. */
   public Employee() {}
  
   public Employee(String fname, String lname, int salary) {
      this.first_name = fname;
      this.last_name = lname;
      this.salary = salary;
   }

   /* Here are the required method definitions */
   public int getId() {
      return id;
   }
	
   public void setId(int id) {
      this.id = id;
   }
	
   public String getFirstName() {
      return first_name;
   }
	
   public void setFirstName(String fname) {
      this.first_name = fname;
   }
	
   public String getLastName() {
      return last_name;
   }
	
   public void setlastName(String lname) {
      this.last_name = lname;
   }
	
   public int getSalary() {
      return salary;
   }
	
   public void setSalary(int salary) {
      this.salary = salary;
   }

} /* End of Employee */

Employee.xml檔案

在這裡,我們將修改 Employee.xml 以引入 <procedure></procedure> 和 <parameterMap></parameterMap> 標籤。這裡的 <procedure></procedure> 標籤將具有一個 id,我們將在應用程式中使用它來呼叫儲存過程。

<?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="Employee">

   <!-- Perform Insert Operation -->
   <insert id="insert" parameterClass="Employee">
      INSERT INTO EMPLOYEE(first_name, last_name, salary)
      values (#first_name#, #last_name#, #salary#)

      <selectKey resultClass="int" keyProperty="id">
         select last_insert_id() as id
      </selectKey>
   </insert>

   <!-- Perform Read Operation -->
   <select id="getAll" resultClass="Employee">
      SELECT * FROM EMPLOYEE
   </select>

   <!-- Perform Update Operation -->
   <update id="update" parameterClass="Employee">
      UPDATE EMPLOYEE
      SET    first_name = #first_name#
      WHERE  id = #id#
   </update>

   <!-- Perform Delete Operation -->
   <delete id="delete" parameterClass="int">
      DELETE FROM EMPLOYEE
      WHERE  id = #id#
   </delete>

   <!-- To call stored procedure. -->
   <procedure id="getEmpInfo" resultClass="Employee" parameterMap="getEmpInfoCall">
      { call getEmp( #acctID# ) } 
   </procedure>
	
   <parameterMap id="getEmpInfoCall" class="map">
      <parameter property="acctID" jdbcType="INT" javaType="java.lang.Integer" mode="IN"/>
   </parameterMap>

</sqlMap>

IbatisSP.java 檔案

此檔案包含應用程式級別的邏輯,用於使用 ResultMap 從 Employee 表中讀取員工姓名 -

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

import java.io.*;
import java.sql.SQLException;
import java.util.*;

public class IbatisSP{
   public static void main(String[] args)
   throws IOException,SQLException{
      Reader rd = Resources.getResourceAsReader("SqlMapConfig.xml");
      SqlMapClient smc = SqlMapClientBuilder.buildSqlMapClient(rd);

      int id = 1;
      System.out.println("Going to read employee name.....");
      Employee e = (Employee) smc.queryForObject ("Employee.getEmpInfo", id);

      System.out.println("First Name:  " + e.getFirstName());
      System.out.println("Record name Successfully ");
   }
} 

編譯和執行

以下是編譯和執行上述軟體的步驟。在進行編譯和執行之前,請確保已正確設定PATH和CLASSPATH。

  • 如上所示建立Employee.xml。
  • 如上所示建立Employee.java並編譯它。
  • 建立如上所示的 IbatisSP.java 並編譯它。
  • 執行 IbatisSP 二進位制檔案以執行程式。

您將獲得以下結果

Going to read employee name.....
First Name:  Zara
Record name Successfully

iBATIS - 動態SQL

動態 SQL 是 iBATIS 的一項非常強大的功能。有時您必須根據引數物件的狀態更改 WHERE 子句條件。在這種情況下,iBATIS 提供了一組動態 SQL 標籤,可以在對映語句中使用這些標籤來增強 SQL 的可重用性和靈活性。

所有邏輯都使用一些額外的標籤放在 .XML 檔案中。以下是一個示例,其中 SELECT 語句將以兩種方式工作 -

如果傳遞 ID,則它將返回與該 ID 對應的所有記錄。

否則,它將返回所有員工 ID 設定為 NULL 的記錄。

<?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="Employee">

   <select id="findByID" resultClass="Employee">
      SELECT * FROM EMPLOYEE
		
      <dynamic prepend="WHERE ">
         <isNull property="id">
            id IS NULL
         </isNull>
			
         <isNotNull property="id">
            id = #id#
         </isNotNull>
      </dynamic>
		
   </select>
</sqlMap>

您可以使用 <isNotEmpty> 標籤檢查條件,如下所示。此處僅當傳遞的屬性不為空時才會新增條件。

..................
<select id="findByID" resultClass="Employee">
   SELECT * FROM EMPLOYEE
	
   <dynamic prepend="WHERE ">
      <isNotEmpty property="id">
         id = #id#
      </isNotEmpty>
   </dynamic>
	
</select>
..................

如果您想要一個可以查詢員工的 id 和/或姓名的查詢,您的 SELECT 語句如下 -

..................
<select id="findByID" resultClass="Employee">
   SELECT * FROM EMPLOYEE
	
   <dynamic prepend="WHERE ">
      <isNotEmpty prepend="AND" property="id">
         id = #id#
      </isNotEmpty>
		
      <isNotEmpty prepend="OR" property="first_name">
         first_name = #first_name#
      </isNotEmpty>
   </dynamic>
</select>
..................

動態 SQL 示例

以下示例顯示瞭如何使用動態 SQL 編寫 SELECT 語句。假設我們在 MySQL 中有以下 EMPLOYEE 表 -

CREATE TABLE EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

讓我們假設此表只有一條記錄,如下所示 -

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
|  1 | Zara       | Ali       |   5000 |
+----+------------+-----------+--------+
1 row in set (0.00 sec)

Employee POJO類

要執行讀取操作,讓我們在 Employee.java 中有一個 Employee 類,如下所示 -

public class Employee {
   private int id;
   private String first_name; 
   private String last_name;   
   private int salary;  

   /* Define constructors for the Employee class. */
   public Employee() {}
  
   public Employee(String fname, String lname, int salary) {
      this.first_name = fname;
      this.last_name = lname;
      this.salary = salary;
   }

   /* Here are the method definitions */
   public int getId() {
      return id;
   }
	
   public String getFirstName() {
      return first_name;
   }
	
   public String getLastName() {
      return last_name;
   }
	
   public int getSalary() {
      return salary;
   }
	
} /* End of Employee */

Employee.xml檔案

要使用 iBATIS 定義 SQL 對映語句,我們將新增以下修改後的 <select> 標籤到 Employee.xml 中,並在該標籤定義內,我們將定義一個 "id",它將在 IbatisReadDy.java 中用於對資料庫執行動態 SQL SELECT 查詢。

<?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="Employee">
   <select id="findByID" resultClass="Employee">
      SELECT * FROM EMPLOYEE
	
      <dynamic prepend="WHERE ">
         <isNotNull property="id">
            id = #id#
         </isNotNull>
      </dynamic>
		
   </select>
</sqlMap>

以上 SELECT 語句將以兩種方式工作 -

  • 如果傳遞 ID,則它返回與該 ID 對應的記錄 否則,它返回所有記錄。

IbatisReadDy.java 檔案

此檔案包含應用程式級別的邏輯,用於從 Employee 表中讀取條件記錄 -

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

import java.io.*;
import java.sql.SQLException;
import java.util.*;

public class IbatisReadDy{
   public static void main(String[] args)
   throws IOException,SQLException{
      Reader rd=Resources.getResourceAsReader("SqlMapConfig.xml");
      SqlMapClient smc=SqlMapClientBuilder.buildSqlMapClient(rd);

      /* This would read all records from the Employee table.*/
      System.out.println("Going to read records.....");
      Employee rec = new Employee();
      rec.setId(1);

      List <Employee> ems = (List<Employee>)  
         smc.queryForList("Employee.findByID", rec);
      Employee em = null;
		
      for (Employee e : ems) {
         System.out.print("  " + e.getId());
         System.out.print("  " + e.getFirstName());
         System.out.print("  " + e.getLastName());
         System.out.print("  " + e.getSalary());
         em = e; 
         System.out.println("");
      }    
      System.out.println("Records Read Successfully ");
   }
} 

編譯和執行

以下是編譯和執行上述軟體的步驟。在進行編譯和執行之前,請確保已正確設定PATH和CLASSPATH。

  • 如上所示建立Employee.xml。
  • 如上所示建立Employee.java並編譯它。
  • 建立如上所示的 IbatisReadDy.java 並編譯它。
  • 執行 IbatisReadDy 二進位制檔案以執行程式。

您將獲得以下結果,並且將從 EMPLOYEE 表中讀取一條記錄。

Going to read records.....
   1  Zara  Ali  5000
Record Reads Successfully

透過將 null 作為 smc.queryForList("Employee.findByID", null) 傳遞來嘗試以上示例。

iBATIS OGNL 表示式

iBATIS 提供了強大的基於 OGNL 的表示式,以消除大多數其他元素。

  • if 語句
  • choose、when、otherwise 語句
  • where 語句
  • foreach 語句

if 語句

在動態 SQL 中最常見的事情是有條件地包含 where 子句的一部分。例如 -

<select id="findActiveBlogWithTitleLike" parameterType="Blog" resultType="Blog">
   SELECT * FROM BLOG
   WHERE state = 'ACTIVE.
	
   <if test="title != null">
      AND title like #{title}
   </if>
	
</select>

此語句提供了一種可選的文字搜尋型別功能。如果您不傳遞標題,則返回所有活動的部落格。但是,如果您確實傳遞了一個標題,它將查詢具有給定 like 條件的標題。

您可以包含多個 if 條件,如下所示 -

<select id="findActiveBlogWithTitleLike" parameterType="Blog" resultType="Blog">
   SELECT * FROM BLOG
   WHERE state = 'ACTIVE.
	
   <if test="title != null">
      AND title like #{title}
   </if>
	
   <if test="author != null">
      AND author like #{author}
   </if>
	
</select>

choose、when 和 otherwise 語句

iBATIS 提供了一個 choose 元素,類似於 Java 的 switch 語句。它有助於在多個選項中選擇一個。

以下示例將僅按標題搜尋(如果提供),然後僅按作者搜尋(如果提供)。如果兩者都不提供,則僅返回精選部落格 -

<select id="findActiveBlogWithTitleLike" parameterType="Blog" resultType="Blog">
   SELECT * FROM BLOG
   WHERE state = 'ACTIVE.
	
   <choose>
      <when test="title != null">
         AND title like #{title}
      </when>
		
      <when test="author != null and author.name != null">
         AND author like #{author}
      </when>
		
      <otherwise>
         AND featured = 1
      </otherwise>
   </choose>
	
</select>

where 語句

檢視我們之前的示例以瞭解在不滿足任何條件時會發生什麼。您最終將得到一個如下所示的 SQL -

SELECT * FROM BLOG
WHERE

這將失敗,但 iBATIS 有一個簡單的解決方案,只需一個簡單的更改,一切正常 -

<select id="findActiveBlogLike" parameterType="Blog" resultType="Blog">
   SELECT * FROM BLOG
	
   <where>
      <if test="state != null">
         state = #{state}
      </if>
		
      <if test="title != null">
         AND title like #{title}
      </if>
		
      <if test="author != null>
         AND author like #{author}
      </if>
   </where>
	
</select>

where 元素僅當包含的標籤返回任何內容時才插入 WHERE。此外,如果該內容以 ANDOR 開頭,則它知道將其剝離。

foreach 語句

foreach 元素允許您指定一個集合並宣告可以在元素主體內部使用的專案和索引變數。

它還允許您指定開頭和結尾字串,並在迭代之間新增分隔符。您可以構建一個 IN 條件,如下所示 -

<select id="selectPostIn" resultType="domain.blog.Post">
   SELECT *
   FROM POST P
   WHERE ID in
	
   <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
      #{item}
   </foreach>
	
</select>

iBATIS - 除錯

在使用 iBATIS 時,除錯程式很容易。iBATIS 具有內建的日誌記錄支援,並且可以使用以下日誌記錄庫,並按此順序搜尋它們。

  • Jakarta Commons Logging (JCL)。
  • Log4J
  • JDK 日誌記錄

您可以將上述任何庫與 iBATIS 一起使用。

使用 Log4J 進行除錯

假設您將使用 Log4J 進行日誌記錄。在繼續之前,您需要交叉檢查以下幾點 -

  • Log4J JAR 檔案 (log4j-{version}.jar) 應位於 CLASSPATH 中。
  • 您在 CLASSPATH 中有可用的 log4j.properties 檔案。

以下是 log4j.properties 檔案。請注意,某些行已註釋掉。如果您需要其他除錯資訊,可以取消註釋它們。

# Global logging configuration
log4j.rootLogger = ERROR, stdout

log4j.logger.com.ibatis = DEBUG

# shows SQL of prepared statements
#log4j.logger.java.sql.Connection = DEBUG

# shows parameters inserted into prepared statements
#log4j.logger.java.sql.PreparedStatement = DEBUG

# shows query results
#log4j.logger.java.sql.ResultSet = DEBUG

#log4j.logger.java.sql.Statement = DEBUG

# Console output
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %5p [%t] − %m%n

您可以從 Apache 網站找到 Log4J 的完整文件 - Log4J 文件

iBATIS 除錯示例

以下 Java 類是一個非常簡單的示例,它初始化然後使用 Log4J 日誌記錄庫用於 Java 應用程式。我們將使用上面提到的位於 CLASSPATH 中的屬性檔案。

import org.apache.log4j.Logger;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

import java.io.*;
import java.sql.SQLException;
import java.util.*;

public class IbatisUpdate{
   static Logger log = Logger.getLogger(IbatisUpdate.class.getName());

   public static void main(String[] args)
   throws IOException,SQLException{
      Reader rd = Resources.getResourceAsReader("SqlMapConfig.xml");
      SqlMapClient smc = SqlMapClientBuilder.buildSqlMapClient(rd);

      /* This would insert one record in Employee table. */
      log.info("Going to update record.....");
      Employee rec = new Employee();
      rec.setId(1);
      rec.setFirstName( "Roma");
      smc.update("Employee.update", rec );
      log.info("Record updated Successfully ");

      log.debug("Going to read records.....");
      List <Employee> ems = (List<Employee>) 
         smc.queryForList("Employee.getAll", null);
      Employee em = null;
		
      for (Employee e : ems) {
         System.out.print("  " + e.getId());
         System.out.print("  " + e.getFirstName());
         System.out.print("  " + e.getLastName());
         System.out.print("  " + e.getSalary());
         em = e;
         System.out.println("");
      }
      log.debug("Records Read Successfully ");
   }
}

編譯和執行

首先,請確保在繼續進行編譯和執行之前已正確設定 PATH 和 CLASSPATH。

  • 如上所示建立Employee.xml。
  • 如上所示建立Employee.java並編譯它。
  • 如上所示建立IbatisUpdate.java並編譯它。
  • 建立如上所示的 log4j.properties。
  • 執行IbatisUpdate二進位制檔案以執行程式。

您將獲得以下結果。一條記錄將更新到 EMPLOYEE 表中,稍後將從 EMPLOYEE 表中讀取相同的記錄。

DEBUG [main] - Created connection 28405330.
DEBUG [main] - Returned connection 28405330 to pool.
DEBUG [main] - Checked out connection 28405330 from pool.
DEBUG [main] - Returned connection 28405330 to pool.
   1  Roma  Ali  5000
   2  Zara  Ali  5000
   3  Zara  Ali  5000

除錯方法

在上面的示例中,我們只使用了 info() 方法,但是您可以根據需要使用以下任何方法 -

public void trace(Object message);
public void debug(Object message);
public void info(Object message);
public void warn(Object message);
public void error(Object message);
public void fatal(Object message);

iBATIS - Hibernate

iBATIS 和 Hibernate 之間存在主要差異。鑑於其特定的領域,這兩種解決方案都能很好地工作。在以下情況下建議使用 iBATIS -

  • 您想建立自己的 SQL 並願意維護它們。
  • 您的環境由關係資料模型驅動。
  • 您必須處理現有和複雜的模式。

如果環境由物件模型驅動並且需要自動生成 SQL,則使用 Hibernate。

iBATIS 和 Hibernate 的區別

Hibernate 和 iBATIS 都是業界提供的開源物件關係對映 (ORM) 工具。每個工具的使用取決於您使用它們的上下文。

下表突出顯示了 iBATIS 和 Hibernate 之間的區別 -

iBATIS Hibernate
iBATIS 更簡單。它以更小的包大小提供。 Hibernate 為您生成 SQL,這意味著您不必花費時間生成 SQL。
iBATIS 靈活。它提供更快的開發時間。 Hibernate 具有高度可擴充套件性。它提供了更高階的快取。
iBATIS 使用 SQL,這可能與資料庫相關。 Hibernate 使用 HQL,它相對獨立於資料庫。在 Hibernate 中更改資料庫更容易。
iBatis 將 JDBC API 中的 ResultSet 對映到您的 POJO 物件,因此您不必關心表結構。 Hibernate 將您的 Java POJO 物件對映到資料庫表。
在 iBATIS 中使用儲存過程非常容易。 在 Hibernate 中使用儲存過程有點困難。

Hibernate 和 iBATIS 都獲得了 SPRING 框架的良好支援,因此選擇其中一個應該不成問題。

iBATOR - 簡介

iBATOR 是 iBATIS 的程式碼生成器。iBATOR 檢查一個或多個數據庫表,並生成可用於訪問這些表的 iBATIS 工件。

稍後您可以編寫自定義 SQL 程式碼或儲存過程以滿足您的需求。iBATOR 生成以下工件 -

  • SqlMap XML 檔案
  • 與表的主鍵和欄位匹配的 Java 類
  • 使用上述物件的 DAO 類(可選)

iBATOR 可以作為獨立的 JAR 檔案執行,也可以作為 Ant 任務執行,或者作為 Eclipse 外掛執行。本教程描述了從命令列生成 iBATIS 配置檔案的簡單方法。

下載 iBATOR

如果您使用的是除 Eclipse 之外的 IDE,請下載獨立的 JAR 檔案。獨立的 JAR 包括一個用於執行 iBATOR 的 Ant 任務,或者您可以從 Java 程式碼的命令列執行 iBATOR。

生成配置檔案

要執行 iBATOR,請按照以下步驟操作 -

步驟 1

建立並適當地填充配置檔案 ibatorConfig.xml。至少,您必須指定 -

  • 一個 <jdbcConnection> 元素,用於指定如何連線到目標資料庫。

  • 一個 <javaModelGenerator> 元素,用於指定生成的 Java 模型物件的的目標包和目標專案。

  • 一個 <sqlMapGenerator> 元素,用於指定生成的 SQL 對映檔案的目標包和目標專案。

  • 一個 <daoGenerator> 元素,用於指定生成的 DAO 介面和類的目標包和目標專案(如果您不希望生成 DAO,可以省略 <daoGenerator> 元素)。

  • 至少一個數據庫 <table> 元素

注意 - 有關 iBATOR 配置檔案的示例,請參閱 XML 配置檔案參考 頁面。

步驟 2

將檔案儲存到方便的位置,例如:\temp\ibatorConfig.xml。

步驟 3

現在從命令列執行 iBATOR,如下所示 -

java -jar abator.jar -configfile \temp\abatorConfig.xml -overwrite

這將告訴 iBATOR 使用您的配置檔案執行。它還會告訴 iBATOR 覆蓋任何具有相同名稱的現有 Java 檔案。如果您想儲存任何現有的 Java 檔案,則省略 **−overwrite** 引數。

如果存在衝突,iBATOR 會使用唯一名稱儲存新生成的檔案。

執行 iBATOR 後,您需要建立或修改標準的 iBATIS 配置檔案以利用您新生成的程式碼。這將在下一節中說明。

執行 iBATOR 後的任務

執行 iBATOR 後,您需要建立或修改其他 iBATIS 配置工件。主要任務如下:

  • 建立或修改 SqlMapConfig.xml 檔案。
  • 建立或修改 dao.xml 檔案(僅當您使用 iBATIS DAO 框架時)。

下面將詳細描述每個任務。

更新 SqlMapConfig.xml 檔案

iBATIS 使用一個 XML 檔案(通常命名為 SqlMapConfig.xml)來指定資料庫連線資訊、事務管理方案以及 iBATIS 會話中使用的 SQL 對映 XML 檔案。

iBATOR 無法為您建立此檔案,因為它對您的執行環境一無所知。但是,此檔案中的某些專案與 iBATOR 生成的專案直接相關。

配置檔案中 iBATOR 的特定需求如下:

  • 必須啟用語句名稱空間。
  • 必須列出 iBATOR 生成的 SQL 對映 XML 檔案。

例如,假設 iBATOR 生成了一個名為 MyTable_SqlMap.xml 的 SQL 對映 XML 檔案,並且該檔案已放置在專案的 test.xml 包中。SqlMapConfig.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>
   <!-- Statement namespaces are required for Abator -->
   <settings useStatementNamespaces="true" />

   <!-- Setup the transaction manager and data source that are
   appropriate for your environment
   -->
	
   <transactionManager type="...">
      <dataSource type="...">
      </dataSource>
   </transactionManager>

   <!-- SQL Map XML files should be listed here -->
   <sqlMap resource="test/xml/MyTable_SqlMap.xml" />

</sqlMapConfig>

如果存在多個 SQL 對映 XML 檔案(這很常見),則可以在 <transactionManager> 元素之後以任何順序使用重複的 <sqlMap> 元素列出這些檔案。

更新 dao.xml 檔案

iBATIS DAO 框架由一個通常稱為 dao.xml 的 xml 檔案配置。

iBATIS DAO 框架使用此檔案來控制 DAO 的資料庫連線資訊,以及列出 DAO 實現類和 DAO 介面。

在此檔案中,您應該指定 SqlMapConfig.xml 檔案的路徑,以及所有 iBATOR 生成的 DAO 介面和實現類。

例如,假設 iBATOR 生成了一個名為 MyTableDAO 的 DAO 介面和一個名為 MyTableDAOImpl 的實現類,並且這些檔案已放置在專案的 test.dao 包中。

dao.xml 檔案應包含以下條目:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE daoConfig PUBLIC "-//ibatis.apache.org//DTD DAO Configuration 2.0//EN" "http://ibatis.apache.org/dtd/dao-2.dtd">

<daoConfig>

   <context>
	
      <transactionManager type="SQLMAP">
         <property name="SqlMapConfigResource" value="test/SqlMapConfig.xml"/>
      </transactionManager>

      <!-- DAO interfaces and implementations should be listed here -->
      <dao interface="test.dao.MyTableDAO" implementation="test.dao.MyTableDAOImpl" />
   </context>
	
</daoConfig>

**注意:** 僅當您為 iBATIS DAO 框架生成 DAO 時,才需要執行此步驟。

廣告