`
aimer311
  • 浏览: 94758 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

ibatis分页实现

    博客分类:
  • java
阅读更多
上次写了关于ibatis处理sybase分页的问题,参见:http://aimer311.iteye.com/blog/289411现在把它写完整,目前算是确定用该方案了。
其实要解决的问题就是在传入存储过程之前的sql构造过程。
分页存储过程如下:
if exists(select 1 from sysobjects where type = 'P' and name = 'asp_query_page') drop procedure asp_query_page
go
create procedure asp_query_page @sql varchar(2000),@start int, @pageSize int as 

begin 
    declare @ipage int
    declare @rcount int 
    declare @execsql varchar(2000)
    declare @sql1 varchar(2000) 
    declare @t int,@p int,@n int,@l int

    begin

        set @sql1=@sql
        set @n=0
        set @l=0
        set @t=charindex('select ',lower(@sql))
        set @sql=substring(@sql,@t+7,char_length(@sql)-7)
        set @n=@n+1
        set @l=@l+7
        
        while(@n!=0)
        begin
            set @t=charindex('select ',lower(@sql))
            set @p=charindex('from ',lower(@sql))
            if ((@t<@p) and (@t!=0))
                begin
                    set @sql=substring(@sql,@t+7,char_length(@sql)-7)
                    set @n=@n+1
                    set @l=@l+6+@t
                end
            else
                begin
                    set @sql=substring(@sql,@p+5,char_length(@sql)-5)
                    set @n=@n-1
                    set @l=@l+4+@p
                end
        end
        set @execsql = substring(@sql1,1,@l-5)+' ,sybid=identity(12) into #temp '+substring(@sql1,@l-4,char_length(@sql1)-@l+5)
        select @rcount=@start + @pageSize
    	set rowcount @rcount 
        set @execsql = @execsql || ' select * from #temp where sybid>' || convert(varchar,@start) || ' and sybid <= ' || convert(varchar,@rcount) 
        print @execsql
        execute (@execsql) 
    	set rowcount 0 
    end
end

ibatis的sqlMap配置如下:
  <parameterMap class="java.util.HashMap" id="params">
	<parameter javaType="String" jdbcType="CHAR" mode="IN" property="sql" />
	<parameter javaType="int" jdbcType="numberic" mode="IN" property="start" />
	<parameter javaType="int" jdbcType="numberic" mode="IN" property="pageSize" />
  </parameterMap>
  <procedure cacheModel="abatorgenerated_cache" id="selectByOrganId" parameterMap="params" resultMap="selectByOrganIdResult">
    {call asp_query_page(?,?,?)}
  </procedure> 

程序中调用如下:
public List queryPageByProc(String sql, int start, int pageSize) {
		QMap map = new QMap().add("sql", sql)
			 	.add("start", new Integer(start))
			 	.add("pageSize", new Integer(pageSize));
			return  getSqlMapClientTemplate().queryForList("PROCEDURE.asp_query_page", map);
	}

这些都很好理解,接下来着重讲下如何在调用procedure之前讲sql完整的传入。我使用的方法其实很简单,多增加一个map文件用于存放所有需要分页的查询语句。文件的内容类似:
<?xml version="1.0" encoding="UTF-8"?>
<sqlMap namespace="TEST">
  <select id="testWithParamMap">
    select unique * from TEST where NAME LIKE '%#NAME#%' 
    [and EMAIL ='#EMAIL#'] and id=1 [and EMAIL= #EMAIL#]
  </select>
  <select id="testWithParamList">
    select * from TEST a,ABC b 
    where 
    a.ID=? 
    [and a.EMAIL like '?'] 
    and a.ID=? 
    [and a.email='?']
  </select> 
  <select id="testWithParamStringArr">
    select convert(varchar,b.id) id,b.groupid 
    from ABC b 
    WHERE A.ID=? 
    [AND A.EMAIL=?] 
    AND ID=? 
    [and a.name = ?]
  </select>     
</sqlMap>

然后解析这个文件,相当于预存了sql模板,当有不同的参数传入时,识别参数,返回最后的sql。目前的解析程序参数支持Map,List,String[].支持不定条件的查询等等。还没有遇到不支持的sql。
java代码的调用如下:
SqlStatement.getSql("BGM_ASSET_INFO.selectByOrganId", params)

整个过程只是增加了预编译sql语句的过程,其他调用与ibatis无异。
你可能会发现这个额外的Map配置文件有诸如:a.email='?'的语句,其实这也很好解决,可以参考sqlMap中多加一个Class="yourClass",然后根据你的VO的字段的类型具体判断是否需要加上'符号,多增加了一些类型解析过程而已。
2
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics