iBatis2学习笔记:基本原理和配置

本文介绍iBatis2的基本原理、配置方法及一个完整的实战案例。iBatis2是一个轻量级的ORM框架,能显著减少JDBC代码量,适用于需要高性能和灵活SQL的应用场景。

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

iBatis2学习笔记:基本原理和配置
 
iBatis2是一个轻量级的数据持久化框架,它是一个半自动化的ORMapping工具,数据库的操作依赖程序员自己书写的SQL,因此可以最大限度发挥JDBC的性能。据测试,它的性能和JDBC是一个级别的,但代码比JDBC简单的多,据说相对JDBC节省了60%的代码量。
 
缺点是映射不灵活,有时候感觉很别扭。当领域对象关系复杂的时候,关联基本上行不通。
 
iBatis2整个框架的jar包就一个,337KB,相比Hibernate等其他框架非常的小巧可爱,并且有.net语言版本。
 
iBatis2的优缺点不是关心的重点,主要是在实际中扬长避短。下面是iBatis2的框架图:
 
 
 
和Hibernate的SessionFactory类似,iBatis2有SqlMapClientBuilder一个类,通过配置文件SqlMapConfig.xml类构建,这个是线程安全的类,并且是单例模式,从它里面可以获取SqlMapClient,SqlMapClient相当于Hibernate的session,用来执行预定义的SQL语句。
 
因此SqlMapClientBuilder、SqlMapConfig.xml、SqlMapClient将是学习iBatis2的核心。以后会逐渐展开,下面是从变成角度来构建SqlMapClientBuilder。
  String resource ="SqlMapConfig.xml";
  Reader reader = Resources.getResourceAsReader(resource);
  SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
 
由于SqlMapClientBuilder的构建是相当耗时的,因此一般都是在程序启动的时候构建一次,并反复使用。
SqlMapClient 是线程不安全的,每次用的时候,需要从SqlMapClientBuilder去申请一个。它相当于一个数据库连接。
 
下面给出一个我学习的例子,也是iBatis中自带的一个例子,但是这个例子无法正常运行,主要是数据库、驱动还有模糊的配置概念导致。下面详细讲述如何规范的把这个例子跑起来:
 
环境:
MySQL5、Java5、iBatis2.3
 
二、安装MySQL5,下载MySQL5,解压缩到某一目录下,然后修改my-small.ini文件如下:
 
    然后安装并启动MySQL5服务

    安装MySQL的客户端工具,SQLyog Enterprise 6.5
 
三、在Idea8中创建一个Java工程ibatis_stu
引入两个必须的包,如下图:
 
数据库链接配置文件 jdbc.properties:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql: //localhost:3306/ibatisdb
jdbc.username=root
jdbc.password=leizhimin
 
 
构件要操作表:
create table ACCOUNT(
    ACC_ID bigint not null AUTO_INCREMENT,
    ACC_FIRST_NAME varchar(20) default NULL,
    ACC_LAST_NAME varchar(30) default NULL,
    ACC_EMAIL varchar(30) default NULL,
     PRIMARY KEY(ACC_ID)
        ) ENGINE=MyISAM DEFAULT CHARSET=gbk COMMENT= 'IBATIS简单测试'
 
iBaits的配置文件SqlMapConfig.xml,(为了使用一些高级特性,增加了命名空间等配置,同时导入了jdbc.properties来协助配置)
<? 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 ="jdbc.properties" />
     < settings
             cacheModelsEnabled ="true"
             errorTracingEnabled ="true"
             enhancementEnabled ="true"
             lazyLoadingEnabled ="true"
             maxRequests ="32"
             maxSessions ="10"
             maxTransactions ="5"
             useStatementNamespaces ="true" />    
    <!-- Configure a built-in transaction manager.  If you're using an
app server, you probably want to use its transaction manager
and a managed datasource
-->
     < transactionManager type ="JDBC" commitRequired ="false" >
         < dataSource type ="SIMPLE" >
             < property name ="JDBC.Driver" value ="${jdbc.driver}" />
             < property name ="JDBC.ConnectionURL" value ="${jdbc.url}" />
             < property name ="JDBC.Username" value ="${jdbc.username}" />
             < property name ="JDBC.Password" value ="${jdbc.password}" />
         </ dataSource >
     </ transactionManager >

    <!-- List the SQL Map XML files. They can be loaded from the
