在mybatis 的@Select注解中使用<script>导致的报错问题

本文介绍了在MyBatis的@Select注解中遇到的SQL语句解析错误,问题源于SQL中的小于号(<)与XML语法冲突。通过将小于号替换为<解决了该问题,使得程序能够正常启动并执行SQL。修复后的代码示例也一并给出。
摘要由CSDN通过智能技术生成

原代码如下如下

  @Select({"<script>SELECT " +
      "IFNULL( sum( CASE WHEN dispose_type = 1 THEN 1 ELSE 0 END ), 0 ) AS misinformation, " +
      "IFNULL( sum( CASE WHEN dispose_type = 2 THEN 1 ELSE 0 END ), 0 ) AS fault, " +
      "IFNULL( sum( CASE WHEN dispose_type = 3 THEN 1 ELSE 0 END ), 0 ) AS alarm, " +
      "IFNULL( sum( CASE WHEN dispose_type = 4 THEN 1 ELSE 0 END ), 0 ) AS others  " +
      "FROM device_event " +
      "WHERE   event_dispose_status = 1   " +
      "and DATE_SUB(CURDATE(), INTERVAL ${period} DAY) <= date(ts) " +
      "  and device_id in (select id from device where org = #{org}  " +
      "<if test = 'subSystem!=null'> and device_system_type=#{subSystem} </if>); </script>"})
  EventDisposeTypeStatisticsVM getDevcieHisEventStatBySubSystemAndPeriod(@Param("subSystem") Long subSystem,@Param("period") Long period,@Param("org") Long org);

使用的是mybatis 的@Select注解执行sql。代码执行时报以下错误。

因为要增加一个subSystem的子判断条件,所以在原sql基础上增加了<script> </script>标志。

结果一执行,代码就报错,程序启动不了,各种百度也找不到原因,因为整个语句看起来没有错。在其他地方也使用了相同写法,并没有报错出现。

主要报错信息如下。

ringframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'deviceEventService': Unsatisfied dependency expressed through field 'baseMapper'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'deviceEventMapper' defined in file [D:\code\zhxf012\build\classes\java\main\com\rydit\business\event\mapper\DeviceEventMapper.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: org.apache.ibatis.builder.BuilderException: Error creating document instance.  Cause: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 428; 元素内容必须由格式正确的字符数据或标记组成。
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]

后来发现<script>的作用是将整个sql语句转换为mybatis 中 xml中的写法,sql中不能存在  大于<   或者 小于>符号,这种符号会被认为是中括号的一部分。从而导致sql解析错误。而我的sql语句中有一个<= 判断条件。

将源代码中的   < 改为 &lt;即可。

      "and DATE_SUB(CURDATE(), INTERVAL ${period} DAY) <= date(ts) " 

主要修改的代码如下。

      "and DATE_SUB(CURDATE(), INTERVAL ${period} DAY) &lt;= date(ts) "

最终正确执行SQL代码如下:

@Select({"<script>SELECT " +
      "IFNULL( sum( CASE WHEN dispose_type = 1 THEN 1 ELSE 0 END ), 0 ) AS misinformation, " +
      "IFNULL( sum( CASE WHEN dispose_type = 2 THEN 1 ELSE 0 END ), 0 ) AS fault, " +
      "IFNULL( sum( CASE WHEN dispose_type = 3 THEN 1 ELSE 0 END ), 0 ) AS alarm, " +
      "IFNULL( sum( CASE WHEN dispose_type = 4 THEN 1 ELSE 0 END ), 0 ) AS others  " +
      "FROM device_event " +
      "WHERE   event_dispose_status = 1   " +
      "and DATE_SUB(CURDATE(), INTERVAL ${period} DAY) &lt;= date(ts) " +
      "  and device_id in (select id from device where org = #{org}  " +
      "<if test = 'subSystem!=null'> and device_system_type=#{subSystem} </if>); </script>"})
  EventDisposeTypeStatisticsVM getDevcieHisEventStatBySubSystemAndPeriod(@Param("subSystem") Long subSystem,@Param("period") Long period,@Param("org") Long org);

参考资料:Error creating document instance. Cause: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber - jiduoduo - 博客园在写mysql的sql语句时,会用到>=或者<= 那么<=这个会被解析为xml的语法 (org.xml.sax.SAXParseException) 这样就会报错。 解决: &https://www.cnblogs.com/jiduoduo/p/14729050.html

好的,我来为你演示一下如何运用 Spring Boot 框架实现用户登录案例。 首先,在 pom.xml 文件添加以下依赖: ```xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.3</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.25</version> </dependency> </dependencies> ``` 其,`spring-boot-starter-web` 用于支持 Web 应用程序的开发,`mybatis-spring-boot-starter` 用于支持 MyBatis 框架的使用,`mysql-connector-java` 用于连接 MySQL 数据库。 接下来,在 application.properties 文件添加数据库连接配置: ```properties spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver mybatis.mapper-locations=classpath:mapper/*.xml ``` 其,`spring.datasource.url` 指定数据库的 URL,`spring.datasource.username` 和 `spring.datasource.password` 分别指定数据库的用户名和密码,`mybatis.mapper-locations` 指定 MyBatis 的 Mapper 文件所在的路径。 接着,创建一个 User 实体类,使用 `@Data` 注解自动生成 Getter 和 Setter 方法: ```java @Data public class User { private Integer id; private String username; private String password; } ``` 然后,创建一个 `UserMapper` 接口,用于定义数据库操作方法: ```java @Mapper public interface UserMapper { User selectByUsername(String username); } ``` 在这里,我们使用了 `@Mapper` 注解来标记这是一个 MyBatis 的 Mapper 接口,并定义了一个 `selectByUsername` 方法,用于根据用户名查询用户信息。 接下来,创建一个 `UserMapper.xml` 文件,用于定义 SQL 语句: ```xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.example.demo.mapper.UserMapper"> <select id="selectByUsername" resultType="com.example.demo.entity.User"> SELECT * FROM user WHERE username = #{username} </select> </mapper> ``` 在这里,我们定义了一个 `selectByUsername` 查询语句,返回值类型为 `com.example.demo.entity.User`。 接着,创建一个 `UserService` 接口,用于定义用户登录方法: ```java public interface UserService { User login(String username, String password); } ``` 然后,创建一个 `UserServiceImpl` 类,实现 `UserService` 接口: ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public User login(String username, String password) { User user = userMapper.selectByUsername(username); if (user != null && user.getPassword().equals(password)) { return user; } return null; } } ``` 在这里,我们使用了 `@Service` 注解来标记这是一个服务类,使用 `@Autowired` 注解来自动注入 `UserMapper` 对象,并实现了 `login` 方法,用于验证用户登录信息是否正确。 最后,创建一个 `LoginController` 类,用于处理登录请求: ```java @Controller public class LoginController { @Autowired private UserService userService; @PostMapping("/login") @ResponseBody public String login(String username, String password) { User user = userService.login(username, password); if (user != null) { return "登录成功"; } else { return "用户名或密码错误"; } } } ``` 在这里,我们使用了 `@Controller` 注解来标记这是一个控制器类,使用 `@Autowired` 注解来自动注入 `UserService` 对象,并定义了一个 `login` 方法,用于处理登录请求。通过 `@PostMapping` 注解来指定该方法只接受 POST 请求,并使用 `@ResponseBody` 注解将返回值转换为 JSON 格式。 现在,我们已经完成了用户登录案例的实现,可以通过访问 `http://localhost:8080/login` 来进行登录操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值