Mybatis自定义Sql

本文介绍了在处理复杂业务逻辑和大量数据时,如何利用Mybatis的@SelectProvider注解自定义SQL,避免XML方式的不便。通过示例代码详细讲解了自定义SQL的注解使用方法,包括为何不推荐使用XML,@SelectProvider的参数配置,以及注意事项,如子查询的正确使用,SQL拼接的效率和避免错误的方法。同时,强调了实践和结合业务解决问题的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:近日遇到很复杂的业务逻辑需要处理(每每这个时候博主经常吐槽自己脑子不够用了?),数据库查询需要通过不同业务不同条件进行动态拼接,而且涉及数据量巨大,表也关联的多,这时候明显xml不适合这个场景,虽然说可以做到,但是麻烦程度绝对大于我接下来的做法,然后不经意间发现下面这种写法,发现Mybatis挺灵活的。有①xml方式(常用)、②普通注解(@Select、@Insert等),③高级注解(@SelectProvider、@InsertProvider等)④SQL语句构建器类http://www.mybatis.org/mybatis-3/zh/statement-builders.html
…还有其它的方式等我去研究发现嘿嘿,言归正传。

假设需求根据给出的条件(此条件不固定),然后关联几张表,给我查出我需要的字段(视图)。看似很简单的需求,实则深似海哈哈哈

下面贴出代码(看不太懂的,下面有解释说明)

/**
* 根据移库规则表检查该数据是否可自动生成任务
*
* @param warehouseTransferRuleConfig
* @return
*/
@SelectProvider(type = WarehouseTransferRuleConfigMapperProvider.class, method = "canAutoCreateSourceDetailList")
List<SourceDetail> canAutoCreateSourceDetailList(WarehouseTransferRuleConfig warehouseTransferRuleConfig,String deviceTypeCodeById,String specById);

class WarehouseTransferRuleConfigMapperProvider {
   

   /**
    * 用于复杂sql查询提供sql拼接
    *
    * @param
    * @return
    */
   public String canAutoCreateSourceDetailList(WarehouseTransferRuleConfig warehouseTransferRuleConfig,String deviceTypeCodeById,String specById) {
   
       //根据规则表数据拼接查询一机一档的sql

       StringBuilder sql = new StringBuilder("select material_number,vehicle_vin_number,device_code,device_type_code,bl_division_code,region_code,device_model_code,device_spec_code,depositary_officer,storage_area,storage_province,storage_city,storage_address,placement_note,dispose_status,first_handover_date,handover_address_type from(select material_number,vehicle_vin_number,device_code,device_type_code,bl_division_code,region_code,device_model_code,device_spec_code,depositary_officer,storage_area,storage_province,storage_city,storage_address,placement_note,dispose_status,first_handover_date,handover_address_type from rmp_source_detail s where first_handover_status='Y' and depositary_officer is not null and handover_address_type is not null and bl_division_code is not null and device_spec_code is not null and dispose_status='01' and is_active='Y'");
       if (warehouseTransferRuleConfig != null) {
   
           //当前日期-定价日期>7
           sql.append(" and to_days(now()) - to_days(device_pricing_date)>7");
           //设备规格
           if (StringUtils.isNotBlank(specById)) {
   
               String specStr="";
               String[] split = specById.split(",");
               for (int i = 0; i < split.length; i++) {
   
                   specStr=specStr+"'"+split[i]+"',";
               }
               specStr=specStr+specStr.substring(0,specStr.length()-1);
               sql.append(" and device_spec_code in(" + specStr + ")");
           }
           //如未配置设备规格,则以设备类型为条件
           if (StringUtils.isBlank(specById)) {
   
               String deviceTypeCodeSql="(select ds.device_type_code from(select device_type_code from rmp_warehouse_transfer_spec_config where id="+
### 创建和使用 MyBatis 自定义 SQL 拦截器 #### 实现原理 MyBatis 提供了插件机制来允许开发者创建自定义拦截器。这些拦截器可以用于拦截执行器(Executor)、参数处理(ParameterHandler)、结果集处理(ResultHandler)以及语句处理器(StatementHandler)[^1]。 为了实现一个自定义拦截器,需要编写一个类并使其继承 `Interceptor` 接口,在该接口中重写 `intercept()` 方法以加入想要执行的额外逻辑。此外还需要配置此拦截器以便它能够被 MyBatis 使用。 #### 示例代码 下面是一个简单的例子展示如何创建一个日志记录拦截器: ```java import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.plugin.*; import java.sql.Statement; import java.util.Properties; @Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}) }) public class LoggingInterceptor implements Interceptor { public Object intercept(Invocation invocation) throws Throwable { System.out.println("Before preparing statement..."); try { Object result = invocation.proceed(); System.out.println("After preparing statement."); return result; } catch (Throwable t) { System.err.println("Error while preparing statement: " + t.getMessage()); throw t; } } public Object plugin(Object target) { return Plugin.wrap(target, this); } public void setProperties(Properties properties) {} } ``` 这段代码展示了如何通过覆盖 `intercept()` 函数来自定义行为,并利用 `plugin()` 和 `setProperties()` 来完成必要的初始化工作。 要使这个拦截器生效,则需将其注册到 MyBatis 配置文件中的 `<plugins>` 节点下: ```xml <configuration> <!-- ... --> <plugins> <plugin interceptor="com.example.LoggingInterceptor"/> </plugins> <!-- ... --> </configuration> ``` 以上就是关于在 MyBatis 中创建和使用自定义 SQL 拦截器的方法介绍及其背后的实现原理说明。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值