classpath, as they are here (com.domain.data...)
-->
     < sqlMap resource ="com/lavasoft/ibatissut/simple/domain/entity/Account.xml" />
    <!-- List more here...-->
</ sqlMapConfig >
 
嵌入的Account的表与实体映射代码:
<? 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 ="Account" >

    <!-- Use type aliases to avoid typing the full classname every time. -->
     < typeAlias alias ="Account" type ="com.lavasoft.ibatissut.simple.domain.entity.Account" />

  <!-- Result maps describe the mapping between the columns returned
       from a query, and the class properties.  A result map isn't
       necessary if the columns (or aliases) match to the properties
       exactly.
-->
   < resultMap id ="AccountResult" class ="Account" >
     < result property ="id" column ="ACC_ID" />
     < result property ="firstName" column ="ACC_FIRST_NAME" />
     < result property ="lastName" column ="ACC_LAST_NAME" />
     < result property ="emailAddress" column ="ACC_EMAIL" />
   </ resultMap >

  <!-- Select with no parameters using the result map for Account class. -->
   < select id ="selectAllAccounts" resultMap ="AccountResult" >
    select * from ACCOUNT
   </ select >

  <!-- A simpler select example without the result map.  Note the
       aliases to match the properties of the target result class.
-->
   < select id ="selectAccountById" parameterClass ="int" resultClass ="Account" >
    select
      ACC_ID as id,
      ACC_FIRST_NAME as firstName,
      ACC_LAST_NAME as lastName,
      ACC_EMAIL as emailAddress
    from ACCOUNT
    where ACC_ID = #id#
   </ select >

  <!-- Insert example, using the Account parameter class -->
   < insert id ="insertAccount" parameterClass ="Account" >
    insert into account(ACC_ID,ACC_FIRST_NAME,ACC_LAST_NAME,ACC_EMAIL) values(NULL, #firstName#, #lastName#, #emailAddress#)
   </ insert >

  <!-- Update example, using the Account parameter class -->
   < update id ="updateAccount" parameterClass ="Account" >
    update ACCOUNT set
      ACC_FIRST_NAME = #firstName#,
      ACC_LAST_NAME = #lastName#,
      ACC_EMAIL = #emailAddress#
    where
      ACC_ID = #id#
   </ update >

  <!-- Delete example, using an integer as the parameter class -->
   < delete id ="deleteAccountById" parameterClass ="int" >
    delete from ACCOUNT where ACC_ID = #id#
   </ delete >

</ sqlMap >
 
一个与表对应的实体Bean(为了输出重写了toString方法):
package com.lavasoft.ibatissut.simple.domain.entity;

/**
* Created by IntelliJ IDEA.<p>
* User: leizhimin<p>
* Date: 2008-8-16 9:57:03<p>
* 帐户
*/

public class Account {
     private int id;
     private String firstName;
     private String lastName;
     private String emailAddress;

     public Account() {
    }

     public Account(String firstName, String lastName, String emailAddress) {
         this.firstName = firstName;
         this.lastName = lastName;
         this.emailAddress = emailAddress;
    }

     public int getId() {
         return id;
    }

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

     public String getFirstName() {
         return firstName;
    }

     public void setFirstName(String firstName) {
         this.firstName = firstName;
    }

     public String getLastName() {
         return lastName;
    }

     public void setLastName(String lastName) {
         this.lastName = lastName;
    }

     public String getEmailAddress() {
         return emailAddress;
    }

     public void setEmailAddress(String emailAddress) {
         this.emailAddress = emailAddress;
    }

    @Override
     public String toString() {
         return "Account{" +
                 "id=" + id +
                 ", firstName='" + firstName + '\'' +
                 ", lastName='" + lastName + '\'' +
                 ", emailAddress='" + emailAddress + '\'' +
                '}';
    }
}
 
核心测试代码(尊重iBatis的原版风格,就窝下蛋,写个main方法就开始跑了。。):
package com.lavasoft.ibatissut.simple;

import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import com.ibatis.common.resources.Resources;
import com.lavasoft.ibatissut.simple.domain.entity.Account;

import java.io.Reader;
import java.io.IOException;
import java.util.List;
import java.sql.SQLException;

/**
* Created by IntelliJ IDEA.<p>
* User: leizhimin<p>
* Date: 2008-8-16 9:59:10<p>
* 首先声明这不是最好的例子,但是从这个例子中可以很快的了解iBatis的工作原理,
* 如果需要更好的学习iBatis,可以参看iBatis实现的JPetStore-5.0.zip。
* [url]http://apache.mirror.phpchina.com/ibatis/binaries/ibatis.java/JPetStore-5.0.zip[/url]
*/


public class SimpleExample {

     /**
     * SqlMapClient的实例是线程安全的,因此仅需要一个实例即可,这里使用了一个静态单例模式。
     */

     private static SqlMapClient sqlMapClient;

     /**
     * 将SqlMapClient的构件放到此不是好注意,应该放到一个单例模式的工具类中,需要的时候随时获取
     */

     static {
         try {
             //读取SqlMapConfig的资源配置
            Reader reader = Resources.getResourceAsReader( "SqlMapConfig.xml");
             //构件一个SqlMapClient的实例
            sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
             //关闭输入流
            reader.close();
        } catch (IOException e) {
             throw new RuntimeException( "在构件SqlMapClient实例的时候发生了异常!" + e, e);
        }
    }

     public static List selectAllAccounts() throws SQLException {
         //返回所有的帐户
         return sqlMapClient.queryForList( "Account.selectAllAccounts");
    }

     public static Account selectAccountById( int id) throws SQLException {
         return (Account) sqlMapClient.queryForObject( "Account.selectAccountById", id);
    }

     public static void insertAccount(Account account) throws SQLException {
        sqlMapClient.insert( "Account.insertAccount", account);
    }

     public static void updateAccount(Account account) throws SQLException {
        sqlMapClient.update( "Account.updateAccount", account);
    }

     public static void deleteAccount( int id) throws SQLException {
        sqlMapClient.delete( "Account.deleteAccount", id);
    }

     public static void main(String[] args) throws SQLException {
        Account act = new Account( "1", "1", "1");
        act.setId(23);
        
        insertAccount(act);


        List<Account> acclist=  selectAllAccounts();
         for(Account acc:acclist){
            System.out.println(acc);
        }
    }
}
 
运行一把看看:
Account{id=1, firstName='45', lastName='45', emailAddress='4554'}
Account{id=2, firstName='234', lastName='234', emailAddress='23423'}
Account{id=3, firstName='1', lastName='1', emailAddress='1'}
Account{id=4, firstName='1', lastName='1', emailAddress='1'}
Account{id=5, firstName='1', lastName='1', emailAddress='1'}

Process finished with exit code 0
 
呵呵,终于看到效果了。
 
iBatis是个好东西,但是技巧性很强,只有完全掌握了iBatis的映射原理和技巧,用起来才不至于生硬繁琐重复。上面这个例子是iBatis发布包中唯一一个例子,而且使用的是一个大家都很陌生的数据库,并且没有执行的入口方法,缺乏SQL脚本,没有使用命名空间等等,这个粗糙的例子给很多第一次接触iBatis的人一个极坏的印象,和一些致命的误导。
 
iBatis应用中应该使用命名空间,不使用的话好像除了HelloWorld这样的简单例子外,找不到第二个。
 
 
 
 
 
 
ibatis 开发指南 ibatis Quick Start............................................................................................ 5 准备工作.......................................................................................................... 5 构建ibatis 基础代码.................................................................................... 5 ibatis 配置........................................................................................................... 11 ibatis 基础语义...................................................................................................... 16 XmlSqlMapClientBuilder................................................................... 16 SqlMapClient ........................................................................................... 16 SqlMapClient 基本操作示例.......................................................... 16 OR 映射........................................................................................................... 19 ibatis 高级特性...................................................................................................... 26 数据关联........................................................................................................ 26 一对多关联............................................................................................ 26 一对一关联............................................................................................ 28 延迟加载........................................................................................................ 30 动态映射........................................................................................................ 31 事务管理........................................................................................................ 35 基于JDBC 的事务管理机制................................................................ 35 基于JTA 的事务管理机制................................................................... 36 外部事务管理......................................................................................... 38 Cache .............................................................................................................. 39 MEMORY 类型Cache 与WeakReference ........................................ 40 LRU 型Cache ....................................................................................... 42 FIFO 型Cache ...................................................................................... 43 OSCache................................................................................................. 43
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值