Postgresql Micronaut jdbc动态查询

Postgresql Micronaut jdbc动态查询,postgresql,jdbc,micronaut,Postgresql,Jdbc,Micronaut,我正在尝试为我的查询添加一个动态过滤器。我已经检查过过滤器本身的语法是否正确 我的代码是: @Repository @JdbcRepository(dialect = Dialect.POSTGRES) interface RoomRepository extends JpaRepository<Room, Long> { @Query(SELECT * FROM person pereson_ WHERE :filter) Page<Person&g

我正在尝试为我的查询添加一个动态过滤器。我已经检查过过滤器本身的语法是否正确

我的代码是:

@Repository
@JdbcRepository(dialect = Dialect.POSTGRES)
interface RoomRepository extends JpaRepository<Room, Long> {
    
    @Query(SELECT * FROM person pereson_ WHERE :filter)
    Page<Person> searchPerson(String filter, Pageable pageable)
}

有什么想法吗?

它不是那样工作的,顺便说一句,它的风格非常糟糕,因为它使您不易接受sql注入

首先创建一些过滤器类:

data class Filter( val name: String, val value: String)
您可以将过滤器拆分为多个存储库函数,并根据设置的过滤器从服务中调用它们

@Repository
@JdbcRepository(dialect = Dialect.POSTGRES)
interface PersonRepo : PageableRepository<Person, Long> {
     findByName(name: String, pageable: Pageable): Page<Person>
     findByNameAndAgeGreaterThanEquals(name: String, age: Int, pageable: Pageable): Page<Person>
     // add some more filter methods 
}

@Singleton
class PersonService(private val repo: PersonRepo) {

  fun searchPerson(filter: List<Filter>, pageable: Pageable) : Page<Person> {
     val filters = filter.map{it.name to it.value}.toMap()
     val isNamePresent = filters.containsKey("name")
     val isAgePresent = filter.containsKey("age")
     return if(isNamePresent && !isAgePresent) {
        repo.findByName(filters["name]!!.value, pageable)
     } else if(isNamePresent && isAgePresent) {
        repo.findByNameAndAgeGreaterThanEquals(filters["name]!!.value, filters["age]!!.value, pageable)
     } else {
         Page.empty()
     }
  }
}
@存储库
@JdbcRepository(方言=方言.POSTGRES)
接口PersonRepo:PageableRepository{
findByName(名称:字符串,可分页:可分页):第页
findByNameAndAgeGreaterThanEquals(名称:String,年龄:Int,可分页:可分页):第页
//添加更多的过滤方法
}
@独生子女
类PersonService(私有val repo:PersonRepo){
有趣的搜索人(过滤器:列表,可分页:可分页):页面{
val filters=filter.map{it.name to it.value}.toMap()
val isNamePresent=filters.containsKey(“名称”)
val isAgePresent=filter.containsKey(“年龄”)
返回if(isNamePresent&!isAgePresent){
repo.findByName(过滤器[“名称]!!.value,可分页)
}else if(isNamePresent&&isAgePresent){
repo.findByNameAndAgeGreaterThanEquals(过滤器[“名称]!!.value,过滤器[“年龄]!!.value,可分页)
}否则{
Page.empty()
}
}
}
或者动态创建sql

@Repository
@JdbcRepository(dialect = Dialect.POSTGRES)
abstract class PersonRepo(private val jdbcOperations: JdbcOperations) : PageableRepository<Person, Long>{

    override fun searchPerson(filter: List<Filter>, pageable: Pageable): Page<Person> {

        val countSql= "SELECT COUNT(*) FROM person AS p ${filter.joinToString(" and ", "WHERE "){it.name + "= ?"}}"
        val totalAmount = jdbcOperations.prepareStatement(sql) { statement ->
            filter.forEachIndexed { i, v -> statement.setString(i+1, v.value) }
            val resultSet = statement.executeQuery()
            jdbcOperations.entityStream(resultSet, Long::class.java).findFirst().orElseGet { 0}
        }

        val sql= "SELECT * FROM person AS p ${filter.joinToString(" and ", "WHERE "){it.name + "= ?"}} SKIP ${pageable.offset} LIMIT {pageable.size}"
        val result = jdbcOperations.prepareStatement(sql) { statement ->
            filter.forEachIndexed { i, v -> statement.setString(i+1, v.value) }
            val resultSet = statement.executeQuery()
            jdbcOperations.entityStream(resultSet, Person::class.java).toList()
        }
        return Page.of(result,pageable, totalAmount)
    }
}
@存储库
@JdbcRepository(方言=方言.POSTGRES)
抽象类PersonRepo(私有val jdbcOperations:jdbcOperations):PageableRepository{
覆盖有趣的searchPerson(筛选器:列表,可分页:可分页):页面{
val countSql=“从person中选择COUNT(*)作为p${filter.joinToString(“and”,“WHERE”){it.name+“=?”}”
val totalAmount=jdbcOperations.prepareStatement(sql){语句->
filter.forachined{i,v->statement.setString(i+1,v.value)}
val resultSet=statement.executeQuery()
entityStream(resultSet,Long::class.java).findFirst().OrelSetGet{0}
}
val sql=“从person中选择*作为p${filter.joinToString(“and”,“WHERE”){it.name+“=?”}跳过${pageable.offset}限制{pageable.size}”
val result=jdbcOperations.prepareStatement(sql){语句->
filter.forachined{i,v->statement.setString(i+1,v.value)}
val resultSet=statement.executeQuery()
entityStream(resultSet,Person::class.java).toList()
}
返回第页,共页(结果、可分页、总金额)
}
}

pereson_
person_
相比?这似乎是正确的选择,但就我的一生而言,我似乎无法将jdbcOperations实例注入我的存储库。为什么不能?是否有任何错误?我就这个问题发表了一篇单独的帖子,
@Repository
@JdbcRepository(dialect = Dialect.POSTGRES)
abstract class PersonRepo(private val jdbcOperations: JdbcOperations) : PageableRepository<Person, Long>{

    override fun searchPerson(filter: List<Filter>, pageable: Pageable): Page<Person> {

        val countSql= "SELECT COUNT(*) FROM person AS p ${filter.joinToString(" and ", "WHERE "){it.name + "= ?"}}"
        val totalAmount = jdbcOperations.prepareStatement(sql) { statement ->
            filter.forEachIndexed { i, v -> statement.setString(i+1, v.value) }
            val resultSet = statement.executeQuery()
            jdbcOperations.entityStream(resultSet, Long::class.java).findFirst().orElseGet { 0}
        }

        val sql= "SELECT * FROM person AS p ${filter.joinToString(" and ", "WHERE "){it.name + "= ?"}} SKIP ${pageable.offset} LIMIT {pageable.size}"
        val result = jdbcOperations.prepareStatement(sql) { statement ->
            filter.forEachIndexed { i, v -> statement.setString(i+1, v.value) }
            val resultSet = statement.executeQuery()
            jdbcOperations.entityStream(resultSet, Person::class.java).toList()
        }
        return Page.of(result,pageable, totalAmount)
    }
}