环境:r2dbc + postgresql
这样的一个简单的需求,根据type查询数据,如果type参数值=null或者type= “”,就查出所有的数据
以前用mybatis是这样写的:
<if test="type != null">
and a.type = #{type}
</if>
这样,如果type=null,出来的sql就是 select * from a;否则就是 select * from a where a.type=5;
现在看很多文章之后,写成这样:
@Query("select a.* from sys a where if(?1 !='',a.type=?1,1=1),nativeQuery = true")
public Mono<SysEntity> getSysByType(String type);
运行之后,报错如下:
2022-03-14 17:46:33.324 DEBUG 4284 --- [actor-tcp-nio-2] a.w.r.e.AbstractErrorWebExceptionHandler : [176dafae-4, L:/0:0:0:0:0:0:0:1:8700 - R:/0:0:0:0:0:0:0:1:6049] Resolved [UnsupportedOperationException: Binding parameters is not supported for the statement 'select a.* from sys a where if(?1 !='',a.type=?1,1=1),nativeQuery = true'] for HTTP GET /sys/byType
2022-03-14 17:46:33.326 ERROR 4284 --- [actor-tcp-nio-2] a.w.r.e.AbstractErrorWebExceptionHandler : [176dafae-4, L:/0:0:0:0:0:0:0:1:8700 - R:/0:0:0:0:0:0:0:1:6049] 500 Server Error for HTTP GET "/sys/byType"
java.lang.UnsupportedOperationException: Binding parameters is not supported for the statement 'select a.* from sys a where if(?1 !='',a.type=?1,1=1),nativeQuery = true'
at io.r2dbc.postgresql.SimpleQueryPostgresqlStatement.bind(SimpleQueryPostgresqlStatement.java:69) ~[r2dbc-postgresql-0.8.1.RELEASE.jar:0.8.1.RELEASE]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
*__checkpoint ? Handler com.jundax.fluxwk.sys.controller.SysTaskController#getSysTaskByType(String) [DispatcherHandler]
*__checkpoint ? HTTP GET "/sys/byType" [ExceptionHandlingWebHandler]
Stack trace:
at io.r2dbc.postgresql.SimpleQueryPostgresqlStatement.bind(SimpleQueryPostgresqlStatement.java:69) ~[r2dbc-postgresql-0.8.1.RELEASE.jar:0.8.1.RELEASE]
at io.r2dbc.postgresql.SimpleQueryPostgresqlStatement.bind(SimpleQueryPostgresqlStatement.java:39) ~[r2dbc-postgresql-0.8.1.RELEASE.jar:0.8.1.RELEASE]
at org.springframework.r2dbc.core.DefaultDatabaseClient$DefaultGenericExecuteSpec.lambda$bindByIndex$6(DefaultDatabaseClient.java:442) ~[spring-r2dbc-5.3.12.jar:5.3.12]
我尝试改成
@Query(value = "select a.* from sys a where a.type=(:type or :type iss null ", nativeQuery = true)
依然是报错
请教,这里应该怎么写?
谢谢
不同数据库及不同版本的函数可能会存在一点差异,常见的一般就是用nvl 或者coalesce函数来处理,比如
where coalesce(传入的查询参数,表里的字段)=表里的字段
由于null和空字符串在不同数据库里存在不一样的情况,所以下面这种方式更为通用
where (case when ?='' or ? is null then a.type else ? end) =a.type
这个查询条件,我直接在数据库里测试是没有问题的,传null或者传非null都可以正常输出结果
而且现在又有新问题出来,不知怎的,启动服务时候,不停地报
022-03-14 19:58:18.219 DEBUG 8760 --- [)-172.17.140.17] sun.rmi.loader : RMI TCP Connection(1)-172.17.140.17: name = "javax.management.ObjectName", codebase = ""
2022-03-14 19:58:18.264 DEBUG 8760 --- [)-172.17.140.17] javax.management.remote.rmi : connectionId=rmi://172.17.140.17 93, name=org.springframework.boot:type=Admin,name=SpringApplication, attribute=Ready
2022-03-14 19:58:18.353 DEBUG 8760 --- [)-172.17.140.17] sun.rmi.server.call : RMI TCP Connection(1)-172.17.140.17: [172.17.140.17] exception:
javax.management.InstanceNotFoundException: org.springframework.boot:type=Admin,name=SpringApplication
at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getMBean(DefaultMBeanServerInterceptor.java:1083) ~[na:na]
at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getAttribute(DefaultMBeanServerInterceptor.java:637) ~[na:na]
at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.getAttribute(JmxMBeanServer.java:678) ~[na:na]
at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1443) ~[na:na]
at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1307) ~[na:na]
at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1399) ~[na:na]
at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.getAttribute(RMIConnectionImpl.java:637) ~[na:na]
at java.base/jdk.internal.reflect.GeneratedMethodAccessor24.invoke(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
这种错误,我查了下,都说把IDEA的“enable jmx agent”勾选掉就可以了
解释说
“You can see this exception when the log level is in TRACE Or DEGUG. There is always some time lag between RMI TCP server start and spring boot tomcat start up . RMI TCP will start first and it will try to find SpringApplication Insatance which is started latter. till that time RMI TCP server will poll to find this SpringApplication instance .Once it finds SpringApplication instance this error is gone and Auto Configuration of spring boot starts .”
但是我勾掉之后,服务倒是没报错,但是springdoc干脆起不来了