Ibatis 简明教程

iBATIS - Quick Guide

iBATIS - Overview

iBATIS 是一个持久化框架,它在 Java、.NET 和 Ruby on Rails 中自动执行 SQL 数据库和对象之间的映射。映射与应用程序逻辑相分离,将 SQL 语句封装在 XML 配置文件中。

iBATIS 是一个轻量级的持久化 API,适合持久化 POJO(旧式纯 Java 对象)。

iBATIS 是一个众所周知的数据映射器,负责在类属性和数据库表的列之间映射参数和结果。

iBATIS 和诸如 Hibernate 等其他持久化框架之间的一个显著差异是 iBATIS 强调使用 SQL,而其他框架通常使用自定义查询语言,如 Hibernate 查询语言 (HQL) 或企业 JavaBean 查询语言 (EJB QL)。

iBATIS Design Philosophies

iBATIS 采用以下设计理念:

  1. Simplicity − iBATIS 被广泛认为是现今最简单的持久化框架之一。

  2. Fast Development − iBATIS 尽力促进超快速开发。

  3. Portability − iBATIS 可实现于近乎任何语言或平台,如面向 Microsoft .NET 的 Java、Ruby 和 C#。

  4. Independent Interfaces − iBATIS 提供与数据库无关的接口和 API,可帮助其余应用程序保持独立于任何与持久性相关的资源。

  5. Open source − iBATIS 是免费的开源软件。

Advantages of iBATIS

iBATIS 提供以下优势:

  1. Supports stored procedures − iBATIS 以存储过程的形式封装 SQL,以便将业务逻辑置于数据库之外,并且应用程序更易于部署和测试,并且更具可移植性。

  2. Supports inline SQL − 并不需要预编译器,并且您可以完整访问 SQL 的所有功能。

  3. Supports dynamic SQL − iBATIS 提供基于参数动态生成 SQL 查询的功能。

  4. Supports O/RM − iBATIS 支持与 O/RM 工具类似的诸多功能,如延迟加载、连接提取、缓存、运行时代码生成和继承

iBATIS 在开发面向数据库应用程序时使用 JAVA 编程语言。在继续阅读之前,请确保您理解过程式和面向对象编程的基础知识,比如控制结构、数据结构和变量、类、对象等。

要详细了解 JAVA,您可以阅读我们的 JAVA Tutorial

iBATIS - Environment

在开始实际开发工作之前,您必须为 iBATIS 设置适当的环境。本章介绍如何为 iBATIS 设置工作环境。

iBATIS Installation

执行以下简单步骤在您的 Linux 机器上安装 iBATIS −

  1. Download iBATIS 下载 iBATIS 的最新版本。

  2. 解压缩下载的文件以从捆绑包中提取 .jar 文件,并将其保存在适当的 lib 目录中。

  3. 在提取的 .jar 文件中适当设置 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

Database Setup

使用以下语法在任何 MySQL 数据库中创建“员工”表——

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

Create SqlMapConfig.xml

考虑以下内容——

  1. 我们将使用 JDBC 访问数据库 testdb

  2. MySQL 的 JDBC 驱动程序是 “com.mysql.jdbc.Driver”。

  3. Connection URL is "jdbc:mysql://localhost:3306/testdb".

  4. 我们的用户名和密码分别是 “root” 和 “root”。

  5. 所有操作的 SQL 语句映射都将在 “Employee.xml” 中描述。

根据上述假设,我们需要创建名为 SqlMapConfig.xml 的 XML 配置文件,其中包含以下内容。你需要在此配置中提供 iBatis 所需的所有配置——

SqlMapConfig.xml 和 Employee.xml 两个文件都必须放在 class 路径中。现在,我们将保持 Employee.xml 文件内容为空,后续章节的内容将对其进行介绍。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
   <settings useStatementNamespaces="true"/>

   <transactionManager type="JDBC">
      <dataSource type="SIMPLE">

         <property name="JDBC.Driver" value="com.mysql.jdbc.Driver"/>
         <property name="JDBC.ConnectionURL" value="jdbc:mysql://localhost:3306/testdb"/>
         <property name="JDBC.Username" value="root"/>
         <property name="JDBC.Password" value="root"/>

      </dataSource>
   </transactionManager>

   <sqlMap resource="Employee.xml"/>
