Mybatis Plus中在XML文件中使用自定义的sql语句

## Mybatis Plus中使用自定义的sql语句

Mybatis Plus中在xml文件中手写sql语句,这个如同在Mybatis中写sql语句一样。但是由于Mybatis Plus进行了封装所以使用起来的配置稍微有所不同,一不小心容易踩坑:

* 首先确定Mybatis Plus的依赖:
 

        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.1</version>
        </dependency>

XML文件采用Mybatis Plus 推荐的放置位置,放在mapper包映射类下面的xml包下面,
接着需要在pom.xml文件中配置一下映射路径否则会报加载不到sql语句的异常:

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
        <resources>
            <!--不添加这句话就无法使用 xml编写sql语句-->
            <resource>
                <directory>src/main/resources</directory>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>

xml映射文件所在路径如图所示:

 

启动类配置包扫描:

@MapperScan("com.gec.hawaste.mapper")
@SpringBootApplication
public class HawasteApplication {

    public static void main(String[] args) {
        SpringApplication.run(HawasteApplication.class, args);
    }

}

接下来在yaml文件中配置mapper.xml文件的所在路径:
 

#此为默认值 表示删除的状态 配置可有可无
mybatis-plus:
  global-config:
    db-config:
      logic-not-delete-value: 0
  # Mybatis plus中使用sql语句 需要添加pom文件 和这里加上xml文件的路径声明
  mapper-locations: classpath*:/com/gec/hawaste/mapper/xml/*.xml

编写mapper接口:
 

IPage<QualificationDo> selectByCondition(IPage<QualificationDo> iPage,QualificationDo qualificationDo);

在xml映射文件中编写sql语句:

<select id="selectByCondition" parameterType="com.gec.hawaste.domain.QualificationDo" resultType="com.gec.hawaste.domain.QualificationDo">
        SELECT
            qu.*,
            su.NAME user_name,
            cu.NAME check_user_name
        FROM
            qualification qu
            LEFT JOIN sys_user su ON qu.upload_user_id = su.id
            LEFT JOIN sys_user cu ON qu.check_user_id = cu.id
        WHERE
            qu.del_flag = 0
            AND qu.type = #{qualificationDo.type}
            AND qu.CHECK = #{qualificationDo.check}
            <![CDATA[ AND DATE(qu.create_date) >= #{qualificationDo.startDate}
                        AND DATE(qu.create_date) <= #{qualificationDo.endDate} ]]>

    </select>


<![CDATA[ AND DATE(qu.create_date) >= #{qualificationDo.startDate}
                        AND DATE(qu.create_date) <= #{qualificationDo.endDate} ]]>
是为了解决xml文件中有无法直接使用 >  <的问题


在单元测试类中使用测试:

运行测试结果:

PageInfo(navigatePages=0, navigatepageNums=null, navigateFirstPage=0, navigateLastPage=0, prePage=0, nextPage=0, isFirstPage=false, isLastPage=false, hasPreviousPage=false, hasNextPage=false)
QualificationDo(super=Qualification(id=1, uploadUserId=2, type=3, address=/uploads/56/0B0DF1F02F804F048A623804EFB88741.png, check=0, description=null, checkUserId=null, createDate=2019-10-10T14:29:12, updateDate=2019-10-10T14:29:12, delFlag=0, createBy=2,超级管理员), userName=超级管理员, checkUserName=null, startDate=null, endDate=null)


 

### 原因 1. **配置问题**:MyBatis-Plus 的拦截器配置可能没有正确生效。如果拦截器没有被正确注册到 MyBatis-Plus 的配置中,那么自定义 SQL 语句就不会经过这些拦截器。例如在 Spring Boot 项目中,如果没有正确配置 `MybatisPlusInterceptor` 并将其添加到 `GlobalConfig` 中,拦截器就无法工作。 2. **SQL 解析问题**:MyBatis-Plus 的 `InnerInterceptor` 通常依赖于对 SQL 语句的解析来确定是否要执行拦截逻辑。如果自定义SQL 语句XML 文件使用了一些特殊的语法或者结构,导致 MyBatis-PlusSQL 解析器无法正确解析该 SQL,那么拦截器可能就不会处理这条 SQL 语句。 3. **拦截器规则限制**:`InnerInterceptor` 可能有自己的规则来决定是否对某条 SQL 进行拦截。例如,有些拦截器可能只对特定表或者特定类型的 SQL 语句(如 `SELECT`、`INSERT` 等)进行拦截,如果自定义 SQL 不符合这些规则,就不会被拦截。 ### 解决方案 1. **检查拦截器配置**:确保 `MybatisPlusInterceptor` 已经正确配置并注册到 MyBatis-Plus 中。以下是一个 Spring Boot 项目中的示例配置: ```java import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyBatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 添加具体的 InnerInterceptor,例如分页拦截器 interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; } } ``` 2. **检查 SQL 语法**:确保自定义 SQL 语句使用的是 MyBatis-Plus 能够解析的语法。避免使用过于复杂或者特殊的 SQL 结构。如果确实需要使用特殊语法,可以考虑对拦截器进行扩展,使其能够处理这些特殊情况。 3. **调整拦截器规则**:如果拦截器的规则限制导致自定义 SQL 不被拦截,可以根据实际需求调整拦截器的规则。例如,如果拦截器只对特定表进行拦截,可以修改拦截器的逻辑,使其对自定义 SQL 涉及的表也进行处理。以下是一个简单的自定义拦截器示例,用于处理所有 SQL 语句: ```java import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor; 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 = {java.sql.Connection.class, Integer.class}) }) public class CustomInnerInterceptor implements InnerInterceptor, Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { // 在这里添加自定义的拦截逻辑 return invocation.proceed(); } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { // 设置属性 } @Override public boolean willDoQuery(StatementHandler sh, Statement stmt) { return true; } @Override public boolean willDoUpdate(StatementHandler sh, Statement stmt) { return true; } } ``` 然后将这个自定义拦截器添加到 `MybatisPlusInterceptor` 中: ```java @Configuration public class MyBatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new CustomInnerInterceptor()); return interceptor; } } ```
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值