iBATIS&Spring合奏(一)--DAO
iBATIS,大家都用的比喻就是什么半自动步枪之类的,没错。一个框架是做神马的相信靠谱点的程序猿们都会先去Google,然后看看官方文档之类的,再在网上找点代码copy下然后运行看看。随后需要深入研究了,需要性能优化了,再去深入研究和体会,牛者自己写个差不多的框架用起来还爽些。这合奏系列文章就是提供给刚刚接受iBATIS框架,想和Spring放在一起用的猿类们的。也是觉得过几阵子不用它自己也会不记得了,先写下来,以后用到的时候也会方便唤醒沉睡的记忆。
1)iBATIS做ORM,还是很轻便且强大的,某些方面的性能方面比Hibernate好些啦。下面简单建两个数据库。如下图:

当然,这里先不用外键,今天是第一步。等会会有两表连接的查询,存储过程下次介绍。然后就是POJO也就是domain模型,这里就不列举代码了。Order表中的user会联合User表的username做链接查询。先以user的操作为例。
2)iBATIS的核心配置文件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="sqlmap.properties"/> <transactionManager type="JDBC"> <dataSource type="SIMPLE"> <property name="JDBC.Driver"value="${jdbc.driverClassName}" /><property name="JDBC.ConnectionURL" value="${jdbc.url}" /><property name="JDBC.Username" value="${jdbc.username}" /><property name="JDBC.Password" value="${jdbc.password}" /> </dataSource> </transactionManager> <sqlMap resource="com/qiyun/spritis/persistence/sqlmapdao/sql/User.xml"/> <sqlMap resource="com/qiyun/spritis/persistence/sqlmapdao/sql/Order.xml"/> <sqlMap resource="com/qiyun/spritis/persistence/sqlmapdao/sql/Dynamic.xml"/></sqlMapConfig>这里配置了数据源,属性值通过读取Properties文件获得。这里就不列举该文件了。涉及到了三个sqlMap标签中指明的资源配置文件。
3)sqlMap配置文件。先看看User.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="User"> <typeAlias alias="user" type="com.qiyun.spritis.pojo.User"/><select id="getAllUsers" resultresultcolumn="ID" /><result property="username" column="USERNAME" /><result property="password" column="PASSWORD" /><result property="company" column="COMPANY" /></resultMap><select id="getUsersByCompanyName2" resultMap="mapResult" parameterparameterresultjdbcType="VARCHAR"/><parameter property="password" jdbcType="VARCHAR"/><parameter property="company" jdbcType="VARCHAR"/></parameterMap><insert id="insertUser" parameterMap="parameterMapEx">INSERT INTO user ( username, password, company)VALUES(?,?,? )</insert><update id="updateUser" parameterparameterid="account-cache"><flushInterval hours="1"/><flushOnExecute statement="insertOneUser2"/><property name="size" value="1000"/></cacheModel></sqlMap>
一看就知道了很多的sql语句。参数类型,返回值类型都在CRUD相关标签中配置了。相信熟悉Hibernate的同学看这个应该很容易理解的。##中间夹着的不就是可爱的参数啦,参数,当然我们在后面看是如何传进来的。下面开始把Spring搞进来啦。
4)Spring在此不介绍了,这里只简单用了Ioc,陆续会加上事务管理的融合再加上Aop的东东。当然也用到了Spring的中间层数据访问的DAO支持。先看beans.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"><beanref="mysqlMapClient"></property></bean><bean id="dataSource" destroy-method="close"/><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /></bean><bean id="mysqlMapClient"value="SqlMapConfig.xml" /><property name="dataSource" ref="dataSource"></property></bean><bean id="transactionManager" lazy-init="default" autowire="default"dependency-check="default"><property name="dataSource"><ref bean="dataSource" /></property> </bean> </beans>5)DAO 接口的示例如下。只简单列举到User表的操作DAO。
package com.qiyun.spritis.persistence.sqlmapdao.interfaces;import java.util.List;import org.springframework.dao.DataAccessException;import com.qiyun.spritis.pojo.User;public interface UserDao { List<User> getAllUsers()throws DataAccessException;List<User> getUserByCompanyName(String compName) throws DataAccessException;void insertUser(User user) throws DataAccessException;void updateUser(User user) throws DataAccessException;void deleteUserById (int id) throws DataAccessException;}6)DAO的实现类。这里用到了Spring的Templete方法,和HibernateTemplete差不多。如下先睹为快:
package com.qiyun.spritis.persistence.sqlmapdao.impl;import java.util.List;import org.springframework.dao.DataAccessException;import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;import com.qiyun.spritis.persistence.sqlmapdao.interfaces.UserDao;import com.qiyun.spritis.pojo.User;public class UserSqlMapDao extends SqlMapClientDaoSupport implements UserDao {@Overridepublic void deleteUserById(int id) throws DataAccessException {getSqlMapClientTemplate().delete("deleteUser", id);}@SuppressWarnings("unchecked")@Overridepublic List<User> getAllUsers() throws DataAccessException {return (List<User>)getSqlMapClientTemplate().queryForList("getAllUsers");}@SuppressWarnings("unchecked")@Overridepublic List<User> getUserByCompanyName(String compName)throws DataAccessException {return (List<User>)getSqlMapClientTemplate().queryForList("getUsersByCompanyName2",compName);}@Overridepublic void insertUser(User user) throws DataAccessException {getSqlMapClientTemplate().update("insertUser",user);}@Overridepublic void updateUser(User user) throws DataAccessException {getSqlMapClientTemplate().update("updateUser",user);}} 到这里就差不多懂了吧,就是把User。xml配置文件中的id和所要传入的参数给getSqlMapClientTemplate方法去调用iBATIS来处理。Spring只是对iBATIS获取sqlMapClient这个核心类进行了轻量的封装。当然为了把AOP加进来,少不了Service层啦。
7)Service层,用Spring容器来管理的Dao们要呼之欲出了。以后要加什么逻辑的话还可以进一步封装。UserService类如下:
package com.qiyun.spritis.service;import java.util.List;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.qiyun.spritis.persistence.sqlmapdao.impl.UserSqlMapDao;import com.qiyun.spritis.persistence.sqlmapdao.interfaces.UserDao;import com.qiyun.spritis.pojo.User;public class UserService {public List<User> getAllUsers() throws Exception {ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");UserDao service = (UserSqlMapDao)ctx.getBean("userDao");List<User> list=(List<User>)service.getAllUsers();ctx.destroy();return list;}public List<User> getUserByCompanyName(String company)throws Exception {ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");UserDao service = (UserSqlMapDao)ctx.getBean("userDao");List<User> list=(List<User>)service.getUserByCompanyName(company);ctx.destroy();return list;}public void insertUser(User user) throws Exception{ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");UserDao service = (UserSqlMapDao)ctx.getBean("userDao");System.out.println(service.getClass());service.insertUser(user);ctx.destroy();}public void deleteUser(int id)throws Exception{ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");UserDao service = (UserSqlMapDao)ctx.getBean("userDao");service.deleteUserById(id);ctx.destroy();}public void updateUser(User user)throws Exception{ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");UserDao service = (UserSqlMapDao)ctx.getBean("userDao");service.updateUser(user);ctx.destroy();}}8)以上就不错做解释,下面开始测试啦。用JUnit来测一下吧,比较方便,用单元测试的好处,相信猿类们早有体会。UserServiceTest如下:
package com.qiyun.spritis.test;import java.util.List;import org.junit.Test;import com.qiyun.spritis.pojo.User;import com.qiyun.spritis.service.UserService;public class UserServiceTest {@Testpublic void testGetAllUsers() throws Exception {UserService us=new UserService();List<User> li=us.getUserByCompanyName("TB");for(int i=0;i<li.size();i++){System.out.println(li.get(i).getId()+"||"+li.get(i).getUsername()+"||"+li.get(i).getPassword()+"||"+li.get(i).getCompany());}}@Testpublic void testInsertUser()throws Exception{UserService us=new UserService();us.insertUser(new User("LK","lk","TB"));List<User> li=us.getAllUsers();System.out.println("最新添加的员工:"+li.get(li.size()-1).getUsername());}@Testpublic void testDeleteUser()throws Exception{UserService us=new UserService();us.deleteUser(8);}@Testpublic void testUpdateUser()throws Exception{User u=new User();u.setId(new Integer(8));u.setUsername("LK");u.setPassword("lk");u.setCompany("IBM");UserService us=new UserService();us.updateUser(u);}}到此。一个Spring和iBATIS的前奏总算演奏完了。当然很简单的一个示例。后面会陆续加上连接查询,动态SQL,以及一些Handler的介绍。等用熟了之后再深入其架构,一个好用的框架当然少不了好的设计模式。先到这里。源码奉上。如果运行中报错,希望同学们先Google一下,可能是缺jar包哦。项目压缩包:spritis(Spring+iBATIS) 1 楼 TTNecro 2010-12-05 膜拜....