试在运行期从ibatis配置文件中取<select/>标签内的sql

ibatis分页不怎么好用,不是数据库物理分页,数量大起来性能下降得厉害,所以有必要依托特定数据库做分页sql的包装,因此牵扯出这样的问题,即在代码中如何从指定id的select标签中获取被动态拼装好带参数占位符(?)并被实际执行的sql语句.

昨天跟了一下代码,从getSqlMapClientTemplate一路跟到ibatis的源代码,
找到了几处关键性代码,因此提取出来,在jpetstore上试验了一下,发现可行,
所以和大家分享一下.

[code]import com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient;
import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate;
import com.ibatis.sqlmap.engine.mapping.sql.Sql;
import com.ibatis.sqlmap.engine.mapping.statement.MappedStatement;[/code]


[code]
//SqlMapExecutorDelegate是一个相当核心的类,他存放了配置文件所有信息和java连接对象,有一个会话池和一个请求池,还有sql解析其,以及一个具体sql语句的执行者,大家可以看看
SqlMapExecutorDelegate delegate=((ExtendedSqlMapClient)(getSqlMapClientTemplate().getSqlMapClient())).getDelegate();
//这个类用来存放某个id名的Statement信息,如这个当中的getProduct就是一条语句的配置id名
MappedStatement ms = delegate.getMappedStatement("getProduct");
//sql类就是某一类型 Statement的对应sql拼装解析类
Sql sql=ms.getSql();
//然后调用getSql方法,把参数值数组传进去,如下面只有一个参数productId,便可以生成 形如 select * from xxx where xx=?的sql语句了,代理类的sql执行者便可以根据这个sql和参数值数组进行参数查询了,前面那个参数的类型是com.ibatis.sqlmap.engine.scope.RequestScope,这个要从上面提到的代理类里面获取,但是因为是保护成员,而且发现拼凑sql的时候并没有多大作用,所以传了个null进去,结果居然通过了,不过这部分我还要确认一下.个人感觉RequestScope还是很重要的,可以会影响其他类型的Statement
System.out.println(sql.getSql(null,productId) );
[/code]

以上例子代码是改自JPetstore,
建议大家自己重写一个继承自SqlMapClientDaoSupport的抽象类,把这个提取sql功能写成一个基类方法,好让具体的业务dao类使用.
在 MyBatis 的映射文件或配置文件中添加`<typeHandler>`标签可以指定类型处理器,具体步骤如下: 1. 创建一个 Java 类型,例如`com.example.MyType`: ```java package com.example; public class MyType { // 类型定义 } ``` 2. 创建一个类型处理器,实现 TypeHandler 接口,例如`com.example.MyTypeHandler`: ```java package com.example; import java.sql.*; import org.apache.ibatis.type.*; @MappedTypes(MyType.class) @MappedJdbcTypes(JdbcType.VARCHAR) public class MyTypeHandler implements TypeHandler<MyType> { @Override public void setParameter(PreparedStatement ps, int i, MyType parameter, JdbcType jdbcType) throws SQLException { // 设置参数 } @Override public MyType getResult(ResultSet rs, String columnName) throws SQLException { // 获取结果 } @Override public MyType getResult(ResultSet rs, int columnIndex) throws SQLException { // 获取结果 } @Override public MyType getResult(CallableStatement cs, int columnIndex) throws SQLException { // 获取结果 } } ``` 3. 在映射文件或配置文件中,使用`<typeHandler>`标签指定类型处理器,例如: ```xml <resultMap id="exampleResultMap" type="com.example.MyType"> <result column="my_column" property="myProperty" typeHandler="com.example.MyTypeHandler"/> </resultMap> ``` 或者: ```xml <configuration> <typeHandlers> <typeHandler handler="com.example.MyTypeHandler"/> </typeHandlers> <!-- 其他配置 --> </configuration> ``` 在第一种情况下,`<result>`标签指定了类型处理器,用于将查询结果映射到 Java 对象中。在第二种情况下,`<typeHandler>`标签指定了全局类型处理器,用于处理所有映射文件中的类型。 希望这个回答能够帮助到你!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值