`
badqiu
  • 浏览: 670230 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

ibatis3 (mybatis) 实例代码下载兼ibatis3优劣分析

    博客分类:
  • Java
阅读更多

(本文章于2010-06-30更新以适应mybatis的最新版本)

 

作为rapid-framework路线图的一部分,集成ibatis3也是以后要更新的内容之一.

现编写了ibatis3的代码例子. 

 

一.首先我们来看现在的xml mapper关于增删改查的编写

 

 

<mapper namespace="UserInfo">

	<resultMap id="RM.UserInfo" type="com.company.project.model.UserInfo">
        <result property="userId" column="USER_ID"/>
        <result property="username" column="USERNAME"/>
        <result property="password" column="PASSWORD"/>
        <result property="birthDate" column="BIRTH_DATE"/>
        <result property="sex" column="SEX"/>
        <result property="age" column="AGE"/>
	</resultMap>
	
	<!-- 用于select查询公用抽取的列 -->
	<sql id="UserInfo.columns">
	    <![CDATA[
        	USER_ID,
        	USERNAME,
        	PASSWORD,
        	BIRTH_DATE,
        	SEX,
        	AGE
	    ]]>
	</sql>

	<!-- useGeneratedKeys="true" keyProperty="xxx" for sqlserver and mysql -->
	<insert id="UserInfo.insert" useGeneratedKeys="true" keyProperty="userId">
    <![CDATA[
        INSERT INTO USER_INFO (
        	USER_ID ,
        	USERNAME ,
        	PASSWORD ,
        	BIRTH_DATE ,
        	SEX ,
        	AGE 
        ) VALUES (
        	#{userId} ,
        	#{username} ,
        	#{password} ,
        	#{birthDate} ,
        	#{sex} ,
        	#{age} 
        )
    ]]>
		<!--	
			oracle: order="BEFORE" SELECT sequenceName.nextval AS ID FROM DUAL 
			DB2: order="BEFORE"" values nextval for sequenceName
		<selectKey resultType="java.lang.Long" order="BEFORE" keyProperty="userId">
			SELECT sequenceName.nextval AS ID FROM DUAL 
        </selectKey>
		-->
	</insert>
    
	<update id="UserInfo.update" >
    <![CDATA[
        UPDATE USER_INFO SET
	        USERNAME = #{username} ,
	        PASSWORD = #{password} ,
	        BIRTH_DATE = #{birthDate} ,
	        SEX = #{sex} ,
	        AGE = #{age} 
        WHERE 
	        USER_ID = #{userId} 
    ]]>
	</update>

    <delete id="UserInfo.delete">
    <![CDATA[
        DELETE FROM USER_INFO WHERE
        USER_ID = #{id} 
    ]]>
    </delete>
    
    <select id="UserInfo.getById" resultMap="RM.UserInfo">
		SELECT <include refid="UserInfo.columns" />
	    <![CDATA[
		    FROM USER_INFO 
	        WHERE 
		        USER_ID = #{id} 
	    ]]>
	</select>
	
	<sql id="UserInfo.findPage.where">
		<!-- ognl访问静态方法的表达式 为@class@method(args),以下为调用rapid中的Ognl.isNotEmpty()方法,还有其它方法如isNotBlank()可以使用,具体请查看Ognl类 -->
		<where>	      				
	       <if test="@Ognl@isNotEmpty(userId)">
				AND USER_ID = #{userId}
			</if>
	       <if test="@Ognl@isNotEmpty(username)">
				AND USERNAME = #{username}
			</if>
	       <if test="@Ognl@isNotEmpty(password)">
				AND PASSWORD = #{password}
			</if>
	       <if test="@Ognl@isNotEmpty(birthDateBegin)">
				AND BIRTH_DATE >= #{birthDateBegin}
		   </if>
		   <if test="@Ognl@isNotEmpty(birthDateEnd)">
				AND BIRTH_DATE &lt;= #{birthDateEnd}
		   </if>
	       <if test="@Ognl@isNotEmpty(sex)">
				AND SEX = #{sex}
			</if>
	       <if test="@Ognl@isNotEmpty(age)">
				AND AGE = #{age}
			</if>
		</where>
	</sql>
		
    <select id="UserInfo.findPage.count" resultType="long">
        SELECT count(*) FROM USER_INFO 
		<include refid="UserInfo.findPage.where"/>    
    </select>
    
    <!--
    	分页查询已经使用Dialect进行分页,也可以不使用Dialect直接编写分页
    	因为分页查询将传 offset,pageSize,lastRows 三个参数,不同的数据库可以根于此三个参数属性应用不同的分页实现
    -->
    <select id="UserInfo.findPage" resultMap="RM.UserInfo">
    	SELECT <include refid="UserInfo.columns" />
	    FROM USER_INFO 
		<include refid="UserInfo.findPage.where"/>
		
		<if test="@Ognl@isNotEmpty(sortColumns)">
			ORDER BY ${sortColumns}
		</if>
    </select>
</mapper>

 

 

与ibatis2 sqlmap的主要异同:

1. insert节点现在可以直接指定mysql auto_increment(或是sqlserver identity)的主键生成策略

  useGeneratedKeys="true" keyProperty="userId" 

 

2.动态构造sql部分,test部分采用的是struts2 ognl表达式,还有choose,foreach语句等,跟struts2 tag是否很像呢?

  (注:此处现可以使用ONGL访问静态方法来解决:@Ognl@isNotEmpty(userId))

  Ognl静态方法调用

 

二.构造SqlSessionFactory,以前的SqlMapClient

 

		Reader reader = Resources.getResourceAsReader("Configuration.xml");
		SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
		SqlSession session = sessionFactory.openSession();

 

三. 配置文件Configuration.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-config.dtd">
<configuration>
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=UTF-8" />
				<property name="username" value="root" />
				<property name="password" value="123456" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="com/company/project/model/mapper/UserInfoMapper.xml" />
	</mappers>
</configuration>

 

以上就是完整的示例, 具体demo代码下载:  http://rapid-framework.googlecode.com/files/ibatis3_demo.zip

 

 

ibatis3 annotation评价:

难听点,根本是个脑残方案,如果用annotation写,我还不如使用类似jdbc的java代码. 不知道自己优势是在xml文件,瞎跟风.

 

而spring现在还没有对ibatis3集成,不过以后rapid会先与spring发布ibatis3的插件, 只提供生成器模板,现不自己开发集成,等待spring. 当然以后对提供类似ibatis2的基于方言Dialect的分页还是会提供的.

 

 

最后仍然做下广告: rapid-framework, 现最好的项目脚手架

http://code.google.com/p/rapid-framework/

 

 

 

20
4
分享到:
评论
11 楼 poplong_2001 2009-12-13  
楼主的原文:ibatis3 annotation评价:

难听点,根本是个脑残方案,如果用annotation写,我还不如使用类似jdbc的java代码. 不知道自己优势是在xml文件,瞎跟风.

楼主这段话说明楼主压根没有认真看ibatis3的官方文档。
ibatis3的官方文档中明确说明了:“Java Annotations are unfortunately limited in their expressiveness and flexibility. Despite a lot of time spent in investigation, design and trials, the most powerful iBATIS mappings simply cannot be built with Annotations – without getting ridiculous that is.”That said, the Java!Annotation based configuration is not without its benefits.
ibatis3之所以推出这种配置方式,主要是为了顺应新的jdk的变化,为部分用户提供一种选择而已,文档中其实已经明确指出了java annotations的缺陷,而且并不鼓励大家在大型的项目中使用。并强调xml的方式仍然是发挥ibatis3优势的最好选择。
10 楼 littleJava 2009-11-09  
iBATIS3.0和iBATIS2.0在XML的规则上有写区别,近期估计不会有iBATIS3的实际项目吧
9 楼 melin 2009-09-28  
badqiu 写道
你现在这个切入点是不行的,必须要能够修改limit及offset的值才行, 我已经写好了,我写一下文章介绍一下.


反射能获取,肯定能修改
期待你的思路。。。
8 楼 badqiu 2009-09-28  
你现在这个切入点是不行的,必须要能够修改limit及offset的值才行, 我已经写好了,我写一下文章介绍一下.
7 楼 melin 2009-09-28  
melin 写道
然以后对提供类似ibatis2的基于方言Dialect的分页还是会提供的. 
希望尽快提供一个ibatis3,谢谢!


自己写了一个,找切入点,花了不少时间:

@Intercepts({@Signature(
		type= StatementHandler.class, 
		method = "prepare", args = {Connection.class})})
public class DiclectStatementHandlerInterceptor implements Interceptor {
	
	private Properties properties;
	
	private static final String DIALECT = "dialect";
	
	public Object intercept(Invocation invocation) throws Throwable {
		RoutingStatementHandler statement = (RoutingStatementHandler)invocation.getTarget();
		
		PreparedStatementHandler handler = (PreparedStatementHandler) ReflectUtil.getField(statement, "delegate", StatementHandler.class);
		
		Integer rowOffset = (Integer)ReflectUtil.getField(handler, "rowOffset", int.class);
		Integer rowLimit = (Integer)ReflectUtil.getField(handler, "rowLimit", int.class);
		
		if(rowLimit !=0) {
			BoundSql boundSql = statement.getBoundSql();
			String sql = boundSql.getSql();
			String dialectStr = properties.getProperty(DIALECT);
			
			Dialect dialect = (Dialect) Class.forName(dialectStr).newInstance();
			
			sql = dialect.getLimitString(sql, rowOffset, rowLimit);
			ReflectUtil.setFieldValue(boundSql, "sql", String.class, sql);
		}
		return invocation.proceed();
	}

	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}

	public void setProperties(Properties properties) {
		this.properties = properties;
	}
}

6 楼 melin 2009-09-27  
然以后对提供类似ibatis2的基于方言Dialect的分页还是会提供的. 
希望尽快提供一个ibatis3,谢谢!
5 楼 超级潜水员 2009-09-24  
真是够快的,期待楼主的3.0版本.
4 楼 badqiu 2009-09-24  
gosin 写道
可以google下,网上已经有spring3跟ibatis3的集成了。


等spring3集成吧,实在没有必要自己写,反正两者都没有发布.都不会有人实际应用ibatis beta3应用于生产环境的.

3 楼 badqiu 2009-09-24  
annotation主要是速度快,如spring的@Component等标注,很方便。

不过,太多annotation就难以接受,尤其ibatis3.0这种,根本不是人能够看的。

而ibatis3这种语法: #{age,javaType=int,jdbcType=NUMERIC,typeHandler=typeHandler}
主要也是由于要适应annotation,所以才搞出这种东西.

2 楼 treblesoftware 2009-09-24  
annotation很侵入代码,不知道badqiu对annotation泛滥有什么感觉?annotation根本没有解决配置问题,配置是变少了,但是由于配置引起的问题根本没有被解决。
1 楼 gosin 2009-09-24  
可以google下,网上已经有spring3跟ibatis3的集成了。

相关推荐

Global site tag (gtag.js) - Google Analytics