</sqlMapConfig>

你还可以使用 SqlMapConfig.xml 文件设置以下可选属性——

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

iBATIS - Create Operation

要执行任何使用iBATIS的创建、读取、更新和删除(CRUD)操作,您需要创建一个与该表对应的纯Java对象(POJO)类。此类描述将“建模”数据库表行的对象。

POJO 类具有实现执行所需操作的所有方法。

我们假设在 MySQL 中具有以下 EMPLOYEE 表:

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

Employee POJO Class

我们将 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 File

为了使用 iBATIS 定义 SQL 映射语句,我们将使用 <insert> 标记,在此标记定义内我们将定义一个“id”,该 id 将在 IbatisInsert.java 文件中用于在数据库上执行 SQL INSERT 查询。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Employee">

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

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

</sqlMap>

此处 parameterClass − 可根据要求采用字符串、int、float、double 或任何类对象作为值。在此示例中,在调用 SqlMap 类的 insert 方法时,我们将 Employee 对象作为参数传递。

如果数据库表使用 IDENTITY、AUTO_INCREMENT 或 SERIAL 列,或者您已定义一个 SEQUENCE/GENERATOR,则可以在 <insert> 语句中使用 <selectKey> 元素以使用或返回该数据库生成的值。

IbatisInsert.java File

此文件将具有插入 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 ");
   }
}

Compilation and Run

以下是编译和运行上述软件的步骤。在继续编译和执行之前,请确保已正确设置 PATH 和 CLASSPATH。

  1. 按上述方式创建 Employee.xml。

  2. 按上述方式创建 Employee.java 并对其进行编译。

  3. 创建 IbatisInsert.java(如上所示)并进行编译。

  4. 执行 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 - Read Operation

我们在上一章中讨论了如何使用 iBATIS 对表执行 CREATE 操作。本章将说明如何使用 iBATIS 读取表。

我们在 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)
);

此表仅有一个记录,如下所示 -

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

Employee POJO Class

要执行读取操作,我们将在 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 File

为了使用 iBATIS 定义 SQL 映射语句,我们将在 Employee.xml 文件中添加 <select> 标记,在该标记定义中,我们将定义一个将在 IbatisRead.java 文件中用于对数据库执行 SQL SELECT 查询的“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">

   <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 语句一起使用。我们将在下一章中演示如何使用 WHERE 子句与 SELECT 语句一起使用,以及如何将值传递给该 WHERE 子句。

IbatisRead.java File

该文件具有从 Employee 表读取记录的应用程序级逻辑:

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

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

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

      /* This would read all records from the Employee table. */
      System.out.println("Going to read records.....");
      List <Employee> ems = (List<Employee>)
         smc.queryForList("Employee.getAll", null);
      Employee em = null;

      for (Employee e : ems) {
         System.out.print("  " + e.getId());
         System.out.print("  " + e.getFirstName());
         System.out.print("  " + e.getLastName());
         System.out.print("  " + e.getSalary());
         em = e;
         System.out.println("");
      }

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

Compilation and Run

以下是编译和运行上述软件的步骤。在继续编译和执行之前,请确保已正确设置 PATH 和 CLASSPATH。

  1. 按上述方式创建 Employee.xml。

  2. 按上述方式创建 Employee.java 并对其进行编译。

  3. 按照上面显示的方式创建 IbatisRead.java 并对其进行编译。

  4. 执行 IbatisRead 二进制文件以运行该程序。

你会获得以下结果,并且会从 EMPLOYEE 表中读取一条记录,如下所示:

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

iBATIS - Update Operation

在上一章中,我们讨论了如何使用 iBATIS 对表执行 READ 操作。本章将解释如何使用 iBATIS 更新表中的记录。

我们在 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)
);

此表仅有一个记录,如下所示 -

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

Employee POJO Class

要执行 udpate 操作,您需要如下修改 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 File

