一直想让mybatis实现根据传入的DTO对象的值来自由组合查询条件。例如:查询语句
select deptno,dname,loc from dept where deptno=? and dname=? and loc=?。如果我传入的DTO只有deptno和dname两个属性值。系统能自动将查询SQL修改为
select deptno,dname,loc from dept where deptno=? and dname=?。虽然通过mybatis的动态SQL可以实现。但是要写的代码太多,而且每个使用SQL都要进行修改,过于麻烦。所以就想通过修改mybatis的代码来实现此种功能。来简化开发代码编写量,提高开发效率.
经过几天的代码追踪,最后通过以下的代码调整,实现以上功能。
设置SQL的类,由于mybatis是在
org.apache.ibatis.executor.statement.PreparedStatementHandler类的
instantiateStatement方法中获取sql
protected Statement instantiateStatement(Connection connection) throws SQLException {
String sql = boundSql.getSql();
所以就想在此处进行sql重新设置。
顾在此处增加
sql=parameterHandler.setSQL(sql);
重新设置SQL
由于ParameterHandler是一个接口。所以在
org.apache.ibatis.executor.parameter.ParameterHandler
接口中增加getSql方法
String setSQL(String sql) throws SQLException;
由于org.apache.ibatis.executor.parameter.DefaultParameterHandler实现了ParameterHandler接口
所以在DefaultParameterHandler类中增加设置SQL的方法。
//更新SQL
public String setSQL(String sql) throws SQLException {
String tempString="";
int tempInt=0;
ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
if (parameterMappings != null) {
MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject);
for (int i = 0; i < parameterMappings.size(); i++) {
ParameterMapping parameterMapping = parameterMappings.get(i);
if (parameterMapping.getMode() != ParameterMode.OUT) {
Object value;
String propertyName = parameterMapping.getProperty();
PropertyTokenizer prop = new PropertyTokenizer(propertyName);
if (parameterObject == null) {
value = null;
} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
value = parameterObject;
} else if (boundSql.hasAdditionalParameter(propertyName)) {
value = boundSql.getAdditionalParameter(propertyName);
} else if (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX)
&& boundSql.hasAdditionalParameter(prop.getName())) {
value = boundSql.getAdditionalParameter(prop.getName());
if (value != null) {
value = configuration.newMetaObject(value).getValue(propertyName.substring(prop.getName().length()));
}
} else {
value = metaObject == null ? null : metaObject.getValue(propertyName);
}
TypeHandler typeHandler = parameterMapping.getTypeHandler();
if (typeHandler == null) {
throw new ExecutorException("There was no TypeHandler found for parameter " + propertyName + " of statement " + mappedStatement.getId());
}
if(value.toString().length()==0){
StringTokenizer parameterMappingParts = new StringTokenizer(sql,"\n\r\t");
sql="";
while (parameterMappingParts.hasMoreTokens()) {
tempString=parameterMappingParts.nextToken();
tempInt = tempString.toUpperCase().indexOf(propertyName.toUpperCase());
if(tempInt==-1){
sql=sql+tempString+"\n\r\t";
}
}
}
}
}
}
return sql;
}
此处是通过换行来进行SQL替换。
所以在XML中编写SQL时,如果哪一个查询条件要根据传入的值来判断是否保留,则需要单独一行。编写SQL如下所示:
select * from Dept where 1=1
DEPTNO = #{deptno}
and DNAME = #{dname}
and LOC = #{loc}
通过以上代码调整,mybatis就可以实现根据传入查询DTO的属性值自动进行查询SQL组合。
最后,第一次写这种技术的内容,忽然发现想要把技术内容讲透彻,还真是挺麻烦的一件事。我在ITeye的第一次。值得纪念!希望能做的更好!
分享到:
相关推荐
MyBatis动态条件通用查询是数据库操作中常见的一种需求,它允许开发者在不编写大量重复SQL语句的情况下,根据传入的参数灵活地执行查询。这个功能的核心在于利用MyBatis的动态SQL特性,结合Map数据结构来构建可变的...
通过mybatis的拦截器,实现为所有sql(或指定sql) 统一添加查询条件,譬如通过线程变量传递某参数(日期),来实现对指定参数的数据筛选,而不需要在每个查询前,手动将该条件注入到查询中。因该资料网络较少,故特此...
"MyBatis之自查询使用递归实现 N级联动效果" MyBatis是一个功能强大且灵活的持久层框架,它支持自查询和递归查询,下面我们将探讨如何使用MyBatis实现 N级联动效果。 递归查询 递归查询是指在一个查询中调用自身...
例如,使用 `<if>`标签来实现动态条件查询,可以将where 1=1改为 `<where>`标签,其余保持不变。 另外,还可以使用 `<when>` 和 `<choose>` 标签来实现动态条件查询。例如,使用 `<when>` 标签来实现动态条件查询,...
通过修改BoundSql的sql字符串,我们可以实现动态SQL,比如根据条件决定是否包含某个字段的LIKE操作。例如,如果某个参数为null,我们可以将对应的WHERE子句去掉,以避免无效的查询。 以下是一个简单的例子,展示...
我们可以使用 Mybatis 的动态 SQL 功能来实现跨库查询,例如使用 `<choose>` 和 `<when>` 语句来根据不同的数据库实例来生成不同的 SQL 语句。 Spring 多数据源处理_Mybatis 实现跨库查询可以有效地提高系统的水平...
条件查询是MyBatis中非常关键的功能,它允许我们根据不同的参数条件动态构建SQL语句,以满足多样化的查询需求。 在MyBatis中,条件查询主要通过动态SQL实现,这通常涉及到`<if>`, `<choose>`, `<when>`, `...
本文将深入探讨Mybatis如何实现这两种查询方式,并提供多种实现方法。 首先,我们来理解Mybatis的基本概念。Mybatis是一个优秀的Java持久层框架,它允许开发者将SQL语句直接写在XML配置文件或者Mapper接口中,从而...
在SpringBoot项目中,整合Mybatis-Plus并实现多数据源的动态切换,同时支持分页查询是一项常见的需求。以下将详细阐述这个过程中的关键步骤和技术要点。 首先,我们需要引入必要的Maven依赖。这里提到了四个关键...
Mybatis框架(条件查询)
Mybatis基于注解实现多表查询功能 Mybatis基于注解实现多表查询功能是指使用Mybatis框架中的注解来实现多表查询的功能。这种方法可以简化配置,提高开发效率。下面我们将详细介绍如何使用Mybatis基于注解实现多表...
例如,可以使用`<if>`标签检查RowBounds是否为空,然后动态地插入`LIMIT`和`OFFSET`。 - **Service类(UserService.java)**:调用Mapper接口的方法,传递RowBounds实例以获取分页数据。通常,我们可以创建一个...
06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo...
例如,当查询特定用户时,可以根据用户 ID 是否为空来决定是否添加 WHERE 子句。 ```xml != null"> AND id = #{id} ``` 2. `<choose>`、`<when>`、`<otherwise>` 标签:类似于 Java 中的 `switch` 语句,用于多...
标题 "使用mybatis实现CRUD" 涉及到的是在Java开发中使用MyBatis框架进行基本的数据操作,即创建(Create)、读取(Read)、更新(Update)和删除(Delete)。MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储...
QueryWrapper还支持逻辑运算符,如`and`、`or`,可以组合多个条件进行查询。例如: ```java queryWrapper.and(wrapper -> wrapper.eq("name", "张三").or().eq("name", "李四")); ``` 这段代码将查询名字为"张三...
这是SpringBoot整合MyBatis实现的简易登陆注册。这里所使用的开发环境是:IDEA、MySQL_8.0.17、Java8;其中用到了Druid数据库连接池。这个登录注册demo中,登录失败有两种情况:①账户不存在;②密码错误。注册失败...
04实现mybatis条件构造器代码demo04实现mybatis条件构造器代码demo04实现mybatis条件构造器代码demo04实现mybatis条件构造器代码demo04实现mybatis条件构造器代码demo04实现mybatis条件构造器代码demo04实现mybatis...