Java必會技能之iBATIS

一、iBATIS介紹

iBATIS的是一個持久層框架,它能夠自動在Java, .NET, 和Ruby on Rails中與SQL數據庫和對象之間的映射。映射是從應用程序邏輯封裝在XML配置文件中的SQL語句脫鉤。

iBATIS是一個輕量級的框架和持久性API適合持久化的POJO(普通Java對象)。

iBATIS是被稱為一個數據映射和映射需要的類的屬性和數據庫中的表的列之間的參數和結果。

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

iBATIS的設計理念:

iBatis提供了以下的設計理念:

簡單:?iBATIS的被廣泛認為是可用的最簡單的持久化框架之一。

快速開發:iBATIS的理念是盡一切可能,以方便超快速開發。

可移植性:?iBATIS可用于幾乎任何語言或平臺,如Java,Ruby和C#,微軟.NET實現。

獨立的接口:iBATIS提供獨立于數據庫的接口和API,幫助應用程序的其余部分保持獨立的任何持久性相關的資源,

開源:iBATIS是自由和開放源碼軟件。

IBATIS的優點

下面是使用iBATIS的一些優勢:

支持存儲過程:iBATIS的SQL封裝以存儲過程的形式,使業務邏輯保持在數據庫之外,應用程序更易于部署和測試,更便于移植。

支持內嵌的SQL:預編譯器不是必需的,并有完全訪問所有的SQL語句的特性。

支持動態SQL:?iBATIS特性提供基于參數動態生成SQL查詢。

支持O / RM:iBATIS支持許多相同的功能作為一個O / RM工具,如延遲加載,連接抓取,緩存,運行時代碼生成和繼承

先決條件:

在開始之前,要確保你了解過程和面向對象編程的基本知識:控制結構,數據結構和變量,類,對象等。

iBATIS使用Java編程語言開發面向數據庫應用程序。

二、iBATIS配置環境

iBATIS 安裝:

這里有幾個簡單的步驟,需要開展Linux機器上安裝iBATIS:

下載iBATIS的最新版本下載iBATIS.

解壓下載的文件,從包中提取.jar文件并將其保存在相應的lib目錄下。

在提取 .jar文件適當設置PATH和CLASSPATH變量。

下面是進行Linux機器下載iBATIS的二進制文件的步驟:

$ 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://localhost:3306/testdb".

使用的用戶名和密碼是 "root" and "root".

SQL語句映射的所有操作將被描述在"Employee.xml".

基于上述假設,我們必須創建一個XML配置文件,nameSqlMapConfig.xml以下內容。這就是需要提供所需的iBatis的所有配置:

這兩個文件SqlMapConfig.xml和Employee.xml 存在于類路徑。

現在,我們將保持Employee.xml文件為空,我們將格式轉換的在隨后的章節內容。




?useStatementNamespaces="true"/> ?

?resource="Employee.xml"/>

還有其他一些可選的屬性,您可以在SqlMapConfig.xml文件中設置:

三、iBATIS創建操作

若要使用iBATIS執行的任何CRUD(創建,寫入,更新和刪除)操作,需要創建一個的POJO(普通Java對象)類對應的表。本課程介紹的對象,將“模式”的數據庫表中的行。

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映射語句中,我們將使用標簽,這個標簽定義中,我們會定義將用于在IbatisInsert.java文件的數據庫執行SQL INSERT查詢“id”。


insert into EMPLOYEE(first_name, last_name, salary) values (#first_name#, #last_name#, #salary#)

select last_insert_id() as id ?


這里parameterClass:可以采取一個值作為字符串,整型,浮點型,double或根據要求任何類的對象。在這個例子中,我們將通過Employee對象作為參數而調用SqlMap類的insert方法。

如果您的數據庫表使用IDENTITY,AUTO_INCREMENT或串行列或已定義的SEQUENCE/GENERATOR,可以使用元素在的語句中使用或返回數據庫生成的值。

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讀取操作

我們已經在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類中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映射語句,我們將增加標記在Employee.xml文件,這個標簽定義中,我們會定義將用于在IbatisRead.java文件的數據庫執行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

在這里,我們沒有使用WHERE子句和SQL SELECT語句。后續章節將演示如何用WHERE和SELECT語句子句,以及如何將值傳遞到WHERE子句。

IbatisRead.java 文件:

該文件將應用程序級別的邏輯從雇員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 ");

}

}