要使用 iBATIS 定义 SQL 映射语句,我们将在 Employee.xml 中添加 <update> 标签,并且在此标签定义内,我们将定义一个“id”,该 id 将在 IbatisUpdate.java 文件中用于对数据库执行 SQL UPDATE 查询。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Employee">

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

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

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

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

</sqlMap>

IbatisUpdate.java File

这个文件具有将记录更新到 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 ");
   }
}

Compilation and Run

以下是如何编译和运行上述软件的步骤。在继续编译和执行之前,请确保已正确设置 PATH 和 CLASSPATH。

  1. 按上述方式创建 Employee.xml。

  2. 按上述方式创建 Employee.java 并对其进行编译。

  3. 如上所示创建 IbatisUpdate.java 并编译它。

  4. 执行 IbatisUpdate 二进制文件来运行程序。

您会得到以下结果,并且会更新 EMPLOYEE 表中的一条记录,然后从 EMPLOYEE 表中读取同一条记录。

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

iBATIS - Delete Operation

本章节描述如何使用 iBATIS 来从一张表中删除记录。

我们在 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)
);

假设这表有如下两条记录 −

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 Class

为了执行删除操作,你不需要修改 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 File

为了使用 iBATIS 来定义 SQL 映射语句,我们会在 Employee.xml 中添加 <delete> 标签,然后在这段标签定义中,我们会定义将被用来在 IbatisDelete.java 文件中执行 SQL DELETE 查询的一个“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">

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

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

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

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

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

</sqlMap>

IbatisDelete.java File

这个文件有应用程序级别的逻辑来从 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 ");
   }
}

Compilation and Run

以下是如何编译和运行上述软件的步骤。在继续编译和执行之前,请确保已正确设置 PATH 和 CLASSPATH。

  1. 按上述方式创建 Employee.xml。

  2. 按上述方式创建 Employee.java 并对其进行编译。

  3. 按上述所示创建 IbatisDelete.java 并将其编译。

  4. 执行 IbatisDelete 二进制文件来运行程序。

你会得到以下结果,一个 ID = 1的记录将从 EMPLOYEE 表中删除,而其余记录则会被读取。

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

iBATIS - Result Maps

resultMap 元素是 iBATIS 中最重要的并且功能最强的元素。使用 iBATIS ResultMap 可以减少高达 90% 的 JDBC 编码,并且在某些情况下,它允许你执行 JDBC 甚至不支持的操作。

ResultMaps 的设计使得对于简单的语句根本不需要明确的结果映射,而对于更复杂的语句,不需要指定超出绝对必要的范围来描述关系的信息。

本章仅简单介绍 iBATIS ResultMaps。

我们在 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)
);

此表有两个记录,如下所示:

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 Class

要使用 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 File

在这里,我们将修改 Employee.xml 以引入 <resultMap></resultMap> 标记。此标记将具有一个 id,我们的 <select> 标记的 resultMap 属性需要它才能运行该 resultMap。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Employee">

   <!-- Perform Insert Operation -->

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

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

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

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

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

   <!-- Using ResultMap -->
   <resultMap id="result" class="Employee">
      <result property="id" column="id"/>
      <result property="first_name" column="first_name"/>
      <result property="last_name" column="last_name"/>
      <result property="salary" column="salary"/>
   </resultMap>

   <select id="useResultMap" resultMap="result">
      SELECT * FROM EMPLOYEE
      WHERE id=#id#
   </select>

</sqlMap>

IbatisResultMap.java File

此文件具有使用 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 ");
   }
}

Compilation and Run

以下是如何编译和运行上述软件的步骤。在继续编译和执行之前,请确保已正确设置 PATH 和 CLASSPATH。

  1. 按上述方式创建 Employee.xml。

  2. 按上述方式创建 Employee.java 并对其进行编译。

  3. 按照上面显示的方式创建 IbatisResultMap.java 并对其进行编译。

  4. 执行 IbatisResultMap 二进制文件以运行该程序。

你会得到在 EMPLOYEE 表上执行的读取操作,其结果如下。

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

