iBATIS 是一個持久性框架,在自動化的 Java,.NET 和 Ruby on Rails 的 SQL 數(shù)據(jù)庫和對象之間進行映射。該映射通過包裝 XML 配置文件中的 SQL 語句從應用程序邏輯分離。
iBATIS 是一個輕量級的框架和持久性 API 利于 POJO(普通Java對象)。
iBATIS 被稱為一個數(shù)據(jù)映射和映射類屬性以及數(shù)據(jù)庫表的列之間的參數(shù)和結(jié)果的集合。
iBATIS 和其它持久性框架如 Hibernate 之間的顯著不同的是,iBATIS 強調(diào)使用SQL,而其他框架通常使用自定義查詢語言,具有 Hibernate 查詢語言(HQL)或企業(yè) JavaBeans 查詢語言(EJB QL)。
iBatis 提供了以下設(shè)計理念 -
簡單- iBATIS 被廣泛認為是當今是最簡單的持久化框架之一。
快速發(fā)展- iBATIS 盡一切努力讓自己快速發(fā)展。
可移植性- iBATIS 可用于幾乎任何語言或平臺如 Java,Ruby 和 C#。
獨立接口- iBATIS 提供與數(shù)據(jù)庫無關(guān)的接口和API,幫助應用程序與數(shù)據(jù)部分保持獨立的持久性。
開源- iBATIS 的源碼及軟件是自由和開放。
iBATIS的具有以下優(yōu)點 -
支持存儲過程- iBATIS 封裝在 SQL 中,使業(yè)務(wù)邏輯保持了數(shù)據(jù)庫特性,應用程序更易于部署和測試,更便于操作。
支持嵌入式SQL -無需預編譯器,你可以完全訪問所有的 SQL 的功能。
支持動態(tài)SQL - iBATIS 提供動態(tài)構(gòu)建基于參數(shù)的SQL查詢功能。
支持O / RM - iBATIS 支持許多功能,作為一個 O / RM 工具,如延遲加載,連接抓取,高速緩存,運行時代碼生成和繼承
iBATIS 利用了 JAVA 編程語言,開發(fā)數(shù)據(jù)庫應用導向。在進一步討論之前,請確保您了解程序和面向?qū)ο缶幊痰幕A(chǔ)知識 - 控制結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu)和變量,類,對象,等等。
要了解 JAVA 詳細你可以通過我們的 JAVA 教程 。
在實際開發(fā)前,你將不得不設(shè)立 iBATIS 的一個適當?shù)沫h(huán)境。本章介紹如何設(shè)置為 SWF 工作環(huán)境。
執(zhí)行以下簡單步驟,在你的 Linux 機器上安裝 iBATIS
從下載最新版本的 iBATIS iBATIS 。
解壓下載的文件,從包中提取 .jar 文件,并讓他們在適當?shù)?lib 目錄下。
在提取 .jar 文件(S)適當設(shè)置 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
使用以下語法創(chuàng)建 MySQL 數(shù)據(jù)庫的 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) );
考慮以下 -
我們將使用 JDBC 訪問數(shù)據(jù)庫 TESTDB。
JDBC 驅(qū)動程序 MySQL 是“com.mysql.jdbc.Driver”。
連接 UR L是為“jdbc:mysql://本地主機:3306 / TESTDB”。
我們將分別使用用戶名和密碼的“根”和“根”。
我們對所有的操作sql語句映射將在“Employee.xml”來描述。
基于以上假設(shè),我們必須創(chuàng)建一個名為 SqlMapConfig.xml 具有下列內(nèi)容的 XML 配置文件。這就是你需要為 iBatis 所需的所有配置 -
這兩個文件 SqlMapConfig.xml 和 Employee.xml 應存在于類路徑是重要的?,F(xiàn)在,我們將保持 Employee.xml 文件空的,我們將覆蓋在以后的章節(jié)內(nèi)容。
<?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://localhost:3306/testdb"/> <property name="JDBC.Username" value="root"/> <property name="JDBC.Password" value="root"/> </dataSource> </transactionManager> <sqlMap resource="Employee.xml"/> </sqlMapConfig>
您可以設(shè)置使用 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"/>
要執(zhí)行使用 iBATIS 創(chuàng)建,讀取,更新和刪除(CRUD)操作,你需要創(chuàng)建一個普通 Java 對象(PO??JO)對應的表類。本課程介紹對象,這將“模型”的數(shù)據(jù)庫表行。
POJO 類將不得不實施所有執(zhí)行所需操作所需要的方法。
讓我們假設(shè)我們有在 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.java文件中創(chuàng)建一個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 */
可以定義方法來設(shè)置表中的各個字段。下一章將介紹如何獲取各個字段的值。
要定義使用iBATIS SQL映射語句中,我們將使用<插入>標記和這個標簽定義中,我們可以定義將在IbatisInsert.java文件中,用于對數(shù)據(jù)庫執(zhí)行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 -可能需要一個值作為字符串,整數(shù),浮點,雙 ,或根據(jù)需求任意類對象 。在這個例子中,我們將通過 Employee 對象作為參數(shù),同時呼吁的SqlMap 類的插入方法。
如果數(shù)據(jù)庫表使用 IDENTITY,AUTO_INCREMENT 或串行列或您已經(jīng)定義了一個 SEQUENCE /發(fā)電機,可以使用 <selectKey元素> 元素在 <插入> 語句中使用或返回數(shù)據(jù)庫生成的值。
該文件將應用程序級別的邏輯插入在雇員表中的記錄 -
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 "); } }
以下是編譯并運行上述軟件的步驟。請確保您已設(shè)置 PATH 和 CLASSPATH 在進行適當?shù)木幾g和執(zhí)行之前。
你會得到下面的結(jié)果,并創(chuàng)下會在 EMPLOYEE 表中創(chuàng)建。
$java IbatisInsert Going to insert record..... Record Inserted Successfully
如果檢查 EMPLOYEE 表,它應該顯示以下結(jié)果 -
mysql> select * from EMPLOYEE; +----+------------+-----------+--------+ | id | first_name | last_name | salary | +----+------------+-----------+--------+ | 1 | Zara | Ali | 5000 | +----+------------+-----------+--------+ 1 row in set (0.00 sec)
我們討論,在最后一章,如何執(zhí)行創(chuàng)建使用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 | +----+------------+-----------+--------+ 1 row in set (0.00 sec)
要執(zhí)行讀操作,我們將修改 Employee 類中 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 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 */
要定義使用 iBATIS SQL 映射語句中,我們將增加的 <select> 在 Employee.xml 文件,這個標簽定義標記內(nèi),我們將定義將在 IbatisRead.java 文件中,用于對數(shù)據(jù)庫執(zhí)行 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>
在這里,我們沒有使用 WHERE 子句與 SQL SELECT 語句。我們將證明,在接下來的章節(jié)中,你怎么能與 WHERE SELECT 語句子句如何使用可以傳遞值到 WHERE 子句。
這個文件的應用程序級的邏輯讀取雇員表中的記錄 -
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 "); } }
以下是編譯并運行上述軟件的步驟。請確保您已設(shè)置 PATH 和 CLASSPATH 在進行適當?shù)木幾g和執(zhí)行之前。
你會得到下面的結(jié)果,并創(chuàng)下會從 EMPLOYEE 表如下讀 -
Going to read records..... 1 Zara Ali 5000 Record Reads Successfully
我們討論,在最后一章,如何在使用 iBATIS 表執(zhí)行讀操作。本章介紹了如何更新使用 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)
要執(zhí)行 UDPATE 操作,你就需要修改 Employee.java 文件內(nèi)容如下 -
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 */
要定義使用 iBATIS SQL 映射語句中,我們將增加 <更新> 在 Employee.xml 這個標簽定義標記內(nèi),我們將定義將在 IbatisUpdate.java 文件中,用于對數(shù)據(jù)庫執(zhí)行 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>
此文件具有應用程序級別的邏輯來更新記錄到 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 "); } }
以下是編譯并運行上述軟件的步驟。請確保您已設(shè)置 PATH 和 CLASSPATH 在進行適當?shù)木幾g和執(zhí)行之前。
你會得到下面的結(jié)果,并創(chuàng)下會在 EMPLOYEE 表進行更新和后,同樣會記錄從 EMPLOYEE 表中讀取。
Going to update record..... Record updated Successfully Going to read records..... 1 Roma Ali 5000 Records Read Successfully
本章介紹了如何從使用 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) );
假設(shè)該表有兩個記錄如下 -
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)
要執(zhí)行刪除操作,你并不需要修改 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 */
要使用 iBATIS 定義 SQL 語句中的映射,我們會在 Employee.xml 添加<刪除>標記和這個標簽定義中,我們可以定義將在 IbatisDelete.java 文件可用于執(zhí)行 SQL 刪除數(shù)據(jù)庫查詢的“身份證”。
<?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>
此文件具有應用程序級別邏輯刪除 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 "); } }
以下是編譯并運行上述軟件的步驟。請確保您已設(shè)置 PATH 和 CLASSPATH 在進行適當?shù)木幾g和執(zhí)行之前。
你會得到以下結(jié)果,并與 ID = 1 的記錄會從 EMPLOYEE 表中刪除并記錄的其余部分將被讀。
Going to delete record..... Record deleted Successfully Going to read records..... 2 Roma Ali 3000 Records Read Successfully
該 resultMap 元素是 iBATIS 最重要和最強大的元素。您最多可以減少使用 iBATIS 的 ResultMap 90% JDBC 編碼,并在某些情況下,它可以讓你做的事情,JDBC 甚至不支持。
ResultMaps 的設(shè)計是這樣的簡單語句根本不要求明確的結(jié)果映射,更復雜的語句需要不超過絕對必要說明的關(guān)系。
本章只是一個簡單的介紹 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)
要使用 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 介紹 <resultMap的> </ resultMap的> 標記。這個標簽本來這是需要我們的 <select> 標記的結(jié)果映射屬性運行此結(jié)果映射的 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> <!-- 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>
這個文件的應用程序級的邏輯讀取使用的 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 "); } }
以下是編譯并運行上述軟件的步驟。請確保您已設(shè)置 PATH 和 CLASSPATH 在進行適當?shù)木幾g和執(zhí)行之前。
你會得到以下結(jié)果這是對 EMPLOYEE 表讀操作。
Going to read record..... ID: 1 First Name: Zara Last Name: Ali Salary: 5000 Record read Successfully
您可以撥打使用 iBATIS 配置的存儲過程。首先,讓我們了解如何創(chuàng)建 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) );
讓我們創(chuàng)建 MySQL 數(shù)據(jù)庫以下存儲過程 -
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.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 介紹<過程> </程序>和<parameterMap 的> </ parameterMap 的>標記。在這里,<過程> </程序>標簽將有哪些,我們將在我們的應用程序使用調(diào)用存儲過程的 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>
這個文件的應用程序級的邏輯讀取使用的 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 "); } }
以下是編譯并運行上述軟件的步驟。請確保您已設(shè)置 PATH 和 CLASSPATH 在進行適當?shù)木幾g和執(zhí)行之前。
你會得到以下結(jié)果:
Going to read record..... ID: 1 First Name: Zara Last Name: Ali Salary: 5000 Record read Successfully
動態(tài) SQL 的 iBATIS 是一個非常強大的功能。有時候,你不得不改變基于您的參數(shù)對象的狀態(tài) WHERE 子句標準。在這種情況下,iBATIS 提供了一組可以映射語句中使用,以提高 SQL 的可重用性和靈活性,動態(tài) SQL 標簽。
所有的邏輯是使用一些額外的標簽放在 .XML 文件。下面是一個例子 SELECT 語句將在兩個方面工作 -
如果你通過一個 ID,那么這將返回所有對應于該ID的記錄。
否則,它會返回所有在那里員工 ID 設(shè)置為 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> ..................
下面的例子演示了如何編寫使用動態(tài) SQL SELECT 語句。想想,我們有以下 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) );
讓我們假設(shè)這個表只有一個記錄如下 -
mysql> select * from EMPLOYEE; +----+------------+-----------+--------+ | id | first_name | last_name | salary | +----+------------+-----------+--------+ | 1 | Zara | Ali | 5000 | +----+------------+-----------+--------+ 1 row in set (0.00 sec)
要執(zhí)行讀操作,讓我們有一個 Employee 類 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 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 */
要定義使用 iBATIS SQL 映射語句中,我們將添加以下修改<選擇>在 Employee.xml 這個標簽定義標記內(nèi),我們將定義將在 IbatisReadDy.java 用于上執(zhí)行動態(tài) SQL SELECT 查詢的“身份證”數(shù)據(jù)庫。
<?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 否則記錄,將返回所有記錄。
這個文件的應用程序級的邏輯讀取 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 "); } }
以下是編譯并運行上述軟件的步驟。請確保您已設(shè)置 PATH 和 CLASSPATH 在進行適當?shù)木幾g和執(zhí)行之前。
你會得到下面的結(jié)果,并創(chuàng)下將從 EMPLOYEE 表中讀取。
Going to read records..... 1 Zara Ali 5000 Record Reads Successfully
由空傳遞的smc.queryForList(“Employee.findByID”,NULL)嘗試上面的例子。
iBATIS 提供基于強大的 OGNL 表達式來消除其他元素。
動態(tài) 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>
這種說法提供了功能一個可選的文本搜索類型。如果你沒有冠軍擦肩而過,那么所有激活的博客被返回。但是,如果你傳遞一個標題,它會尋找與給定的條件下像一個冠軍。
您可以包括多個 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>
iBATIS 提供了一個選擇元素,它類似于 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>
看看我們前面的例子,看看如果沒有的條件都滿足會發(fā)生什么。你最終會與像這樣的 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 元素插入,只有當被包含的標記返回任何內(nèi)容的WHERE。此外,如果該內(nèi)容開頭 AND 或 OR,它知道剝離其關(guān)閉。
foreach 元素允許你指定一個集合,聲明可以在元素體內(nèi)部使用的項目和指標的變量。
它還允許你指定打開和關(guān)閉的字符串,并添加一個分隔符放在迭代之間??梢园慈缦路绞綐?gòu)建在 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>
這是很容易調(diào)試程序與 iBATIS 工作時。 iBATIS 有內(nèi)置的日志支持,并在按照以下順序記錄庫和搜索他們的作品。
您可以使用上述任何圖書館與 iBATIS 一起。
假設(shè)你要使用 log4j 的日志記錄。在開始之前,你需要交叉檢查以下幾點 -
以下是 log4j.properties 文件。請注意,某些行被注釋掉。如果你需要更多的調(diào)試信息,你可以取消它們。
# 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
你可以找到阿帕奇網(wǎng)站 Log4j 提供完整的文檔- log4j 文檔 。
下面的 Java 類是一個非常簡單的例子,初始化,然后使用 Java 應用程序 Log4J 日志庫。我們將使用其中位于 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 "); } }
首先,確保你已經(jīng)設(shè)置 PATH 和 CLASSPATH 在進行適當?shù)木幾g和執(zhí)行之前。
你會得到以下結(jié)果。 A 記錄將在 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()方法,但是你可以使用任何下列方法根據(jù)您的要求-
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 之間的主要差異。這兩種解決方案很好地工作,因為它們特定領(lǐng)域。 iBATIS 建議的情況如下 -
使用 Hibernate 如果環(huán)境是由對象模型驅(qū)動的并需要自動生成SQL。
Hibernate 和 iBATIS 的是開源對象關(guān)系映射(ORM)工具,在同行業(yè)中可用。這些工具的用途取決于你使用它們的上下文。
下表重點介紹的 iBATIS 和 Hibernate 之間的差異 -
iBATIS | 過冬 |
---|---|
iBATIS 更簡單。它有一個更小的封裝尺寸。 | Hibernate 會為你的 SQL,這意味著你不必花時間生成 SQL。 |
iBATIS 是靈活的。它提供了更快的開發(fā)時間。 | Hibernate 是高度可擴展的。它提供了一個更高級的高速緩存。 |
iBATIS 使用SQL這可能是數(shù)據(jù)庫相關(guān)的。 | Hibernate 使用 HQL 是相對獨立的數(shù)據(jù)庫。這是比較容易改變分貝休眠。 |
iBatis 映射從 JDBC API 到你的 POJO OBJETS ResultSet 中,所以你不必在意表結(jié)構(gòu)。 | Hibernate 映射您的 Java 對象 POJO 到數(shù)據(jù)庫表。 |
這是很容易使用 iBATIS 存儲過程。 | 存儲過程使用的是 Hibernate 有點困難。 |
Hibernate 和 iBATIS 的接收來自 Spring 框架很好的支持,所以它不應該選擇其中的一個問題。
iBATOR 是 iBATIS 的代碼生成器。 iBATOR 內(nèi)部檢查的一個或多個數(shù)據(jù)庫表和生成可用于訪問表 iBATIS 的工件。
稍后,您可以編寫自定義的S QL 代碼或存儲過程來滿足您的要求。 iBATOR生成以下工件 -
iBATOR 可以作為一個獨立的 JAR 文件運行,或者作為一個 Ant 任務(wù),或者作為一個 Eclipse 插件。本教程介紹的命令行生成 iBATIS 的配置文件的最簡單的方法。
如果您使用的不是其他的 Eclipse 的 IDE 下載獨立 JAR。獨立 JAR 包括一個 Ant 任務(wù)運行 iBATOR,也可以從 Java 代碼在命令行運行 iBATOR。
要運行 iBATOR,請按照下列步驟 -
創(chuàng)建并填寫相應的配置文件 ibatorConfig.xml。至少,你必須指定 -
A <jdbcConnection>元素指定如何連接到目標數(shù)據(jù)庫。
A <javaModelGenerator>元素來指定目標包和生成的 Java 模型對象目標項目。
A <sqlMapGenerator>元素來指定目標包和生成的 SQL 映射文件的目標項目。
A <daoGenerator>元素指定生成的 DAO 接口和類目標包和目標的項目(可以省略<daoGenerator>元素,如果你不希望產(chǎn)生的 DAO)。
至少一個數(shù)據(jù)庫<table>元素
注-請參閱 XML 配置文件參考頁面的 iBATOR 配置文件的一個例子。
將該文件保存在方便的位置,例如在: TEMP ibatorConfig.xml。
現(xiàn)在從命令行運行 iBATOR 如下 -
java -jar abator.jar -configfile empabatorConfig.xml -overwrite
它會告訴 iBATOR 使用您的配置文件來運行。它還會告訴 iBATOR 覆蓋具有相同名稱的任何現(xiàn)有的 Java 文件。如果您想保存任何現(xiàn)有的 Java 文件,那么忽略-overwrite 參數(shù)。
如果有沖突,iBATOR 節(jié)省了一個獨特的名字,新生成的文件。
運行 iBATOR 后,您需要創(chuàng)建或修改標準 iBATIS 的配置文件來利用你新生成的代碼。這將在接下來的部分中說明。
運行 iBATOR 后,您需要創(chuàng)建或修改其他 iBATIS 的配置工件。主要工作如下 -
每個任務(wù)將在下面詳細描述的 -
iBATIS 使用 XML 文件,通常稱為 SqlMapConfig.xml,為那些在 iBATIS 的會話中使用一個數(shù)據(jù)庫連接,事務(wù)管理方案,SQL 映射的 XML 文件中指定的信息。
因為它什么都不知道關(guān)于你的執(zhí)行環(huán)境 iBATOR 不能為你創(chuàng)建這個文件。然而,一些在此文件中的項目涉及直接向 iBATOR 生成物品。
是在配置文件中 iBATOR 特定需求如下: -
例如,假設(shè) iBATOR 已經(jīng)生成一個名為 MyTable_SqlMap.xml 的 SQL 映射文件,該文件已被放置在你的項目的 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 映射文件(這是很常見的),則可以將文件與 <transactionManager的> 元素經(jīng)過反復 <SQLMAP> 元素的順序排列。
iBATIS 的 DAO 框架是由俗稱 dao.xml 的 XML 文件進行配置。
iBATIS 的 DAO 框架使用這個文件來控制 DAO 的數(shù)據(jù)庫連接信息,還列出 DAO 實現(xiàn)類和 DAO 接口。
在這個文件中,應指定的路徑 SqlMapConfig.xml 文件,所有的 iBATOR 產(chǎn)生的 DAO 接口和實現(xiàn)類。
例如,假設(shè) iBATOR 已經(jīng)生成一個名為 MyTableDAO一個DAO 接口,并呼吁 MyTableDAOImpl 實現(xiàn)類,并且該文件已被放置在你的項目的 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 的需要。
更多建議: