一个iBatis的demo

本文介绍了一种半自动ORM解决方案iBatis的使用方法,包括环境搭建、表结构创建、配置文件编写及Java代码实现。并通过具体示例展示了如何进行增删改查等基本操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

相对Hibernate和Apache OJB 等“一站式”ORM解决方案而言,ibatis 是一种“半 
自动化”的ORM实现。 
所谓“半自动”,可能理解上有点生涩。纵观目前主流的ORM,无论Hibernate 还是 
Apache OJB,都对数据库结构提供了较为完整的封装,提供了从POJO 到数据库表的全 
套映射机制。程序员往往只需定义好了POJO 到数据库表的映射关系,即可通过Hibernate 
或者OJB 提供的方法完成持久层操作。程序员甚至不需要对SQL 的熟练掌握, 
Hibernate/OJB 会根据制定的存储逻辑,自动生成对应的SQL 并调用JDBC 接口加以执 
行。 ----摘自官方资料的一段话 

iBatis是一种很好的解决方案,使用起来很灵活,参考一些网络中的资料我也想把自己的使用过程写下来,如有错误希望指正。 

环境:JDK1.5+Eclipse3.2  使用时仅需要在Eclipse中导入项目。 

首先是表结构, 提供了两种数据库的支持分别为MySQL与hsqldb,可以根据实际情况选择使用。以MySQL为例: 
Java代码   收藏代码
  1. create database if not exists `ibatis_schema`;  
  2.   
  3. USE `ibatis_schema`;  
  4.   
  5. drop table if exists `t_user`;  
  6.   
  7. CREATE TABLE `t_user` (  
  8.   `id` int(12) NOT NULL auto_increment,  
  9.   `name` varchar(50default NULL,  
  10.   `date` date default NULL,  
  11.   PRIMARY KEY  (`id`)  
  12. ) ENGINE=InnoDB DEFAULT CHARSET=GBK;  
  13.   
  14. Insertinto  `t_user`(name,date) values('liulu','2007-03-15'),('liulu2','2007-03-15'),('liulu3','2007-03-15');  

然后是iBatis的配置文件 SqlMapConfig.xml 
这里进行数据源的配置以及一些参数的设置和优化 
Java代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2.   
  3. <!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"  
  4.     "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">  
  5.   
  6. <sqlMapConfig>  
  7.   
  8.     <settings cacheModelsEnabled="true" useStatementNamespaces="true" />  
  9.     <transactionManager type="JDBC">  
  10.         <dataSource type="SIMPLE">  
  11.             <property name="JDBC.Driver" value="com.mysql.jdbc.Driver" />  
  12.             <property name="JDBC.ConnectionURL" value="jdbc:mysql://localhost/ibatis_schema" />  
  13.             <property name="JDBC.Username" value="root" />  
  14.             <property name="JDBC.Password" value="1234" />  
  15.         </dataSource>  
  16.     </transactionManager>  
  17.       
  18.     <sqlMap resource="com/javaeye/liulu/maps/User.xml" />  
  19. </sqlMapConfig>  

User.java就是domain了,是映射的对象。 
Java代码   收藏代码
  1. package com.javaeye.liulu.domain;  
  2.   
  3. import java.io.Serializable;  
  4. import java.util.Date;  
  5.   
  6. public class User implements Serializable{  
  7.     private int id;  
  8.     private String name;  
  9.     private Date date;  
  10.     public Date getDate() {  
  11.         return date;  
  12.     }  
  13.     public void setDate(Date date) {  
  14.         this.date = date;  
  15.     }  
  16.     public int getId() {  
  17.         return id;  
  18.     }  
  19.     public void setId(int id) {  
  20.         this.id = id;  
  21.     }  
  22.     public String getName() {  
  23.         return name;  
  24.     }  
  25.     public void setName(String name) {  
  26.         this.name = name;  
  27.     }  
  28. }  

下面是比较重要的SQL Map XML映射文件,所有方法都在这里。 
User.xml 
Java代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"  
  3. "http://www.ibatis.com/dtd/sql-map-2.dtd">  
  4.   
  5. <sqlMap namespace="User">  
  6.     <typeAlias alias="UserObject" type="com.javaeye.liulu.domain.User" />  
  7.     <resultMap id="userResult" class="UserObject">  
  8.         <result property="id" column="id" jdbcType="NUMBER" />  
  9.         <result property="name" column="name" jdbcType="VARCHAR2" />  
  10.         <result property="date" column="date" jdbcType="DATE" />  
  11.     </resultMap>  
  12.   
  13.     <select id="getByPK" resultMap="userResult" parameterClass="UserObject">  
  14.         <![CDATA[   
  15.         select  
  16.           id,  
  17.           name,   
  18.           date   
  19.         from t_user   
  20.         where id = #id#   
  21.         ]]>  
  22.     </select>  
  23.       
  24.     <select id="getById" resultMap="userResult" parameterClass="java.lang.String">  
  25.         <![CDATA[   
  26.         select  
  27.           id,  
  28.           name,   
  29.           date   
  30.         from t_user   
  31.         where id = $String$  
  32.         ]]>  
  33.     </select>  
  34.   
  35.     <sql id="Dy_SC">  
  36.         <dynamic prepend="WHERE">  
  37.             <isNotNull prepend="AND" property="id">id like #id#</isNotNull>  
  38.             <isNotNull prepend="AND" property="name">name like #name#</isNotNull>  
  39.         </dynamic>  
  40.     </sql>  
  41.   
  42.     <select id="getUser" resultMap="userResult">  
  43.         <![CDATA[   
  44.         select  
  45.           id,  
  46.           name,   
  47.           date   
  48.         from t_user   
  49.         ]]>  
  50.         <include refid="Dy_SC" />  
  51.     </select>  
  52.   
  53.     <insert id="insertUser" parameterClass="UserObject">  
  54.         INSERT INTO t_user (name,date) VALUES (#name#,#date#)  
  55.     </insert>  
  56.       
  57.     <insert id="insertUserTest" parameterClass="UserObject">  
  58.         INSERT INTO t_user (id,name,date) VALUES (#id#,#name#,#date#)  
  59.     </insert>  
  60.   
  61.     <update id="updateUser" parameterClass="UserObject">  
  62.         <![CDATA[   
  63.         UPDATE t_user   
  64.         SET    
  65.           name=#name#,   
  66.           date=#date#   
  67.         WHERE id = #id#  
  68.         ]]>  
  69.     </update>  
  70.   
  71.     <delete id="deleteUser" parameterClass="java.lang.String">  
  72.         delete from t_user where id=#value#  
  73.     </delete>  
  74.   
  75.     <statement id="getMaxId" resultClass="java.lang.Integer">  
  76.         select Max(id) from t_user  
  77.     </statement>  
  78.   
  79.     <statement id="getMax" resultClass="java.util.HashMap">  
  80.         select Max(id) as id,Max(name) as name,Max(date) as date from t_user  
  81.     </statement>  
  82.   
  83. </sqlMap>  

这样就可以来测试了,测试也使用了两种方法,先使用一个普通应用程序来测试一下程序的运行好了。 
Java代码   收藏代码
  1. package com.javaeye.liulu;  
  2.   
  3. import java.io.Reader;  
  4. import java.sql.Connection;  
  5. import java.sql.DriverManager;  
  6. import java.sql.SQLException;  
  7. import java.util.Date;  
  8. import java.util.HashMap;  
  9. import java.util.List;  
  10. import java.util.Map;  
  11. import java.util.Properties;  
  12.   
  13. import com.ibatis.common.jdbc.ScriptRunner;  
  14. import com.ibatis.common.resources.Resources;  
  15. import com.ibatis.sqlmap.client.SqlMapClient;  
  16. import com.ibatis.sqlmap.client.SqlMapClientBuilder;  
  17. import com.javaeye.liulu.domain.User;  
  18.   
  19. public class Main {  
  20.   
  21.     //hsql初始化,对MySQL没有影响  
  22.     static {  
  23.         try {  
  24.             Properties props = Resources.getResourceAsProperties("properties/database.properties");  
  25.             String url = props.getProperty("url");  
  26.             String driver = props.getProperty("driver");  
  27.             String username = props.getProperty("username");  
  28.             String password = props.getProperty("password");  
  29.             if (url.equals("jdbc:hsqldb:mem:ibatisDemo")) {  
  30.                 Class.forName(driver).newInstance();  
  31.                 Connection conn = DriverManager.getConnection(url, username, password);  
  32.                 try {  
  33.                     ScriptRunner runner = new ScriptRunner(conn, falsefalse);  
  34.                     runner.setErrorLogWriter(null);  
  35.                     runner.setLogWriter(null);  
  36.                     runner.runScript(Resources.getResourceAsReader("ddl/hsql/ibatisdemo-hsqldb-schema.sql"));  
  37.                     runner.runScript(Resources.getResourceAsReader("ddl/hsql/ibatisdemo-hsqldb-dataload.sql"));  
  38.                 } finally {  
  39.                     conn.close();  
  40.                 }  
  41.             }  
  42.         } catch (Exception e) {  
  43.             throw new RuntimeException("Description.  Cause: " + e, e);  
  44.         }  
  45.     }  
  46.   
  47.     /** 
  48.      * 初始化iBatis获得一个SqlMapClient对象 
  49.      *  
  50.      * @param 
  51.      * @return SqlMapClient 
  52.      */  
  53.     public static SqlMapClient getSqlMapClient() {  
  54.         String resource = "com/javaeye/liulu/maps/SqlMapConfig.xml";  
  55.         SqlMapClient sqlMap = null;  
  56.         try {  
  57.             Reader reader = Resources.getResourceAsReader(resource);  
  58.             sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);  
  59.         } catch (Exception e) {  
  60.             e.printStackTrace();  
  61.         }  
  62.         return sqlMap;  
  63.     }  
  64.   
  65.     /** 
  66.      * 插入一条记录 
  67.      *  
  68.      * @param 
  69.      * @return 
  70.      */  
  71.     public static void insert() {  
  72.         SqlMapClient sqlMap = getSqlMapClient();  
  73.         try {  
  74.             sqlMap.startTransaction();  
  75.             User user = new User();  
  76.             user.setName("insert1");  
  77.             user.setDate(new Date());  
  78.             sqlMap.insert("User.insertUser", user);  
  79.             sqlMap.commitTransaction();  
  80.         } catch (SQLException e) {  
  81.             e.printStackTrace();  
  82.         }  
  83.     }  
  84.   
  85.     /** 
  86.      * 将第一条记录的信息更新 
  87.      *  
  88.      * @param 
  89.      * @return 
  90.      */  
  91.     public static void update() {  
  92.         SqlMapClient sqlMap = getSqlMapClient();  
  93.         try {  
  94.             sqlMap.startTransaction();  
  95.             User user = (User)sqlMap.queryForObject("User.getById""1");  
  96.             user.setName("update1");  
  97.             sqlMap.update("User.updateUser", user);  
  98.             sqlMap.commitTransaction();  
  99.         } catch (SQLException e) {  
  100.             e.printStackTrace();  
  101.         } finally {  
  102.             try {  
  103.                 sqlMap.endTransaction();  
  104.             } catch (SQLException e) {  
  105.                 e.printStackTrace();  
  106.             }  
  107.         }  
  108.     }  
  109.   
  110.     /** 
  111.      * 删除id最大的记录 
  112.      *  
  113.      * @param 
  114.      * @return 
  115.      */  
  116.     public static void delete() {  
  117.         SqlMapClient sqlMap = getSqlMapClient();  
  118.         try {  
  119.             sqlMap.startTransaction();  
  120.             String maxId = sqlMap.queryForObject("User.getMaxId"null).toString();  
  121.             sqlMap.delete("User.deleteUser", maxId);  
  122.             sqlMap.commitTransaction();  
  123.         } catch (SQLException e) {  
  124.             e.printStackTrace();  
  125.         }  
  126.     }  
  127.   
  128.     /** 
  129.      * 根据name查询User为Map的List 
  130.      *  
  131.      * @param 
  132.      * @return List 
  133.      */  
  134.     public static List getUser() {  
  135.         SqlMapClient sqlMap = getSqlMapClient();  
  136.         List<User> user = null;  
  137.         try {  
  138.             sqlMap.startTransaction();  
  139.             HashMap params = new HashMap();  
  140.             params.put("name""%liulu%");  
  141.             user = sqlMap.queryForList("User.getUser", params);  
  142.             sqlMap.commitTransaction();  
  143.         } catch (SQLException e) {  
  144.             e.printStackTrace();  
  145.         } finally {  
  146.             try {  
  147.                 sqlMap.endTransaction();  
  148.             } catch (SQLException e) {  
  149.                 e.printStackTrace();  
  150.             }  
  151.         }  
  152.         return user;  
  153.     }  
  154.   
  155.     /** 
  156.      * 查询各个字段的最大值(一般用于统计,此处演示使用方法) 
  157.      *  
  158.      * @param 
  159.      * @return 
  160.      */  
  161.     public static void getMax() {  
  162.         SqlMapClient sqlMap = getSqlMapClient();  
  163.         try {  
  164.             sqlMap.startTransaction();  
  165.             Map search = (HashMap) sqlMap.queryForObject("User.getMax"null);  
  166.             System.out.println(search.get("id").toString() + "\n"  
  167.                     + search.get("name").toString() + "\n"  
  168.                     + search.get("date").toString());  
  169.             sqlMap.commitTransaction();  
  170.         } catch (SQLException e) {  
  171.             e.printStackTrace();  
  172.         }  
  173.     }  
  174.   
  175.     /** 
  176.      * 通过主键查找,返回user 
  177.      *  
  178.      * @param 
  179.      * @return 
  180.      */  
  181.     public static void getByPK() {  
  182.         SqlMapClient sqlMap = getSqlMapClient();  
  183.         User user = new User();  
  184.         try {  
  185.             sqlMap.startTransaction();  
  186.             user.setId(1);  
  187.             user = (User) sqlMap.queryForObject("User.getByPK", user);  
  188.             System.out.println(user.getId() + "\n" + user.getName() + "\n"  
  189.                     + user.getDate());  
  190.             sqlMap.commitTransaction();  
  191.         } catch (SQLException e) {  
  192.             e.printStackTrace();  
  193.         }  
  194.     }  
  195.   
  196.     public static void main(String[] args) {  
  197.         //insert();  
  198.         //update();  
  199.         //delete();  
  200.   
  201.         List<User> user = getUser();  
  202.         for (User o : user) {  
  203.             System.out.println("id:" + o.getId() + "\nname:" + o.getName()  
  204.                     + "\nDate:" + o.getDate() + "\n------------");  
  205.         }  
  206.         //getMax();  
  207.         //getByPK();  
  208.     }  
  209. }  

所有的方法都是静态的,可以分别对映射方法进行测试。 

下面使用的是单元测试对iBatis来测试,使用了dbunit这个开源项目。 
首先,要为单元测试准备数据。使用DbUnit,我们可以用XML文件来准备测试数据集。 
t_user对应表名 
id,name,date分别对应列名 

user_seed.xml 
Java代码   收藏代码
  1. <?xml version="1.0" encoding="GBK"?>  
  2. <dataset>  
  3.     <t_user id="1"  
  4.         name="liulu"  
  5.         date="2007-01-01"/>  
  6.       
  7.     <t_user id="2"  
  8.         name="liulu2"  
  9.         date="2007-03-15"/>  
  10.           
  11.     <t_user id="3"  
  12.         name="liulu3"  
  13.         date="2007-03-18"/>  
  14. </dataset>  

方便测试,首先为SqlMap的单元测试编写一个抽象的测试基类 
Java代码   收藏代码
  1. package com.javaeye.liulu.test;  
  2.   
  3. import java.io.Reader;  
  4. import java.sql.Connection;  
  5. import java.sql.DriverManager;  
  6. import java.util.Properties;  
  7.   
  8. import javax.sql.DataSource;  
  9.   
  10. import org.dbunit.DatabaseTestCase;  
  11. import org.dbunit.database.DatabaseConnection;  
  12. import org.dbunit.database.IDatabaseConnection;  
  13.   
  14. import com.ibatis.common.resources.Resources;  
  15. import com.ibatis.db.util.ScriptRunner;  
  16. import com.ibatis.sqlmap.client.SqlMapClient;  
  17. import com.ibatis.sqlmap.client.SqlMapClientBuilder;  
  18.   
  19. public abstract class BaseSqlMapTest extends DatabaseTestCase {  
  20.     protected static SqlMapClient sqlMap;  
  21.   
  22.     protected IDatabaseConnection getConnection() throws Exception {  
  23.         return new DatabaseConnection(getJdbcConnection());  
  24.     }  
  25.     protected void setUp() throws Exception {  
  26.         super.setUp();  
  27.         init();  
  28.     }  
  29.     protected void tearDown() throws Exception {  
  30.         super.tearDown();  
  31.         getConnection().close();  
  32.         if (sqlMap != null) {  
  33.             DataSource ds = sqlMap.getDataSource();  
  34.             Connection conn = ds.getConnection();  
  35.             conn.close();  
  36.         }  
  37.     }  
  38.     protected void init() throws Exception {  
  39.         initSqlMap("com/javaeye/liulu/maps/SqlMapConfig.xml"null);  
  40.     }  
  41.     protected SqlMapClient getSqlMapClient() {  
  42.         return sqlMap;  
  43.     }  
  44.     protected void initSqlMap(String configFile, Properties props)  
  45.             throws Exception {  
  46.         Reader reader = Resources.getResourceAsReader(configFile);  
  47.         sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader, props);  
  48.         reader.close();  
  49.     }  
  50.     protected void initScript(String script) throws Exception {  
  51.         DataSource ds = sqlMap.getDataSource();  
  52.         Connection conn = ds.getConnection();  
  53.           
  54.         Reader reader = Resources.getResourceAsReader(script);  
  55.         ScriptRunner runner = new ScriptRunner();  
  56.         runner.setStopOnError(false);  
  57.         runner.setLogWriter(null);  
  58.         runner.setErrorLogWriter(null);  
  59.   
  60.         runner.runScript(conn, reader);  
  61.         conn.commit();  
  62.         conn.close();  
  63.         reader.close();  
  64.     }  
  65.     private Connection getJdbcConnection() throws Exception {  
  66.         /* 
  67.         Properties props = new Properties(); 
  68.         props.load(Resources.getResourceAsStream("properties/database.properties")); 
  69.         Class driver = Class.forName(props.getProperty("driver")); 
  70.         Connection conn = DriverManager.getConnection(props.getProperty("url"),  
  71.                 props.getProperty("username"), props.getProperty("password")); 
  72.                 */  
  73.         Class driver = Class.forName("com.mysql.jdbc.Driver");  
  74.         Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/ibatis_schema","root","1234");  
  75.         return conn;  
  76.     }  
  77. }  

然后为每个SqlMap映射文件编写一个测试用例,extends上面的抽象类 
Java代码   收藏代码
  1. package com.javaeye.liulu.test;  
  2.   
  3. import java.io.Reader;  
  4. import java.util.Date;  
  5. import java.util.HashMap;  
  6. import java.util.List;  
  7.   
  8. import org.dbunit.dataset.IDataSet;  
  9. import org.dbunit.dataset.xml.FlatXmlDataSet;  
  10. import org.dbunit.operation.DatabaseOperation;  
  11.   
  12. import com.ibatis.common.resources.Resources;  
  13. import com.javaeye.liulu.domain.User;  
  14.   
  15. public class UserTest extends BaseSqlMapTest {  
  16.   
  17.     protected IDataSet getDataSet() throws Exception {  
  18.         Reader reader = Resources.getResourceAsReader("com/javaeye/liulu/test/user_seed.xml");  
  19.         return new FlatXmlDataSet(reader);  
  20.     }  
  21.       
  22.     public void testGetByPK() throws Exception {  
  23.         User user = new User();  
  24.         user.setId(1);  
  25.         user = (User) sqlMap.queryForObject("User.getByPK", user);  
  26.         assertNotNull(user);  
  27.         assertEquals(user.getId(), 1);  
  28.         assertEquals(user.getName(), "liulu");  
  29.         assertEquals(user.getDate().getDay(), 1);  
  30.     }  
  31.       
  32.     public void testGetUser() throws Exception {  
  33.         List users = null;  
  34.         HashMap params = new HashMap();  
  35.         params.put("name""%liulu%");  
  36.         users = (List) sqlMap.queryForList("User.getUser", params);  
  37.         assertEquals(users.size(),3);  
  38.     }  
  39.       
  40.     public void testInsertUser() throws Exception {  
  41.         User user = new User();  
  42.         user.setId(4);  
  43.         user.setName("insert1");  
  44.         user.setDate(new Date());  
  45.         sqlMap.insert("User.insertUserTest", user);  
  46.           
  47.         User user2 = new User();  
  48.         user2.setId(4);  
  49.         user2 = (User) sqlMap.queryForObject("User.getById""4");  
  50.         assertEquals(user.getId(),user2.getId());  
  51.         assertEquals(user.getName(),user2.getName());  
  52.           
  53.     }  
  54.       
  55.     public void testUpdateUser() throws Exception {  
  56.         User user = (User)sqlMap.queryForObject("User.getById""1");  
  57.         user.setName("liulu7");  
  58.         sqlMap.update("User.updateUser", user);  
  59.         User user2 = (User)sqlMap.queryForObject("User.getById""1");  
  60.         assertEquals(user2.getName(),"liulu7");  
  61.     }  
  62.       
  63.     public void testDeleteUser() throws Exception {  
  64.         int num = sqlMap.delete("User.deleteUser""1");  
  65.         assertEquals(num,1);  
  66.     }  
  67.       
  68.     public void testGetMaxId() throws Exception {  
  69.         int i =  (Integer)sqlMap.queryForObject("User.getMaxId"null);  
  70.         assertEquals(3,i);  
  71.     }  
  72.       
  73. }  

注意,其中测试insert时由于id为auto_increment,可能需要对测试数据中<dataset/>进行设置,网络中并未查询到相关的方法,所以在映射文件中加入了一个 
Java代码   收藏代码
  1. <insert id="insertUserTest" parameterClass="UserObject">  
  2.         INSERT INTO t_user (id,name,date) VALUES (#id#,#name#,#date#)  
  3.     </insert>  

用例测试中测试的是insertUserTest,并非insertUser,请注意。 

到这里就结束了,demo比较简单,希望能给大家带来帮助。 

参考: 
http://ibatis.apache.org/ 
http://hsqldb.org/ 
http://www.dbunit.org/ 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值