iBATIS - Stored Procedures

你可以使用 iBATIS 配置来调用存储过程。首先,让我们了解如何在 MySQL 中创建存储过程。

我们在 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)
);

我们将在 MySQL 数据库中创建以下存储过程——

DELIMITER $$

   DROP PROCEDURE IF EXISTS `testdb`.`getEmp` $$
   CREATE PROCEDURE `testdb`.`getEmp`
   (IN empid INT)

   BEGIN
      SELECT * FROM EMPLOYEE
      WHERE ID = empid;
   END $$

DELIMITER;

考虑 “员工” 表中有以下两条记录——

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 Class

若要使用存储过程,则无需修改 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 File

在这里,我们将修改 Employee.xml 以引入 <procedure></procedure> 和 <parameterMap></parameterMap> 标记。<procedure></procedure> 标记有一个 ID,我们将在应用程序中使用此 ID 来调用存储过程。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Employee">

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

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

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

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

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

   <!-- To call stored procedure. -->
   <procedure id="getEmpInfo" resultClass="Employee" parameterMap="getEmpInfoCall">
      { call getEmp( #acctID# ) }
   </procedure>

   <parameterMap id="getEmpInfoCall" class="map">
      <parameter property="acctID" jdbcType="INT" javaType="java.lang.Integer" mode="IN"/>
   </parameterMap>

</sqlMap>

IbatisSP.java File

此文件中包含应用程序级别的逻辑,用于使用 ResultMap 从“员工”表中读取员工的姓名——

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 ");
   }
}

Compilation and Run

以下是如何编译和运行上述软件的步骤。在继续编译和执行之前,请确保已正确设置 PATH 和 CLASSPATH。

  1. 按上述方式创建 Employee.xml。

  2. 按上述方式创建 Employee.java 并对其进行编译。

  3. 按上述所示创建 IbatisSP.java 并将其编译。

  4. 执行 IbatisSP 二进制文件来运行程序。

你会得到下列结果:

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

iBATIS - Dynamic SQL

动态 SQL 是 iBATIS 中一项非常强大的功能。有时,您不得不在根据您的参数对象的状态更改 WHERE 子句条件。在这种情况下,iBATIS 提供了一组动态 SQL 标签,可在映射的语句中使用,以增强 SQL 的可重用性和灵活性。

所有逻辑都使用一些其他标签放入 .XML 文件中。以下是一个 SELECT 语句将以两种方式工作的示例:

如果您传递一个 ID,它将返回对应于该 ID 的所有记录。

否则,它将返回所有员工 ID 设置为 NULL 的记录。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Employee">

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

      <dynamic prepend="WHERE ">
         <isNull property="id">
            id IS NULL
         </isNull>

         <isNotNull property="id">
            id = #id#
         </isNotNull>
      </dynamic>

   </select>
</sqlMap>

您可以按照以下方式使用 <isNotEmpty> 标记检查条件。在此,仅当传递的属性不为空时,才会添加条件。

..................
<select id="findByID" resultClass="Employee">
   SELECT * FROM EMPLOYEE

   <dynamic prepend="WHERE ">
      <isNotEmpty property="id">
         id = #id#
      </isNotEmpty>
   </dynamic>

</select>
..................

如果您想要一个查询,其中我们可以选择一个 id 和/或一个 Employee 的第一个名称,您的 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>
..................

Dynamic SQL Example

以下示例显示了如何使用动态 SQL 编写 SELECT 语句。考虑在 MySQL 中,我们有以下 EMPLOYEE 表 −

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

让我们假设此表只有一个记录,如下所示 −

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

Employee POJO Class

为了执行读取操作,让我们在 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 File

为了使用 iBATIS 定义 SQL 映射语句,我们会在 Employee.xml 中添加以下修改后的 <select> 标记,并在该标记定义内部,我们将定义一个 "id",它将在 IbatisReadDy.java 中用于对数据库执行动态 SQL SELECT 查询。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Employee">
   <select id="findByID" resultClass="Employee">
      SELECT * FROM EMPLOYEE

      <dynamic prepend="WHERE ">
         <isNotNull property="id">
            id = #id#
         </isNotNull>
      </dynamic>

   </select>
