iBatis学习笔记

iBatis是一个由Apache维护的ORM框架,不同于Hibernate的全自动实现,它提供半自动的映射,允许开发者自定义SQL。本文将介绍如何搭建iBatis环境,配置XML映射文件,并展示增删改查操作。

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

iBatis是Apcahe的一个开源项目,10年由Google托管后,改名为mybatis

iBatis和hibernate一样是一种ORM(对象关系映射)的框架,不同之处在于Hibernate是提供了全面的数据库封装机制的全自动化ORM实现,实现了POJO和数据库表之间的映射,以及SQL的自动的生成和执行。而iBatis是一种办自动化的实现,着力于POJO和SQL之间的映射,也就是说iBatis并不会为程序员在运行期自动生成SQL执行,具体的SQL需要程序员自己编写,然后通过配置映射文件,将SQL所需的参数,以及返回的结果字段映射到指定的POJO.

iBatis以SQL开发的工作量和数据库移植性上差为代价,为系统设计提供了更大的自由空间。

下面就来实际操作一个iBatis的实例

首先是搭建iBatis的开发环境:导入jar包ibatis-2.3.4.726.jar和ojdbc14.jar

然后创建数据库表和添加数据















数据库语句

create table userinfo(
id int primary key,
name varchar2(50),
score varchar2(50)
);
Insert into users values(1,’唐伯虎’,’10’);
Insert into users values(2,’点’,’20’);
Insert into users values(3,’秋香’,’30’);
-- Create sequence 
create sequence USERINFO_ID
minvalue 1
maxvalue 999999999999999999999999999
start with 1
increment by 1
cache 20;


user类

package cn.entityy;

public class User {
	private int id;
	private String name;
	private String score;
	
