iBatis 框架

**iBatis **一词来源于“internet”和“abatis”的组合,是一个由Clinton Begin在2001年发起的开放源代码项目。于2010年6月16号被谷歌托管,改名为MyBatis。是一个基于SQL映射支持Java和.NET的持久层框架。

iBatis 提供的持久层框架包括SQL Maps和Data Access Objects(DAO),同时还提供一个利用这个框架开发的JPetStore实例。

相对Hibernate和ApacheOJB等“一站式”ORM解决方案而言,iBatis 是一种“半自动化”的ORM实现。这里的“半自动化”,是相对Hibernate等提供了全面的数据库封装机制的“全自动化”ORM 实现而言,“全自动”ORM 实现了 POJO 和数据库表之间的映射,以及 SQL 的自动生成和执行。而iBatis 的着力点,则在于POJO 与 SQL之间的映射关系。也就是说,iBatis 并不会为程序员在运行期自动生成 SQL 执行。具体的 SQL 需要程序员编写,然后通过映射配置文件,将SQL所需的参数,以及返回的结果字段映射到指定 POJO。

开发环境搭建

软件 版本
HGDB 安全版V4、企业版v5及以上版本
JDK 1.6、1.7、1.8
Java IDE Eclipse、IntelliJ IDEA
iBatis ibatis-2.3.4.726.jar

示例项目

结构图如下:

image-20220419153649110

主要文件介绍

ibatis-config.xml :iBatis 配置文件

<?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>
<!-- 使用JDBC的事务管理 -->
<transactionManager type="JDBC">
<!-- 数据源 -->
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="com.highgo.jdbc.Driver"/>
<property name="JDBC.ConnectionURL" value="jdbc:highgo://192.168.2.5:5866/test"/>
<property name="JDBC.Username" value="test"/>
<property name="JDBC.Password" value="test"/>
</dataSource>
</transactionManager>
<!-- 这里可以写多个实体的映射文件 -->
<sqlMap resource="userMapper.xml"/>
</sqlMapConfig>

userMapper.xml:配置文件

iBatis是”半自动”的ORM框架,即SQL语句需要开发者自定义,iBatis的关注点在POJO与SQL之间的映射关系。那么SQL语句在哪里配置自定义呢?就在Mapper.xml中配置

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

<typeAlias alias="User" type="com.highgo.ibatis.User"/>

<select id="selectById" resultClass="com.highgo.ibatis.User">
SELECT * FROM test_user WHERE id in($ids$)
</select>
<select id="selectByIds" parameterClass="java.util.List" resultClass="User">
SELECT * FROM test_user WHERE id in <iterate open="(" conjunction="," close=")" >#ids[]#</iterate>
</select>

<select id="selectByArray" parameterClass="java.util.Map" resultClass="User">
SELECT * FROM test_user WHERE id IN<iterate property="ids" open="(" conjunction="," close=")" >
<![CDATA[
#ids[]#
]]>
</iterate>
</select>

<select id="selectAll" parameterClass="java.util.List" resultClass="User">
SELECT * FROM test_user
</select>

</sqlMap>

User.java:实体类文件

public class User {
private int id;
private String name;
private Date birthday;

public int getId() {
return id;
}

public String getName() {
return name;
}

public Date getBirthday() {
return birthday;
}

public void setId(int id) {
this.id = id;
}

public void setName(String name) {
this.name = name;
}

public void setBirthday(Date birthday) {
this.birthday = birthday;
}

@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", birthday=" + birthday
+ "]";
}

}

UserDao.java:DAO接口文件

public interface UserDao {
List<User> getUserById(Integer id);
List<User> selectByArray(Map<String, Object> query);
List<User> getUserByIds(List<Integer> ids);
List<User> test();
}

UserDaoImpl.java:DAO 实现类文件

public class UserDaoImpl implements UserDao {
private static SqlMapClient sqlMapClient = null;
// 读取配置文件
static {
try {
Reader reader = Resources.getResourceAsReader("ibatis-config.xml");
sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}

public User getUser(int id) {
return null;
}

public List<User> getUserById(Integer id) {
List<User> users = null;
try {
users = sqlMapClient.queryForList("selectById", id);
} catch (SQLException e) {
e.printStackTrace();
}
return users;
}

public List<User> selectByArray(Map<String, Object> query) {
List<User> users = null;
try {
users = sqlMapClient.queryForList("selectByArray", query);
} catch (SQLException e) {
e.printStackTrace();
}
return users;
}

public List<User> getUserByIds(List<Integer> ids) {
List<User> users = null;
try {
users = sqlMapClient.queryForList("selectByIds", ids);
} catch (SQLException e) {
e.printStackTrace();
}
return users;
}

public List<User> test(){
List<User> users = null;
try {
//int[] ids = {1};
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
users = sqlMapClient.queryForList("selectAll", ids);
} catch (SQLException e) {
e.printStackTrace();
}
return users;
}
}

test.java:测试类文件

public class Test {
public static void main(String[] args) throws IOException {
UserDao userDao = new UserDaoImpl();
List<User> users=null;
users = userDao.test();
//使用forEach遍历集合
for (User userEntity : users) {
System.out.println(userEntity);
}
}
}

执行结果:

image-20220419154113981

注意事项

DAO 模式

DAO(Data Access Objects 数据存取对象)是指位于业务逻辑和持久化数据之间实现对持久化数据的访问。

DAO 模式提供了访问关系型数据库系统所需操作的接口,将数据访问和业务逻辑分离对上层提供面向对象的数据访问接口,通俗来讲,就是将数据库操作都封装起来,对外提供相应的接口。

从以上 DAO 模式定义可以看出,DAO 模式的优势就在于它实现了两次隔离。

  • 隔离了数据访问代码和业务逻辑代码。业务逻辑代码直接调用DAO方法即可,完全感觉不到数据库表的存在。分工明确,数据访问层代码变化不影响业务逻辑代码,这符合单一职能原则,降低了藕合性,提高了可复用性。
  • 隔离了不同数据库实现。采用面向接口编程,如果底层数据库变化,如由 MySQL 变成 Oracle 只要增加 DAO 接口的新实现类即可,原有 MySQ 实现不用修改。这符合 “开-闭” 原则。该原则降低了代码的藕合性,提高了代码扩展性和系统的可移植性。

一个典型的DAO 模式主要由以下几部分组成。

  • DAO接口: 把对数据库的所有操作定义成抽象方法,可以提供多种实现。
  • DAO 实现类: 针对不同数据库给出DAO接口定义方法的具体实现。
  • 实体类:用于存放与传输对象数据。
  • 数据库连接和关闭工具类: 避免了数据库连接和关闭代码的重复使用,方便修改。