</sqlMap>

上面的 SELECT 语句将以两种方式工作 −

  1. 如果您传递一个 ID,那么它会返回与该 ID 对应的记录,否则,它会返回所有记录。

IbatisReadDy.java File

此文件具有应用程序级别的逻辑,用于从 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 ");
   }
}

Compilation and Run

以下是编译和运行上述软件的步骤。在继续编译和执行之前,请确保已正确设置 PATH 和 CLASSPATH。

  1. 按上述方式创建 Employee.xml。

  2. 按上述方式创建 Employee.java 并对其进行编译。

  3. 照上面所示创建 IbatisReadDy.java,并对其进行编译。

  4. 执行 IbatisReadDy 二进制文件来运行该程序。

您将得到以下结果,并且会从 EMPLOYEE 表中读取一条记录。

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

通过传递 null 作为 smc.queryForList("Employee.findByID", null) 来尝试上面的示例。

iBATIS OGNL Expressions

iBATIS 提供了强大的基于 OGNL 的表达式,以消除大多数其他元素。

  1. if Statement

  2. choose, when, otherwise Statement

  3. where Statement

  4. foreach Statement

The if Statement

在动态 SQL 中最常见的事情是有条件地包含 where 子句的一部分。例如 −

<select id="findActiveBlogWithTitleLike" parameterType="Blog" resultType="Blog">
   SELECT * FROM BLOG
   WHERE state = 'ACTIVE.

   <if test="title != null">
      AND title like #{title}
   </if>

</select>

该语句提供了一个可选的文本搜索类型功能。如果您没有传递标题,那么它会返回所有活动的博客。但是,如果您确实传递了一个标题,它将使用给定的 like 条件查找标题。

您可以包含多个 if 条件,如下所示 −

<select id="findActiveBlogWithTitleLike" parameterType="Blog" resultType="Blog">
   SELECT * FROM BLOG
   WHERE state = 'ACTIVE.

   <if test="title != null">
      AND title like #{title}
   </if>

   <if test="author != null">
      AND author like #{author}
   </if>

</select>

The choose, when, and otherwise Statements

iBATIS 提供了一个 choose 元素,类似于 Java 的 switch 语句。它有助于在许多选项中只选择一个 case。

以下示例只根据标题进行搜索(如果提供了标题的话),然后根据给定的作者进行搜索。如果没有提供标题或作者,它只返回精选的博客 −

<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>

The where Statement

查看我们之前的示例,看看没有满足任何条件时会发生什么。您最终将得到一条类似这样的 SQL 语句 −

SELECT * FROM BLOG
WHERE

这会失败,但 iBATIS 借助一个简单的更改就提供了一个简单的解决方案,一切都正常运行 −

<select id="findActiveBlogLike" parameterType="Blog" resultType="Blog">
   SELECT * FROM BLOG

   <where>
      <if test="state != null">
         state = #{state}
      </if>

      <if test="title != null">
         AND title like #{title}
      </if>

      <if test="author != null>
         AND author like #{author}
      </if>
   </where>

</select>

where 元素只在包含它的标记返回任何内容时才插入 WHERE。此外,如果该内容以 AND 或 OR 开头,它知道要剔除它。

The foreach Statement

foreach 元素允许你指定一个集合并声明可以在元素内部使用的项目和索引变量。

它还允许你指定开始字符串和结束字符串以及添加一个分隔符以置于迭代之间。你可以按照如下方法构建一个 IN 条件 −

<select id="selectPostIn" resultType="domain.blog.Post">
   SELECT *
   FROM POST P
   WHERE ID in

   <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
      #{item}
   </foreach>

</select>

iBATIS - Debugging

在使用 iBATIS 时调试你的程序很容易。iBATIS 内置有日志记录支持,它与以下日志库协作,并按此顺序搜索它们。

  1. Jakarta Commons Logging (JCL).

  2. Log4J

  3. JDK logging

你可以将上面列出的任何库与 iBATIS 一起使用。

Debugging with Log4J

