Java必會(huì)技能之iBATIS

一、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);

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容