一、iBATIS介紹
iBATIS的是一個(gè)持久層框架,它能夠自動(dòng)在Java, .NET, 和Ruby on Rails中與SQL數(shù)據(jù)庫(kù)和對(duì)象之間的映射。映射是從應(yīng)用程序邏輯封裝在XML配置文件中的SQL語(yǔ)句脫鉤。
iBATIS是一個(gè)輕量級(jí)的框架和持久性API適合持久化的POJO(普通Java對(duì)象)。
iBATIS是被稱為一個(gè)數(shù)據(jù)映射和映射需要的類的屬性和數(shù)據(jù)庫(kù)中的表的列之間的參數(shù)和結(jié)果。
iBATIS和其他持久化框架,如Hibernate之間的顯著區(qū)別在于,iBATIS強(qiáng)調(diào)使用SQL,而其他的框架通常使用一個(gè)自定義的查詢語(yǔ)言,具有Hibernate查詢語(yǔ)言(HQL)或Enterprise JavaBeans的查詢語(yǔ)言(EJB QL)。
iBATIS的設(shè)計(jì)理念:
iBatis提供了以下的設(shè)計(jì)理念:
簡(jiǎn)單:?iBATIS的被廣泛認(rèn)為是可用的最簡(jiǎn)單的持久化框架之一。
快速開(kāi)發(fā):iBATIS的理念是盡一切可能,以方便超快速開(kāi)發(fā)。
可移植性:?iBATIS可用于幾乎任何語(yǔ)言或平臺(tái),如Java,Ruby和C#,微軟.NET實(shí)現(xiàn)。
獨(dú)立的接口:iBATIS提供獨(dú)立于數(shù)據(jù)庫(kù)的接口和API,幫助應(yīng)用程序的其余部分保持獨(dú)立的任何持久性相關(guān)的資源,
開(kāi)源:iBATIS是自由和開(kāi)放源碼軟件。
IBATIS的優(yōu)點(diǎn)
下面是使用iBATIS的一些優(yōu)勢(shì):
支持存儲(chǔ)過(guò)程:iBATIS的SQL封裝以存儲(chǔ)過(guò)程的形式,使業(yè)務(wù)邏輯保持在數(shù)據(jù)庫(kù)之外,應(yīng)用程序更易于部署和測(cè)試,更便于移植。
支持內(nèi)嵌的SQL:預(yù)編譯器不是必需的,并有完全訪問(wèn)所有的SQL語(yǔ)句的特性。
支持動(dòng)態(tài)SQL:?iBATIS特性提供基于參數(shù)動(dòng)態(tài)生成SQL查詢。
支持O / RM:iBATIS支持許多相同的功能作為一個(gè)O / RM工具,如延遲加載,連接抓取,緩存,運(yùn)行時(shí)代碼生成和繼承
先決條件:
在開(kāi)始之前,要確保你了解過(guò)程和面向?qū)ο缶幊痰幕局R(shí):控制結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu)和變量,類,對(duì)象等。
iBATIS使用Java編程語(yǔ)言開(kāi)發(fā)面向數(shù)據(jù)庫(kù)應(yīng)用程序。
二、iBATIS配置環(huán)境
iBATIS 安裝:
這里有幾個(gè)簡(jiǎn)單的步驟,需要開(kāi)展Linux機(jī)器上安裝iBATIS:
下載iBATIS的最新版本下載iBATIS.
解壓下載的文件,從包中提取.jar文件并將其保存在相應(yīng)的lib目錄下。
在提取 .jar文件適當(dāng)設(shè)置PATH和CLASSPATH變量。
下面是進(jìn)行Linux機(jī)器下載iBATIS的二進(jìn)制文件的步驟:
$ 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
數(shù)據(jù)庫(kù)設(shè)置:
使用下面的語(yǔ)法在 MySQL數(shù)據(jù)庫(kù)中創(chuàng)建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)
? ? ? ? );
創(chuàng)建SqlMapConfig.xml
考慮以下幾點(diǎn):
我們將使用JDBC來(lái)訪問(wèn)數(shù)據(jù)庫(kù)?testdb.
MySQL的JDBC驅(qū)動(dòng)程序是 "com.mysql.jdbc.Driver".
連接URL是 "jdbc:mysql://localhost:3306/testdb".
使用的用戶名和密碼是 "root" and "root".
SQL語(yǔ)句映射的所有操作將被描述在"Employee.xml".
基于上述假設(shè),我們必須創(chuàng)建一個(gè)XML配置文件,nameSqlMapConfig.xml以下內(nèi)容。這就是需要提供所需的iBatis的所有配置:
這兩個(gè)文件SqlMapConfig.xml和Employee.xml 存在于類路徑。
現(xiàn)在,我們將保持Employee.xml文件為空,我們將格式轉(zhuǎn)換的在隨后的章節(jié)內(nèi)容。
?useStatementNamespaces="true"/> ?
?resource="Employee.xml"/>
還有其他一些可選的屬性,您可以在SqlMapConfig.xml文件中設(shè)置:
三、iBATIS創(chuàng)建操作
若要使用iBATIS執(zhí)行的任何CRUD(創(chuàng)建,寫(xiě)入,更新和刪除)操作,需要?jiǎng)?chuàng)建一個(gè)的POJO(普通Java對(duì)象)類對(duì)應(yīng)的表。本課程介紹的對(duì)象,將“模式”的數(shù)據(jù)庫(kù)表中的行。
POJO類必須實(shí)現(xiàn)所有執(zhí)行所需的操作所需的方法。
我們已經(jīng)在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 類:
我們會(huì)在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 */
可以定義方法來(lái)設(shè)置表中的各個(gè)字段。
Employee.xml 文件:
要定義使用iBATIS SQL映射語(yǔ)句中,我們將使用標(biāo)簽,這個(gè)標(biāo)簽定義中,我們會(huì)定義將用于在IbatisInsert.java文件的數(shù)據(jù)庫(kù)執(zhí)行SQL INSERT查詢“id”。
insert into EMPLOYEE(first_name, last_name, salary) values (#first_name#, #last_name#, #salary#)
select last_insert_id() as id ?
這里parameterClass:可以采取一個(gè)值作為字符串,整型,浮點(diǎn)型,double或根據(jù)要求任何類的對(duì)象。在這個(gè)例子中,我們將通過(guò)Employee對(duì)象作為參數(shù)而調(diào)用SqlMap類的insert方法。
如果您的數(shù)據(jù)庫(kù)表使用IDENTITY,AUTO_INCREMENT或串行列或已定義的SEQUENCE/GENERATOR,可以使用元素在的語(yǔ)句中使用或返回?cái)?shù)據(jù)庫(kù)生成的值。
IbatisInsert.java 文件:
文件將應(yīng)用程序級(jí)別的邏輯在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 ");}}?
編譯和運(yùn)行:
下面是步驟來(lái)編譯并運(yùn)行上述軟件。請(qǐng)確保已在進(jìn)行的編譯和執(zhí)行之前,適當(dāng)?shù)卦O(shè)置PATH和CLASSPATH。
創(chuàng)建Employee.xml如上所示。
創(chuàng)建Employee.java如上圖所示,并編譯它。
創(chuàng)建IbatisInsert.java如上圖所示,并編譯它。
執(zhí)行IbatisInsert二進(jìn)制文件來(lái)運(yùn)行程序。
會(huì)得到下面的結(jié)果,并創(chuàng)紀(jì)錄的將在EMPLOYEE表中創(chuàng)建。
$java IbatisInsert?Going to insert record.....?Record?Inserted?Successfully
去查看EMPLOYEE表,它應(yīng)該有如下結(jié)果:
mysql>?select?*?from EMPLOYEE;+----+------------+-----------+--------+| id | first_name | last_name | salary |+----+------------+-----------+--------+|?1?|?Zara?|?Ali?|?5000?|+----+------------+-----------+--------+
1 row in?set?(0.00 sec)
四、iBATIS讀取操作
我們已經(jīng)在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 類:
要執(zhí)行讀操作,我們將修改Employee類中Employee.java文件,如下所示:
public class Employee {
private int id;
private Stringfirst_name;
private Stringlast_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映射語(yǔ)句,我們將增加標(biāo)記在Employee.xml文件,這個(gè)標(biāo)簽定義中,我們會(huì)定義將用于在IbatisRead.java文件的數(shù)據(jù)庫(kù)執(zhí)行SQL SELECT查詢的“id”。
PUBLIC "-//ibatis.apache.org//DTD?SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
INSERT INTO EMPLOYEE(first_name, last_name, salary)
values (#first_name#, #last_name#, #salary#)
select last_insert_id() as id
SELECT * FROM EMPLOYEE
在這里,我們沒(méi)有使用WHERE子句和SQL SELECT語(yǔ)句。后續(xù)章節(jié)將演示如何用WHERE和SELECT語(yǔ)句子句,以及如何將值傳遞到WHERE子句。
IbatisRead.java 文件:
該文件將應(yīng)用程序級(jí)別的邏輯從雇員Employee表中讀出記錄:
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 ems = (List)
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 ");
}
}
編譯和運(yùn)行:
下面是步驟來(lái)編譯并運(yùn)行上述應(yīng)用。請(qǐng)確保您已在進(jìn)行的編譯和執(zhí)行之前,適當(dāng)?shù)卦O(shè)置PATH和CLASSPATH。
創(chuàng)建Employee.xml如上所示。
創(chuàng)建Employee.java如上圖所示,并編譯它。
創(chuàng)建IbatisRead.java如上圖所示,并編譯它。
執(zhí)行IbatisRead二進(jìn)制文件來(lái)運(yùn)行程序。
你會(huì)得到下面的結(jié)果,并且將記錄從EMPLOYEE表中讀取。
Going to read records.....?1?Zara?Ali?5000?Record?Reads?Successfully
五、iBATIS更新操作
我們已經(jīng)在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 類:
要執(zhí)行讀操作,我們將修改Employee類中Employee.java文件,如下所示:
public class Employee {
private int id;
private Stringfirst_name;
private Stringlast_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映射語(yǔ)句,我們想補(bǔ)充的標(biāo)簽Employee.xml文件,這個(gè)標(biāo)簽定義中,我們會(huì)定義將用于在IbatisUpdate.java文件的數(shù)據(jù)庫(kù)執(zhí)行SQL UPDATE查詢的“id”。
PUBLIC "-//ibatis.apache.org//DTD?SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
INSERT INTO EMPLOYEE(first_name, last_name, salary)
values (#first_name#, #last_name#, #salary#)
select last_insert_id() as id
SELECT * FROM EMPLOYEE
UPDATE EMPLOYEE
SET??? first_name = #first_name#
WHERE? id = #id#
IbatisUpdate.java 文件:
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 ems = (List)
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 ");
}
}
編譯和運(yùn)行:
下面是步驟來(lái)編譯并運(yùn)行上述軟件。請(qǐng)確保您已在進(jìn)行的編譯和執(zhí)行之前,適當(dāng)?shù)卦O(shè)置PATH和CLASSPATH。
創(chuàng)建Employee.xml如上所示。
創(chuàng)建Employee.java如上圖所示,并編譯它。
創(chuàng)建IbatisUpdate.java如上圖所示,并編譯它。
執(zhí)行IbatisUpdate二進(jìn)制文件來(lái)運(yùn)行程序。
得到下面的結(jié)果,并創(chuàng)建紀(jì)錄在EMPLOYEE表進(jìn)行更新和更高版本相同的記錄將從EMPLOYEE表中讀出。
Going to update record.....?Record updated Successfully?Going to read records.....?1?Roma?Ali?5000?Records?Read?Successfully
六、iBATIS刪除操作
我們已經(jīng)在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?|?
+----+------------+-----------+--------+
1 row in?set?(0.00 sec)
Employee POJO 類:
要執(zhí)行讀操作,我們將修改Employee類中Employee.java文件,如下所示:
public class Employee {
private int id;
private Stringfirst_name;
private Stringlast_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映射語(yǔ)句中,我們將增加鍵標(biāo)簽Employee.xml文件,這個(gè)標(biāo)簽定義中,我們會(huì)定義將用于在IbatisDelete.java文件執(zhí)行SQL DELETE查詢數(shù)據(jù)庫(kù)的“id”。
PUBLIC "-//ibatis.apache.org//DTD?SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
INSERT INTO EMPLOYEE(first_name, last_name, salary)
values (#first_name#, #last_name#, #salary#)
select last_insert_id() as id
SELECT * FROM EMPLOYEE
UPDATE EMPLOYEE
SET??? first_name = #first_name#
WHERE? id = #id#
DELETE FROM EMPLOYEE
WHERE? id = #id#
IbatisDelete.java 文件:
文件將應(yīng)用程序級(jí)別的邏輯從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 ems = (List)
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 ");
}
}
編譯和運(yùn)行:
下面是步驟來(lái)編譯并運(yùn)行上述軟件。請(qǐng)確保已在進(jìn)行的編譯和執(zhí)行之前,適當(dāng)?shù)卦O(shè)置PATH和CLASSPATH。
創(chuàng)建Employee.xml如上所示。
創(chuàng)建Employee.java如上圖所示,并編譯它。
創(chuàng)建IbatisDelete.java如上圖所示,并編譯它。
執(zhí)行IbatisDelete二進(jìn)制文件來(lái)運(yùn)行程序。
得到以下結(jié)果,ID=1將在EMPLOYEE表中被刪除,并讀取EMPLOYEE表中的一條記錄。
Going to delete record.....?Record deleted Successfully?Going to read records.....?2?Roma?Ali?3000?Records?Read?Successfully
七、iBATIS結(jié)果映射
resultMap的元素是在iBATIS的最重要和最強(qiáng)大的元素。您可以通過(guò)使用iBATIS的結(jié)果映射減少高達(dá)90%的JDBC編碼,在某些情況下,可以讓你做JDBC不支持的事情。
ResultMaps的設(shè)計(jì)是這樣的簡(jiǎn)單語(yǔ)句不需要明確的結(jié)果映射,以及更復(fù)雜的報(bào)表要求不超過(guò)絕對(duì)必要說(shuō)明的關(guān)系。
本章將只給你一個(gè)簡(jiǎn)單的介紹iBATIS的結(jié)果映射。
我們已經(jīng)在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?|?
+----+------------+-----------+--------+
1 row in?set?(0.00 sec)
Employee POJO 類:
要執(zhí)行讀操作,我們將修改Employee類中Employee.java文件,如下所示:
public class Employee {
private int id;
private Stringfirst_name;
private Stringlast_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 文件:
在這里,我們將修改Employee.xml文件介紹標(biāo)記。這個(gè)標(biāo)簽就必須在我們標(biāo)記的resultMap屬性運(yùn)行此結(jié)果映射這是需要一個(gè)id。
PUBLIC "-//ibatis.apache.org//DTD?SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
INSERT INTO EMPLOYEE(first_name, last_name, salary)
values (#first_name#, #last_name#, #salary#)
select last_insert_id() as id
SELECT * FROM EMPLOYEE
UPDATE EMPLOYEE
SET??? first_name = #first_name#
WHERE? id = #id#
DELETE FROM EMPLOYEE
WHERE? id = #id#
SELECT * FROM EMPLOYEE
WHERE id=#id#
IbatisResultMap.java 文件:
文件將應(yīng)用程序級(jí)別的邏輯,從使用結(jié)果映射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 ");
}
}
編譯和運(yùn)行:
下面是步驟來(lái)編譯并運(yùn)行上述軟件。請(qǐng)確保您已在進(jìn)行的編譯和執(zhí)行之前,適當(dāng)?shù)卦O(shè)置PATH和CLASSPATH。
創(chuàng)建Employee.xml如上所示。
創(chuàng)建Employee.java如上圖所示,并編譯它。
創(chuàng)建IbatisResultMap.java如上圖所示,并編譯它。
執(zhí)行IbatisResultMap二進(jìn)制文件來(lái)運(yùn)行程序。
會(huì)得到下面的結(jié)果是對(duì)EMPLOYEE表的讀操作。
Going to read record..... ID:?1?First?Name:?Zara?Last?Name:?Ali?Salary:?5000?Record read Successfully
八、iBATIS存儲(chǔ)過(guò)程
使用iBATIS配置來(lái)調(diào)用存儲(chǔ)過(guò)程。為了理解這一章,首先需要了解我們是如何在MySQL中創(chuàng)建一個(gè)存儲(chǔ)過(guò)程。
我們已經(jīng)在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)
);
讓我們?cè)贛ySQL數(shù)據(jù)庫(kù)中創(chuàng)建以下存儲(chǔ)過(guò)程。
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 類:
使用存儲(chǔ)過(guò)程,你就需要修改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文件介紹和標(biāo)記。這里標(biāo)簽將有一個(gè)id,我們會(huì)用我們的應(yīng)用程序來(lái)調(diào)用存儲(chǔ)過(guò)程。
PUBLIC "-//ibatis.apache.org//DTD?SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
INSERT INTO EMPLOYEE(first_name, last_name, salary)
values (#first_name#, #last_name#, #salary#)
select last_insert_id() as id
SELECT * FROM EMPLOYEE
UPDATE EMPLOYEE
SET??? first_name = #first_name#
WHERE? id = #id#
DELETE FROM EMPLOYEE
WHERE? id = #id#
parameterMap="getEmpInfoCall">
{ call getEmp( #acctID# ) }?
javaType="java.lang.Integer" mode="IN"/>
IbatisSP.java 文件:
文件將應(yīng)用程序級(jí)別的邏輯讀取使用結(jié)果映射Employee表員工的姓名name:
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 ");
}
}
編譯和運(yùn)行:
下面是步驟來(lái)編譯并運(yùn)行上述應(yīng)用程序。請(qǐng)確保您在進(jìn)行的編譯和執(zhí)行之前,適當(dāng)?shù)卦O(shè)置PATH和CLASSPATH。
創(chuàng)建Employee.xml如上所示。
創(chuàng)建Employee.java如上圖所示,并編譯它。
創(chuàng)建IbatisSP.java如上圖所示,并編譯它。
執(zhí)行IbatisSP二進(jìn)制文件來(lái)運(yùn)行程序。
得到以下結(jié)果:
Going to read record..... ID:?1?First?Name:?Zara?Last?Name:?Ali?Salary:?5000?Record read Successfully
九、iBATIS動(dòng)態(tài)SQL
使用動(dòng)態(tài)查詢是iBatis一個(gè)非常強(qiáng)大的功能。有時(shí)你已經(jīng)改變WHERE子句條件的基礎(chǔ)上你的參數(shù)對(duì)象的狀態(tài)。在這種情況下的iBATIS提供了一組可以映射語(yǔ)句中使用,以提高SQL語(yǔ)句的重用性和靈活性的動(dòng)態(tài)SQL標(biāo)簽。
所有的邏輯是使用一些額外的標(biāo)簽放在:XML文件。下面是一個(gè)例子,其中的SELECT語(yǔ)句將努力在兩個(gè)方面:
如果想傳遞一個(gè)ID,然后它會(huì)返回所有與該ID的記錄,
否則,將返回所有雇員ID為NULL的記錄。
PUBLIC "-//ibatis.apache.org//DTD?SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
SELECT * FROM EMPLOYEE
id IS NULL
id = #id#
可以使用標(biāo)簽如下檢查條件。在此條件下將增加,只有當(dāng)通過(guò)屬性不為空。
?? SELECT * FROM EMPLOYEE
??
?????
?????????? id = #id#
如果想查詢對(duì)id和/或雇員的名字選取。SELECT語(yǔ)句如下:
?? SELECT * FROM EMPLOYEE
??
?????
?????????? id = #id#
?????
?????????? first_name = #first_name#
例如:動(dòng)態(tài)SQL
下面的例子將展示如何編寫(xiě)SELECT語(yǔ)句中使用動(dòng)態(tài)SQL??紤],我們已經(jīng)在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 |
|? 3 | Noha?????? | Ali?????? |?? 7000 |
+----+------------+-----------+--------+
3 row in set (0.00 sec)
Employee POJO 類:
要執(zhí)行讀取操作,讓我們?cè)贓mployee.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映射語(yǔ)句,我們將增加在以下文件Employee.xml修改標(biāo)記和這個(gè)標(biāo)簽定義,我們將定義一個(gè)“id”,這將被用于IbatisReadDy.java文件上執(zhí)行動(dòng)態(tài)SQL的SELECT查詢數(shù)據(jù)庫(kù)。
PUBLIC "-//ibatis.apache.org//DTD?SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
SELECT * FROM EMPLOYEE
id = #id#
上面的SELECT語(yǔ)句將努力在兩個(gè)方面(一)如果想傳遞一個(gè)ID,然后將相應(yīng)的編號(hào)(二)返回的記錄,否則將返回所有記錄。
IbatisReadDy.java 文件:
文件將應(yīng)用程序級(jí)別的邏輯從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 ems = (List)
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 ");
}
}
編譯和運(yùn)行:
下面是步驟來(lái)編譯并運(yùn)行上述應(yīng)用。請(qǐng)確保已在進(jìn)行的編譯和執(zhí)行之前,適當(dāng)?shù)卦O(shè)置PATH和CLASSPATH。
創(chuàng)建Employee.xml如上所示。
創(chuàng)建Employee.java如上圖所示,并編譯它。
創(chuàng)建IbatisReadDy.java如上圖所示,并編譯它。
執(zhí)行IbatisReadDy二進(jìn)制文件來(lái)運(yùn)行程序。
會(huì)得到下面的結(jié)果,并且將記錄從EMPLOYEE表中讀取。
Going to read records.....?1?Zara?Ali?5000?Record?Reads?Successfully
試試上面的例子中通過(guò)傳遞空值作為smc.queryForList(“Employee.findByID”,NULL)。
iBATIS OGNL 表達(dá)式
iBATIS的提供了強(qiáng)大的基于OGNL的表達(dá)式來(lái)消除其他元素。
if 語(yǔ)句
choose, when, otherwise 語(yǔ)句
where 語(yǔ)句
foreach 語(yǔ)句
if語(yǔ)句:
最常見(jiàn)的事情在動(dòng)態(tài)SQL是有條件地包括一個(gè)where子句的一部分。例如:
?????????? parameterType="Blog" resultType="Blog">
?? SELECT * FROM BLOG
?? WHERE state = 'ACTIVE.
??
????? AND title like #{title}
這條語(yǔ)句會(huì)提供功能的可選的文本搜索類型。如果沒(méi)有傳遞title,那么所有激活的博客將被退回。但是,如果傳遞一個(gè)標(biāo)題,它會(huì)尋找標(biāo)題以like?給定的條件。?
可以包括多個(gè)if條件如下:
最常見(jiàn)的事情在動(dòng)態(tài)SQL是有條件地包括一個(gè)where子句的一部分。例如:
?????????? parameterType="Blog" resultType="Blog">
?? SELECT * FROM BLOG
?? WHERE state = 'ACTIVE.
??
????? AND title like #{title}
??
????? AND author like #{author}
choose, when, otherwise 語(yǔ)句:
iBATIS提供了一個(gè)選擇的元素,它類似于Java的switch語(yǔ)句。這有助于選擇很多種情況。
下面的例子將只搜索標(biāo)題上如果提供,那么只有由作者如果已提供。如果沒(méi)有提供,讓我們只返回精選的博客:
parameterType="Blog" resultType="Blog">
SELECT * FROM BLOG
WHERE state = 'ACTIVE.
AND title like #{title}
author.name?!= null">
AND author like #{author}
AND featured = 1
where 語(yǔ)句:
如果我們看一下前面的例子中,如果沒(méi)有一個(gè)條件滿足會(huì)發(fā)生什么事?最終SQL看起來(lái)像這樣:
SELECT * FROM BLOG WHERE
這會(huì)失敗,但iBATIS有一個(gè)簡(jiǎn)單的改變一個(gè)簡(jiǎn)單的解決方案,讓一切工作正常:
?????????? parameterType="Blog" resultType="Blog">
?? SELECT * FROM BLOG
??
?????
???????? state = #{state}
?????
???????? AND title like #{title}
???????? AND author like #{author}
where元素知道只有插入WHERE?,如果有一個(gè)由含標(biāo)簽返回的任何內(nèi)容。此外,如果該內(nèi)容開(kāi)頭AND或OR,它知道剝離其關(guān)閉。
foreach語(yǔ)句:
foreach元素是非常強(qiáng)大的,并允許你指定一個(gè)集合,聲明可以在元素的體內(nèi)可用于項(xiàng)目和索引變量。
它也允許你指定打開(kāi)和關(guān)閉的字符串,并添加一個(gè)分隔符放置在迭代之間。可以建立一個(gè)IN條件如下:
?? SELECT *
?? FROM POST P
?? WHERE ID in
????? open="(" separator="," close=")">
???????? #{item}
十、iBATIS調(diào)試
這是很容易,同時(shí)與iBATIS的工作程序進(jìn)行調(diào)試。 iBATIS有內(nèi)置的日志支持,并適用于下列日志庫(kù),并在這個(gè)順序搜索他們。
Jakarta Commons日志記錄(JCL)。
Log4J
JDK 日志
可以使用任何上面列出的庫(kù)在iBATIS。
調(diào)試和Log4J:
假設(shè)你要使用Log4J,這是最好用的日志記錄。繼續(xù)操作之前,需要交叉檢查以下幾點(diǎn):
Log4J JAR 文件 (log4j-{version}.jar) 應(yīng)在CLASSPATH中。
必須在CLASSPATH中提供log4j.properties。
下面是一個(gè)log4j.properties文件。請(qǐng)注意,某些行被注釋掉了。你可以取消他們,如果你需要額外的調(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
可以找到完整的Log4J文檔,從Apaches?網(wǎng)站:Log4J 文檔.
iBATIS 調(diào)試?yán)樱?/p>
下面的Java類是一個(gè)非常簡(jiǎn)單的例子,初始化,然后使用Java應(yīng)用程序Log4J的日志庫(kù)。它位于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 ems = (List)
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 ");
}
}
編譯和運(yùn)行:
下面是步驟來(lái)編譯并運(yùn)行上述軟件。請(qǐng)確保您已在進(jìn)行的編譯和執(zhí)行之前,適當(dāng)?shù)卦O(shè)置PATH和CLASSPATH。
創(chuàng)建Employee.xml如上所示。
創(chuàng)建Employee.java如上圖所示,并編譯它。
創(chuàng)建IbatisUpdate.java如上圖所示,并編譯它。
創(chuàng)建log4j.properties文件,如上圖所示。
執(zhí)行IbatisUpdate二進(jìn)制文件來(lái)運(yùn)行程序。
會(huì)得到下面的結(jié)果,并記錄在EMPLOYEE表進(jìn)行更新, 然后相同的記錄將被從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
調(diào)試方法:
在上面的例子中,我們只使用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);