假设你打算使用 Log4J 进行日志记录。在继续操作之前,你需要交叉检查以下几点 −

  1. Log4J JAR 文件 (log4j-{version}.jar) 应在 CLASSPATH 中。

  2. 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

你可以在 Apaches 网站上找到 Log4J 的完整文档− Log4J Documentation

iBATIS Debugging Example

下面的 Java 类是一个非常简单的例子,它初始化 Log4J 日志库并随后将它用于 Java 应用程序。我们将使用前面提到的位于 CLASSPATH 中的属性文件。

import org.apache.log4j.Logger;

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

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

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

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

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

      log.debug("Going to read records.....");
      List <Employee> ems = (List<Employee>)
         smc.queryForList("Employee.getAll", null);
      Employee em = null;

      for (Employee e : ems) {
         System.out.print("  " + e.getId());
         System.out.print("  " + e.getFirstName());
         System.out.print("  " + e.getLastName());
         System.out.print("  " + e.getSalary());
         em = e;
         System.out.println("");
      }
      log.debug("Records Read Successfully ");
   }
}

Compilation and Run

首先,确保在继续编译和执行之前你已适当地设置 PATH 和 CLASSPATH。

  1. 按上述方式创建 Employee.xml。

  2. 按上述方式创建 Employee.java 并对其进行编译。

  3. 如上所示创建 IbatisUpdate.java 并编译它。

  4. 创建上面所示的 log4j.properties。

  5. 执行 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

Debug Methods

在上面的示例中,我们只使用了 info() 方法,但是你可以根据你的要求使用以下任何方法 −

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

iBATIS - Hibernate

iBATIS和Hibernate之间有很大的不同。这两种解决方案在给定其特定领域时都能正常工作。如下所述建议使用iBATIS−

  1. 您想创建自己的SQL并且愿意维护它们。

  2. 您的环境是由关系数据模型驱动的。

  3. 您必须基于现有且复杂的架构进行工作。

如果环境是由对象模型驱动的并且需要自动生成SQL,则使用Hibernate。

Difference between iBATIS and Hibernate

Hibernate和iBATIS都是业界可用的开源对象关系映射(ORM)工具。每种工具的使用取决于您使用它们的上下文。

下表重点介绍了iBATIS和Hibernate之间的差异−

iBATIS

Hibernate

iBATIS更简单。它采用更小的软件包大小。

Hibernate会为您生成SQL,这意味着您不必花费时间生成SQL。

iBATIS很灵活。它提供更快的开发时间。

Hibernate具有高度可扩展性。它提供了一个更高级的缓存。

iBATIS使用可能是与数据库相关的SQL。

Hibernate使用相对独立于数据库的HQL。在Hibernate中更改db更容易。

iBatis将JDBC API中的ResultSet映射到您的POJO Objets,因此您不必关心表结构。

Hibernate将您的Java POJO对象映射到数据库表。

在iBATIS中使用存储过程非常容易。

在Hibernate中使用存储过程有点困难。

Hibernate和iBATIS都受到SPRING框架的良好支持,因此选择其中一个应该不是问题。

iBATOR - Introduction

iBATOR 是一个 iBATIS 的代码生成器。iBATOR 会对一张或多张数据库表进行内省,并且生成可用于访问这些表的 iBATIS 工件。

之后你可以编写自己的自定义 SQL 代码或存储过程来满足你的需求。iBATOR 生成了以下工件 −

  1. SqlMap XML Files

  2. 类表的主键和字段相匹配的 Java 类

  3. 使用上述对象的 DAO 类(可选)

iBATOR 可以作为一个独立的 JAR 文件,或作为一个 Ant 任务,或作为一个 Eclipse 插件来运行。本教程描述了从命令行生成 iBATIS 配置文件的最简单方式。

Download iBATOR

如果你使用的是除了 Eclipse 之外的 IDE,下载独立 JAR。独立 JAR 包含了一个运行 iBATOR 的 Ant 任务,或者你也可以从 Java 代码的命令行中运行 iBATOR。

  1. 你可以从 Download iBATOR 下载 zip 文件。

  2. 你可以查看在线文档 − iBATOR Documentation