編譯和運行:

下面是步驟來編譯并運行上述應用。請確保您已在進行的編譯和執行之前,適當地設置PATH和CLASSPATH。

創建Employee.xml如上所示。

創建Employee.java如上圖所示,并編譯它。

創建IbatisRead.java如上圖所示,并編譯它。

執行IbatisRead二進制文件來運行程序。

你會得到下面的結果,并且將記錄從EMPLOYEE表中讀取。

Going to read records.....?1?Zara?Ali?5000?Record?Reads?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)

);

此表有如下只有一條記錄:

mysql>?select?*?from EMPLOYEE;+----+------------+-----------+--------+| id | first_name | last_name | salary |+----+------------+-----------+--------+

|?1?|?Zara?|?Ali?|?5000?|

+----+------------+-----------+--------+1 row in?set?(0.00 sec)

Employee POJO 類:

要執行讀操作,我們將修改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映射語句,我們想補充的標簽Employee.xml文件,這個標簽定義中,我們會定義將用于在IbatisUpdate.java文件的數據庫執行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 ");

}

}

編譯和運行:

下面是步驟來編譯并運行上述軟件。請確保您已在進行的編譯和執行之前,適當地設置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刪除操作

我們已經在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 類:

要執行讀操作,我們將修改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映射語句中,我們將增加鍵標簽Employee.xml文件,這個標簽定義中,我們會定義將用于在IbatisDelete.java文件執行SQL DELETE查詢數據庫的“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 文件:

文件將應用程序級別的邏輯從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 ");

}

}

編譯和運行:

下面是步驟來編譯并運行上述軟件。請確保已在進行的編譯和執行之前,適當地設置PATH和CLASSPATH。

創建Employee.xml如上所示。

創建Employee.java如上圖所示,并編譯它。

創建IbatisDelete.java如上圖所示,并編譯它。

執行IbatisDelete二進制文件來運行程序。

得到以下結果,ID=1將在EMPLOYEE表中被刪除,并讀取EMPLOYEE表中的一條記錄。

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

七、iBATIS結果映射

resultMap的元素是在iBATIS的最重要和最強大的元素。您可以通過使用iBATIS的結果映射減少高達90%的JDBC編碼,在某些情況下,可以讓你做JDBC不支持的事情。

ResultMaps的設計是這樣的簡單語句不需要明確的結果映射,以及更復雜的報表要求不超過絕對必要說明的關系。

本章將只給你一個簡單的介紹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?|?

+----+------------+-----------+--------+

1 row in?set?(0.00 sec)

Employee POJO 類:

要執行讀操作,我們將修改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文件介紹標記。這個標簽就必須在我們標記的resultMap屬性運行此結果映射這是需要一個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 文件:

文件將應用程序級別的邏輯,從使用結果映射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文件介紹和標記。這里標簽將有一個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#


parameterMap="getEmpInfoCall">

{ call getEmp( #acctID# ) }?

javaType="java.lang.Integer" mode="IN"/>

IbatisSP.java 文件:

文件將應用程序級別的邏輯讀取使用結果映射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 ");

}

}

編譯和運行:

下面是步驟來編譯并運行上述應用程序。請確保您在進行的編譯和執行之前,適當地設置PATH和CLASSPATH。

創建Employee.xml如上所示。

創建Employee.java如上圖所示,并編譯它。

創建IbatisSP.java如上圖所示,并編譯它。

執行IbatisSP二進制文件來運行程序。

得到以下結果:

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

九、iBATIS動態SQL

使用動態查詢是iBatis一個非常強大的功能。有時你已經改變WHERE子句條件的基礎上你的參數對象的狀態。在這種情況下的iBATIS提供了一組可以映射語句中使用,以提高SQL語句的重用性和靈活性的動態SQL標簽。

所有的邏輯是使用一些額外的標簽放在:XML文件。下面是一個例子,其中的SELECT語句將努力在兩個方面:

