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
示例项目 结构图如下:
主要文件介绍
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); } } }
执行结果:
注意事项 DAO 模式
DAO(Data Access Objects 数据存取对象)是指位于业务逻辑和持久化数据之间实现对持久化数据的访问。
DAO 模式提供了访问关系型数据库系统所需操作的接口,将数据访问和业务逻辑分离对上层提供面向对象的数据访问接口,通俗来讲,就是将数据库操作都封装起来,对外提供相应的接口。
从以上 DAO 模式定义可以看出,DAO 模式的优势就在于它实现了两次隔离。
隔离了数据访问代码和业务逻辑代码。业务逻辑代码直接调用DAO方法即可,完全感觉不到数据库表的存在。分工明确,数据访问层代码变化不影响业务逻辑代码,这符合单一职能原则,降低了藕合性,提高了可复用性。
隔离了不同数据库实现。采用面向接口编程,如果底层数据库变化,如由 MySQL 变成 Oracle 只要增加 DAO 接口的新实现类即可,原有 MySQ 实现不用修改。这符合 “开-闭” 原则。该原则降低了代码的藕合性,提高了代码扩展性和系统的可移植性。
一个典型的DAO 模式主要由以下几部分组成。
DAO接口: 把对数据库的所有操作定义成抽象方法,可以提供多种实现。
DAO 实现类: 针对不同数据库给出DAO接口定义方法的具体实现。
实体类:用于存放与传输对象数据。
数据库连接和关闭工具类: 避免了数据库连接和关闭代码的重复使用,方便修改。