	public String getScore() {
		return score;
	}
	public void setScore(String score) {
		this.score = score;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public User(int id, String name,String score) {
		super();
	        this.id = id;
		this.name = name;
	        this.score=score;
	}
	public User(){
		super();
	}
	
	
}

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>
	<!-- 参数说明:
	 cacheModelsEnabled 是否启用SqlMapClient 上的缓存机制。建议设为"true"
	 enhancementEnabled:是否针对POJO 启用字节码增强机制以提升getter/setter 的调用效能,避免使用Java
       Reflect 所带来的性能开销。同时,这也为Lazy Loading 带来了极大的性能提升。建议设为"true"
     lazyLoadingEnabled: 启用或禁用SqlMapClient的所有延迟加载。调试程序时使用。 建议设为"true"
	 maxRequests: 同时执行SQL语句的最大线程数。大于这个值的线程将阻塞直到另一个线程执行完成。 不同的DBMS有不同的限制值,但任何数据库都有这些限制。通常这个值应该至少是 
	   maxTransactions的10倍,并且总是大于maxSessions和maxTranactions。 减小这个参数值通常能提高性能。
	 maxSessions: 同一时间内活动的最大session数。一个session可以是代码请求的显式session, 也可以是当线程使用SqlMapClient实例(即执行一条语句)自动获得的session。 
		它应该总是大于或等于maxTransactions并小于maxRequests。减小这个参数值通常能 减少内存使用。
	 maxTransactions: 同时进入SqlMapClient.startTransaction()的最大线程数。大于这个值的线程将阻塞 直到另一个线程退出。不同的DBMS有不同的限制值,但任何数据库都有这些限制。这个 
		参数值应该总是小于或等于maxSessions并总是远远小于maxRequests。减小这个参数值 通常能提高性能。 
	 useStatementNamespaces: 
		如果启用本属性,必须使用全限定名来引用mapped statement。Mapped statement的 全限定名由sql-map的名称和mapped-statement的名称合成,例如 
		queryForObject(“sqlMapName.statementName”) -->
	<settings cacheModelsEnabled="true" lazyLoadingEnabled="true"
		enhancementEnabled="true" />
	<!-- 配置数据库连接信息 -->
	<transactionManager type="JDBC">
		<dataSource type="SIMPLE">
			<property name="JDBC.Driver" value="oracle.jdbc.driver.OracleDriver" />
			<property name="JDBC.ConnectionURL" value="jdbc:oracle:thin:@localhost:1521:orcl" />
			<property name="JDBC.Username" value="scott" />
			<property name="JDBC.Password" value="tiger" />
		</dataSource>
	</transactionManager>
	<sqlMap resource="cn/entityy/sqlmap-user.xml" />

</sqlMapConfig>

 


通过<insert>、<delete>、<update>、

<select>四个节点,我们分别定义了针对TUser 对象的增删改查操作

<?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标签是设置别名用的 声明别名后,在文件的后续部分可以直接使用别名
             而不用再给出完整类型了,非常方便 -->
    <typeAlias alias="User" type="cn.entityy.User"/>
    <!-- 返回值参数也同样有两种类型,一种是对象类型resultClass一种是resultMap
            当结果集列名和类属性名完全对应的时候,则应该使用resultClass来指定查询结果类型。当然有些列明不对应,可以在sql中使用as重命名达到一致的效果。
           当查询结果列名和类属性名对应不上的时候,应该选择 resultMap指定查询结果集类型。否则,则查询出来填充的对象属性为空(数字的为0,对象的为null)。
     -->
    <resultMap class="User" id="getAllUser" />
    <!-- cacheModel 节点定义了本映射文件中使用的Cache 机制:
    . flushInterval :设定缓存有效期,如果超过此设定值,则将此CacheModel 的缓存清空。
    . size:本CacheModel 中最大容纳的数据对象数量。
    . flushOnExecute:指定执行特定Statement 时,将缓存清空。如updateUser 操作将更新数据库中的用户信息,
               这将导致缓存中的数据对象与数据库中的实际数据发生偏差,因此必须将缓存清空以避免脏数据的出现。
     -->
    <cacheModel type="LRU" id="userCache">
    <flushInterval  hours="24"/>
    <flushOnExecute statement="updateUser"/>
    <property name="size" value="1000"/>
    </cacheModel>
    <!-- 查询语句 -->
    <select id="getAllUser" resultClass="User" cacheModel="userCache">
    select * from userinfo
    </select>
    <!-- parameterClass表示参数的内容 -->
    <!-- #表示这是一个外部调用的需要传进的参数,可以理解为占位符 -->
    <!-- 通过<![CDATA[……]]>节点,可以避免SQL 中与XML 规范相冲突的字符对 XML 映射文件的合法性造成影响-->
    <select id="getUserById" resultClass="User" parameterClass="int" cacheModel="userCache">
    <![CDATA[
     select * from userinfo  
    ]]> 
    <dynamic prepend="where">
    <isNotEmpty >
    id= #id#
    </isNotEmpty>
    </dynamic>
    </select>
    <!-- 新增用户对象 -->
    <!-- 这里需要说明一下不同的数据库主键的生成,对各自的数据库有不同的方式: -->
    <!-- mysql:SELECT LAST_INSERT_ID() AS VALUE -->
    <!-- mssql:select @@IDENTITY as value -->
    <!-- oracle:SELECT STOCKIDSEQUENCE.NEXTVAL AS VALUE FROM DUAL -->
    <!-- 还有一点需要注意的是不同的数据库生产商生成主键的方式不一样,有些是预先生成 (pre-generate)主键的,如Oracle和PostgreSQL。
               有些是事后生成(post-generate)主键的,如MySQL和SQL Server 所以如果是Oracle数据库,则需要将selectKey写在insert之前 -->
    <!-- 1. dual 确实是一张表.是一张只有一个字段,一行记录的表. 
      2.习惯上,我们称之为'伪表'.因为他不存储主题数据.
      3. 他的存在,是为了操作上的方便.因为select 都是要有特定对象的. --> 
    <insert id="saveUser" parameterClass="User">
    <selectKey resultClass="int" keyProperty="id">
    select userinfo_id.nextval as id from dual
    </selectKey>
    <![CDATA[
     insert into userinfo values(#id#,#name#,#score#) 
    ]]> 
    </insert>
    <!-- 删除用户对象 -->
    <delete id="deleteUser" parameterClass="int">
    <![CDATA[
      delete from userinfo where id=#id#
    ]]> 
    </delete>
    <!-- 更新用户对象 -->
    <update id="updateUser" parameterClass="User">
     <![CDATA[
      update userinfo set name=#name#,score=#score# where id=#id#
    ]]> 
    </update>
    </sqlMap>
      

package cn.dao;

import java.util.List;

import cn.entityy.User;

public interface UserDao {
public List<User> getAllUser();
public User getUserById(int id);
public void delete(int id);
public void save(User user);
public void update(User user);
}

package cn.impl;

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

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

import cn.dao.UserDao;
import cn.entityy.User;

public class UserImpl  implements UserDao {
   private static SqlMapClient sqlmapclient=null;
   static{
	  try {
		Reader reader=Resources.getResourceAsReader("SqlMapConfig.xml");
		sqlmapclient=SqlMapClientBuilder.buildSqlMapClient(reader);
		reader.close();
	} catch (IOException e) {
		e.printStackTrace();
	}
   }
	@Override
	public List<User> getAllUser() {
		try {
			return sqlmapclient.queryForList("getAllUser");
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public User getUserById(int id) {
		try {
			return (User) sqlmapclient.queryForObject("getUserById",id);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public void delete(int id) {
		try {
			sqlmapclient.delete( "deleteUser",id);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void save(User user) {
		   try {
			sqlmapclient.insert("saveUser", user);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void update(User user) {
		try {
			sqlmapclient.update("updateUser", user);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

package cn.test;

import java.util.List;

import cn.entityy.User;
import cn.impl.UserImpl;

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
     UserImpl ui=new UserImpl();
     ui.delete(4);
     User u=new User();
     u.setName("点");
     u.setScore("20");
     ui.save(u);
     User uu=ui.getUserById(3);
     uu.setName("秋香姐");
     uu.setScore("90");
     ui.update(uu);
     List<User> list=ui.getAllUser();
     for (User user : list) {
		System.out.println(user.getId()+user.getName()+user.getScore());
	}
     User user=ui.getUserById(3);
     System.out.println(user.getId()+user.getName()+user.getScore());
	}
    
}


另外ibatis还支持动态定制SQL语句,详细操作可参考别的文章



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值