sophia0 2013-07-29
相对于Hibernate提供了全面的数据库封装机制的“全自动化”ORM实现而言,iBATIS则是一种“半自动”的ORM实现。
所谓“全自动化”ORM实现是指实现了POJO(Plain Old Java Object 简单的Java对象)和数据库表之间的映射,以及SQL的自动生成和执行。而IBatis则不会为程序员在运行期间自动生成SQL语句,需要程序员自己编写,然后通过映射配置文件,将SQL所需的参数,以及返回的结果字段映射到指定的POJO中。
iBatis 与 Hibernate 的区别:
Hibernate功能强大,数据库无关性好,O/R映射能力强,如果对Hibernate相当精通,而且对Hibernate进行了适当的封装,那么整个持久层代码会相当简单,需要写的代码很少,开发速度快。Hibernate对数据库结构提供了较为完整的封装,Hibernate的O/R Mapping实现了POJO和数据库表之间的映射,以及SQL的自动生成和执行。程序员只需要定义好POJO到数据表的映射关系,即可通过Hibernate提供的方法完成持久层的操作。程序员甚至不需要对SQL相当熟练的掌握,Hibernate/OJB 会根据制定的存储逻辑,自动生成对应的SQL并调用JDBC接口加以执行。
iBatis入门简单,即学即用,提供了数据库查询的自动绑定功能,而且延续了很好的SQL使用经验,对于没有那么高的对象模型要求的项目来说,相当完美。当系统数据处理量巨大、性能要求极为苛刻时,这往往意味着我们必须经过高度优化的SQL语句(或存储过程)才能达到性能设计的指标。在这种情况下iBatis会有更好的可控性和表现。
总之:Hibernate比iBatis复杂,学习成本高,iBatis简单容易上手,是基于原生SQL的框架。可以说Hibernate功能强大而复杂,iBatis简单而小巧。
iBATIS的下载与配置:
iBATIS的官方下载地址:http://labs.renren.com/apache-mirror/ibatis/binaries/ibatis.java/
MYBATIS的官方下载地址:http://code.google.com/p/mybatis/downloads/list
注:iBATIS 是 3.0以前的版本的名字,3.0(包括3.0)以后的版本叫MyBatis。MyBatis 和 iBatis有很多的区别,包括包的结构和类名。而我们今天所说的iBatis是指3.0以前的版本。
注:所有的持久类属性的类型都不要声明为基本类型(int、long、float、double),应该声明为对应的封装类型(Integer、Long、Float、Double),因为IBatis是面向对象的解决方案。因此所有的属性、参数和结果必须是对象。
ibatis运行过程:
ibatis框架整体运行模式和Hibernate很像,对于每一个需要操作的实体类我们都必须创建一个类似的映射文件一般名为xxx_SqlMap.xml,在我们配置好所有的实体类的映射文件后还需要配置二个文件,一个是装有数据库连接参数的属性文件SqlMapConfig.properties;另一个是sqlMapConfig.xml文件,数据库的配置文件后面会截图给大家,主要是sqlMapConfig.xml这个文件,这个文件是我们使用ibatis操作数据库前必须要加载的,我找了一些资料上说可以使用单例模式将sqlMapClient参数作为static final类型,但是我赋值有错误,所以自己写了一个静态方法获取sqlMapClient实例。
配置文件样例(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>
<properties resource="SqlMapConfig.properties"/>
<settings
enhancementEnabled="true"
useStatementNamespaces="true"
cacheModelsEnabled="true"
lazyLoadingEnabled="true"
/>
<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}"/>
<property name="JDBC.ConnectionURL" value="${url}"/>
<property name="JDBC.Username" value="${username}"/>
<property name="JDBC.Password" value="${password}"/>
<property name="Pool.MaximumActiveConnections" value="10" /> <!-- 数据库连接池可维持的最大容量 -->
<property name="Pool.MaximumIdleConnections" value="5" /> <!-- 数据库连接池可挂起的连接数 -->
<property name="Pool.MaximumCheckoutTime" value="120000" /> <!-- 连接某个任务占用的最大时间(ms) -->
<property name="Pool.TimeToWait" value="500" /> <!-- 线程等待连接的最大时间(ms) -->
<property name="Pool.PingQuery" value="select 1 from users" /> <!-- 数据库连接状态检测语句 -->
<property name="Pool.PingEnabled" value="false" /> <!-- 是否允许检测连接状态 -->
<property name="Pool.PingConnectionsOlderThan" value="1" /> <!-- 对连接时间超过设定值将进行连接检测 -->
<property name="Pool.PingConnectionsNotUsedFor" value="1" /> <!-- 对空闲超过设定值的连接进行检测 -->
</dataSource>
</transactionManager>
<sqlMap resource="com/ego/vo/users_SqlMap.xml" />
</sqlMapConfig>
数据库属性文件配置:
#MySql数据库连接参数配置
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/testibatis
username=root
password=111111
users_SqlMap.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 namespace="users">
<cacheModel id="userCache" type="LRU">
<flushInterval hours="24"/>
<property name="size" value="1000"/>
</cacheModel>
<typeAlias alias="User" type="com.ego.vo.User"/> <!-- 使用别名 -->
<resultMap id="userResult" class="User">
<result property="userId" column="ID" jdbcType="VARCHAR"/>
<result property="username" column="USERNAME" jdbcType="VARCHAR"/>
<result property="password" column="PASSWORD" jdbcType="VARCHAR"/>
<result property="age" column="AGE" jdbcType="VARCHAR"/>
</resultMap>
<select id="getUser" cacheModel="userCache" resultMap="userResult" parameterclass="User">
SELECT * FROM T_USER WHERE ID=#userId:NUMERIC#
</select>
<select id="getUserList" cacheModel="userCache" resultMap="userResult" parameterclass="User">
SELECT * FROM T_USER
</select>
<insert id="insertUser" parameterclass="User">
insert into T_USER(ID,USERNAME,PASSWORD,AGE)
values(#userId:NUMERIC#,#username:VARCHAR#,#password:VARCHAR#,#age:NUMERIC#);
</insert>
<update id="updateUser" parameterclass="User">
update T_USER set USERNAME=#username:VARCHAR#,PASSWORD=#password:VARCHAR#,AGE=#age:NUMERIC#
where ID=#userId:NUMERIC#;
</update>
<delete id="deleteUser" parameterclass="User">
delete from T_USER where id="userId:NUMERIC";
</delete>
</sqlMap>
测试类:
package com.ego.dao;
import java.io.IOException;
import java.io.Reader;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.ego.vo.User;
import com.ibatis.common.resources.Resources;
import com.ibatis.common.util.PaginatedList;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
public class UserDao {
/**
* 获取SqlMapClient实例
* @return
*/
public static SqlMapClient getSqlMapClient(){
SqlMapClient sqlMapClient=null;
String resource = "sqlMapConfig.xml";
//加载配置文件和映射文件
try {
Reader reader = Resources.getResourceAsReader(resource);
sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
} catch (IOException e) {
e.printStackTrace();
}
return sqlMapClient;
}
/**
* 插入对象
* @param sqlMapClient
* @throws Exception
*/
public void insertUser(SqlMapClient sqlMapClient) throws Exception{
sqlMapClient.startTransaction();
User user = new User();
user.setUserId("1007");
user.setAge("25");
user.setUsername("GYL");
user.setPassword("1234");
sqlMapClient.insert("users.insertUser", user);
sqlMapClient.commitTransaction();
}
/**
* 查询单个对象
* @param sqlMapClient
* @return
* @throws Exception
*/
public User queryForObject(SqlMapClient sqlMapClient) throws Exception{
sqlMapClient.startTransaction();
User user=new User();
try {
user.setUserId("1007");
//String userId =new String("1007");
user = (User)sqlMapClient.queryForObject("users.getUser",user);
System.out.println("userDao:"+user.toString());
} catch (SQLException e) {
e.printStackTrace();
}
sqlMapClient.commitTransaction();
return user;
}
/**
* 查询集合
* @param sqlMapClient
* @return
* @throws Exception
*/
public List<User> queryForList(SqlMapClient sqlMapClient) throws Exception{
sqlMapClient.startTransaction();
List<User> users = new ArrayList<User>();
users = (List<User>)sqlMapClient.queryForList("users.getUserList",null,0,3);
sqlMapClient.commitTransaction();
return users;
}
/**
* 分页查询
* @param sqlMapClient
* @return
*/
public PaginatedList queryForPaginatedList(SqlMapClient sqlMapClient){
PaginatedList usersByPage=null;
try {
usersByPage = sqlMapClient.queryForPaginatedList("users.getUserList", null,3);
} catch (SQLException e) {
e.printStackTrace();
}
return usersByPage;
}
/**
* 测试方法
* @param args
*/
public static void main(String[] args) {
UserDao userDao = new UserDao();
SqlMapClient sqlMapClient = UserDao.getSqlMapClient();
// try {
// userDao.insertUser(sqlMapClient);
// System.out.println("成功!!!");
// } catch (Exception e) {
// System.out.println(" 失败!!!");
// e.printStackTrace();
// }
// try {
// User user = userDao.queryForObject(sqlMapClient);
// System.out.println("User:"+user.toString());
// } catch (Exception e) {
// e.printStackTrace();
// }
//List<User> users = new ArrayList<User>();
// try {
// users = userDao.queryForList(sqlMapClient);
// } catch (Exception e) {
// e.printStackTrace();
// }
// System.out.println("Size:"+users.size());
//
// for(User user:users){
// System.out.println("user:"+user.toString());
// }
PaginatedList users=null;
users = userDao.queryForPaginatedList(sqlMapClient);
System.out.println("Size:"+users.size());
users.nextPage();
int n = users.getPageIndex();
System.out.println("n"+n);
for(int i=0;i<users.size();i++){
User user = (User)users.get(i);
System.out.println("user:"+user.toString());
}
}
}
实体类User:
package com.ego.vo;
public class User {
private String userId;//用户ID
private String username;//用户名
private String password;//密码
private String age;//
public User(){
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getUserId() {
return userId;
}
public String getUsername() {
return username;
}
public void setUserId(String userId) {
this.userId = userId;
}
@Override
public String toString() {
return "User [age=" + age + ", password=" + password + ", userid="
+ userId + ", username=" + username + "]";
}
}
数据库字段:
见附图 其中ID和AGE是int类型。
本篇有部分参考其他资料,如有侵权行为,请联系我,我会及时删除,谢谢。
如:对于sql语句order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为order by "id"。