`
java1978
  • 浏览: 10257 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使mybatis实现根据输入值是否为空进行动态组合查询条件

 
阅读更多
     一直想让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动态条件通用查询

    MyBatis动态条件通用查询是数据库操作中常见的一种需求,它允许开发者在不编写大量重复SQL语句的情况下,根据传入的参数灵活地执行查询。这个功能的核心在于利用MyBatis的动态SQL特性,结合Map数据结构来构建可变的...

    MyBatis拦截器 添加查询条件动态修改sql

    通过mybatis的拦截器,实现为所有sql(或指定sql) 统一添加查询条件,譬如通过线程变量传递某参数(日期),来实现对指定参数的数据筛选,而不需要在每个查询前,手动将该条件注入到查询中。因该资料网络较少,故特此...

    MyBatis之自查询使用递归实现 N级联动效果(两种实现方式)

    "MyBatis之自查询使用递归实现 N级联动效果" MyBatis是一个功能强大且灵活的持久层框架,它支持自查询和递归查询,下面我们将探讨如何使用MyBatis实现 N级联动效果。 递归查询 递归查询是指在一个查询中调用自身...

    Mybatis实现动态代理,动态SQL

    例如,使用 `&lt;if&gt;`标签来实现动态条件查询,可以将where 1=1改为 `&lt;where&gt;`标签,其余保持不变。 另外,还可以使用 `&lt;when&gt;` 和 `&lt;choose&gt;` 标签来实现动态条件查询。例如,使用 `&lt;when&gt;` 标签来实现动态条件查询,...

    MyBatis拦截器分页与动态修改SQL及其参数值

    通过修改BoundSql的sql字符串,我们可以实现动态SQL,比如根据条件决定是否包含某个字段的LIKE操作。例如,如果某个参数为null,我们可以将对应的WHERE子句去掉,以避免无效的查询。 以下是一个简单的例子,展示...

    spring多数据源的处理_mybatis实现跨库查询

    我们可以使用 Mybatis 的动态 SQL 功能来实现跨库查询,例如使用 `&lt;choose&gt;` 和 `&lt;when&gt;` 语句来根据不同的数据库实例来生成不同的 SQL 语句。 Spring 多数据源处理_Mybatis 实现跨库查询可以有效地提高系统的水平...

    mybatis条件查询

    条件查询是MyBatis中非常关键的功能,它允许我们根据不同的参数条件动态构建SQL语句,以满足多样化的查询需求。 在MyBatis中,条件查询主要通过动态SQL实现,这通常涉及到`&lt;if&gt;`, `&lt;choose&gt;`, `&lt;when&gt;`, `...

    Mybatis多参数查询与列表查询不同方式实现

    本文将深入探讨Mybatis如何实现这两种查询方式,并提供多种实现方法。 首先,我们来理解Mybatis的基本概念。Mybatis是一个优秀的Java持久层框架,它允许开发者将SQL语句直接写在XML配置文件或者Mapper接口中,从而...

    SpringBoot整合mybatis-plus实现多数据源的动态切换且支持分页查询.pdf

    在SpringBoot项目中,整合Mybatis-Plus并实现多数据源的动态切换,同时支持分页查询是一项常见的需求。以下将详细阐述这个过程中的关键步骤和技术要点。 首先,我们需要引入必要的Maven依赖。这里提到了四个关键...

    Mybatis框架(条件查询)

    Mybatis框架(条件查询)

    Mybatis基于注解实现多表查询功能

    Mybatis基于注解实现多表查询功能 Mybatis基于注解实现多表查询功能是指使用Mybatis框架中的注解来实现多表查询的功能。这种方法可以简化配置,提高开发效率。下面我们将详细介绍如何使用Mybatis基于注解实现多表...

    MyBatis分页功能实现

    例如,可以使用`&lt;if&gt;`标签检查RowBounds是否为空,然后动态地插入`LIMIT`和`OFFSET`。 - **Service类(UserService.java)**:调用Mapper接口的方法,传递RowBounds实例以获取分页数据。通常,我们可以创建一个...

    06实现mybatis分页插件demo

    06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo...

    mybatis之动态SQL

    例如,当查询特定用户时,可以根据用户 ID 是否为空来决定是否添加 WHERE 子句。 ```xml != null"&gt; AND id = #{id} ``` 2. `&lt;choose&gt;`、`&lt;when&gt;`、`&lt;otherwise&gt;` 标签:类似于 Java 中的 `switch` 语句,用于多...

    使用mybatis实现CRUD

    标题 "使用mybatis实现CRUD" 涉及到的是在Java开发中使用MyBatis框架进行基本的数据操作,即创建(Create)、读取(Read)、更新(Update)和删除(Delete)。MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储...

    mybatis-plus QueryWrapper条件查询器

    QueryWrapper还支持逻辑运算符,如`and`、`or`,可以组合多个条件进行查询。例如: ```java queryWrapper.and(wrapper -&gt; wrapper.eq("name", "张三").or().eq("name", "李四")); ``` 这段代码将查询名字为"张三...

    用SpringBoot整合MyBatis实现登录注册功能

    这是SpringBoot整合MyBatis实现的简易登陆注册。这里所使用的开发环境是:IDEA、MySQL_8.0.17、Java8;其中用到了Druid数据库连接池。这个登录注册demo中,登录失败有两种情况:①账户不存在;②密码错误。注册失败...

    04实现mybatis条件构造器代码demo

    04实现mybatis条件构造器代码demo04实现mybatis条件构造器代码demo04实现mybatis条件构造器代码demo04实现mybatis条件构造器代码demo04实现mybatis条件构造器代码demo04实现mybatis条件构造器代码demo04实现mybatis...

Global site tag (gtag.js) - Google Analytics