Generating Configuration File

要运行 iBATOR,请执行以下步骤:

Step 1

适当创建并填写配置文件 ibatorConfig.xml。至少必须指定以下内容:

  1. 一个 &lt;jdbcConnection&gt; 元素,用于指定如何连接到目标数据库。

  2. 一个 &lt;javaModelGenerator&gt; 元素,用于指定目标包和生成 Java 模型对象的的目标项目。

  3. 一个 &lt;sqlMapGenerator&gt; 元素,用于指定目标包和生成 SQL 映射文件的的目标项目。

  4. 一个 &lt;daoGenerator&gt; 元素,用于指定目标包和生成 DAO 接口和类的目标项目(如果不想生成 DAO,可以省略 <daoGenerator> 元素)。

  5. 至少一个数据库 &lt;table&gt; 元素

NOTE − 有关 iBATOR 配置文件的示例,请参阅 XML Configuration File Reference 页面。

Step 2

将该文件保存到便于查找的位置,例如:\temp\ibatorConfig.xml。

Step 3

现在从命令行运行 iBATOR,如下所示:

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

这将告知 iBATOR 使用配置文件运行。它还将告知 iBATOR 覆盖同名的任何现有 Java 文件。如果您要保存任何现有 Java 文件,则省略 −overwrite 参数。

如果出现冲突,iBATOR 会以唯一名称保存新生成的文件。

运行 iBATOR 后,需要创建或修改标准 iBATIS 配置文件,以利用新生成代码。下一部分对此进行了说明。

Tasks After Running iBATOR

运行 iBATOR 后,需要创建或修改其他 iBATIS 配置工件。主要任务如下:

  1. 创建或修改 SqlMapConfig.xml 文件。

  2. 创建或修改 dao.xml 文件(仅当您使用 iBATIS DAO 框架时)。

下面详细描述每个任务:

Updating the SqlMapConfig.xml File

iBATIS 使用名为 SqlMapConfig.xml 的 XML 文件来指定连接数据库的信息、事务管理方案以及 iBATIS 会话中使用的 SQL 映射 XML 文件。

iBATOR 无法为您创建此文件,因为它不知道您的执行环境。但是,此文件中的某些项直接关系到 iBATOR 生成的项。

iBATOR 配置文件中的特定需求如下 -

  1. 命名空间语句必须启用。

  2. 必须列出 iBATOR 生成的 SQL Map XML 文件。

例如,假设 iBATOR 生成了一个名为 MyTable_SqlMap.xml 的 SQL Map XML 文件,并且该文件已被放入您的项目的 test.xml 包中。SqlMapConfig.xml 文件应具有以下条目 -

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
   <!-- Statement namespaces are required for Abator -->
   <settings useStatementNamespaces="true" />

   <!-- Setup the transaction manager and data source that are
   appropriate for your environment
   -->

   <transactionManager type="...">
      <dataSource type="...">
      </dataSource>
   </transactionManager>

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

</sqlMapConfig>

如果有不止一个 SQL Map XML 文件(这是很常见的),那么可以在 <transactionManager> 元素之后使用重复的 <sqlMap> 元素以任意顺序列出这些文件。

Updating the dao.xml File

iBATIS DAO 框架由一个通常称为 dao.xml 的 xml 文件配置。

iBATIS DAO 框架使用这个文件来控制 DAO 的数据库连接信息,并且还可以列出 DAO 实现类和 DAO 接口。

在这个文件中,您应该指定 SqlMapConfig.xml 文件的路径,以及所有 iBATOR 生成的 DAO 接口和实现类。

例如,假设 iBATOR 生成了一个名为 MyTableDAO 的 DAO 接口和一个名为 MyTableDAOImpl 的实现类,并且这些文件已被放入您项目的 test.dao 包中。

dao.xml 文件应该具有以下条目 -

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

<daoConfig>

   <context>

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

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

</daoConfig>

NOTE − 仅当您为 iBATIS DAO 框架生成了 DAO 时,才需要此步骤。