如果想傳遞一個ID,然后它會返回所有與該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#

可以使用標簽如下檢查條件。在此條件下將增加,只有當通過屬性不為空。

?? SELECT * FROM EMPLOYEE

??

?????

?????????? id = #id#



如果想查詢對id和/或雇員的名字選取。SELECT語句如下:

?? SELECT * FROM EMPLOYEE

??

?????

?????????? id = #id#


?????

?????????? first_name = #first_name#



例如:動態SQL

下面的例子將展示如何編寫SELECT語句中使用動態SQL。考慮,我們已經在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 類:

要執行讀取操作,讓我們在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映射語句,我們將增加在以下文件Employee.xml修改標記和這個標簽定義,我們將定義一個“id”,這將被用于IbatisReadDy.java文件上執行動態SQL的SELECT查詢數據庫。


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語句將努力在兩個方面(一)如果想傳遞一個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 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 ");

}

}

編譯和運行:

下面是步驟來編譯并運行上述應用。請確保已在進行的編譯和執行之前,適當地設置PATH和CLASSPATH。

創建Employee.xml如上所示。

創建Employee.java如上圖所示,并編譯它。

創建IbatisReadDy.java如上圖所示,并編譯它。

執行IbatisReadDy二進制文件來運行程序。

會得到下面的結果,并且將記錄從EMPLOYEE表中讀取。

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

試試上面的例子中通過傳遞空值作為smc.queryForList(“Employee.findByID”,NULL)。

iBATIS OGNL 表達式

iBATIS的提供了強大的基于OGNL的表達式來消除其他元素。

if 語句

choose, when, otherwise 語句

where 語句

foreach 語句

if語句:

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

?????????? parameterType="Blog" resultType="Blog">

?? SELECT * FROM BLOG

?? WHERE state = 'ACTIVE.

??

????? AND title like #{title}


這條語句會提供功能的可選的文本搜索類型。如果沒有傳遞title,那么所有激活的博客將被退回。但是,如果傳遞一個標題,它會尋找標題以like?給定的條件。?

可以包括多個if條件如下:

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

?????????? parameterType="Blog" resultType="Blog">

?? SELECT * FROM BLOG

?? WHERE state = 'ACTIVE.

??

????? AND title like #{title}


??

????? AND author like #{author}


choose, when, otherwise 語句:

iBATIS提供了一個選擇的元素,它類似于Java的switch語句。這有助于選擇很多種情況。

下面的例子將只搜索標題上如果提供,那么只有由作者如果已提供。如果沒有提供,讓我們只返回精選的博客:

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 語句:

如果我們看一下前面的例子中,如果沒有一個條件滿足會發生什么事?最終SQL看起來像這樣:

SELECT * FROM BLOG WHERE

這會失敗,但iBATIS有一個簡單的改變一個簡單的解決方案,讓一切工作正常:

?????????? parameterType="Blog" resultType="Blog">

?? SELECT * FROM BLOG

??

?????

???????? state = #{state}


?????

???????? AND title like #{title}



???????? AND author like #{author}



where元素知道只有插入WHERE?,如果有一個由含標簽返回的任何內容。此外,如果該內容開頭AND或OR,它知道剝離其關閉。

foreach語句:

foreach元素是非常強大的,并允許你指定一個集合,聲明可以在元素的體內可用于項目和索引變量。

它也允許你指定打開和關閉的字符串,并添加一個分隔符放置在迭代之間。可以建立一個IN條件如下:

?? SELECT *

?? FROM POST P

?? WHERE ID in


????? open="(" separator="," close=")">

???????? #{item}


十、iBATIS調試

這是很容易,同時與iBATIS的工作程序進行調試。 iBATIS有內置的日志支持,并適用于下列日志庫,并在這個順序搜索他們。

Jakarta Commons日志記錄(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

可以找到完整的Log4J文檔,從Apaches?網站:Log4J 文檔.

iBATIS 調試例子:

下面的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 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 ");

}

}

編譯和運行:

下面是步驟來編譯并運行上述軟件。請確保您已在進行的編譯和執行之前,適當地設置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);

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容