多个可选@requestparam在spring boot中不获取数据

fslejnso  于 2021-07-23  发布在  Java
关注(0)|答案(3)|浏览(577)

我想在springboot项目中对响应数据进行分页。根据业务逻辑,我添加了多个requestparam。如果我传递所有请求参数的值,即性别和国家,则一切正常。但如果我不给出一个或两个值,我会得到500个状态码,尽管我将gender和country requestparam作为可选的。意思是,
如果我击中
http://localhost:8080/api/v1/users?page=1&country=russia&gender=m,
我得到了分页的回应。
但如果我打了
http://localhost:8080/api/v1/users?page=1&gender=m
http://localhost:8080/api/v1/users?page=1&country=俄罗斯
http://localhost:8080/api/v1/users?第1页。
我有例外
这是我的密码。 UserRepository.kt ```
@Repository
interface UserRepository: JpaRepository<User, Long> {

@Query(
    nativeQuery = true,
    value = "SELECT * FROM user_info WHERE gender =:gender AND country =:country"
)
fun getUsers(gender: String?, country: String?, pageable: Pageable): Page<User>

}
`UserServiceImpl.kt`
@Service
class UserServiceImpl(
@Autowired private val userRepository: UserRepository
): UserService {

override fun getUsers(gender: String?, country: String?, pageable: Pageable): Page<User> {
    return userRepository.getUsers(gender, country, pageable)
}

}
`UserController.kt`
@RestController
@RequestMapping(
path = [
"/api/v1/"
]
)
class UserController(
@Autowired private val userService: UserService
) {

@GetMapping("users")
fun getUsers(
    @RequestParam(required = true) page: Int,
    @RequestParam(required = false) gender: String?,
    @RequestParam(required = false) country: String?
): Page<User> {
    return userService.getUsers(gender, country, PageRequest.of(page, 10))
}

}
`response`
{
"status": "500 INTERNAL_SERVER_ERROR",
"message": "Internal server error occurs",
"error": "could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet"
}

sqserrrh

sqserrrh1#

在这里最好使用jdbctemplate,如下所示:

String query = "SELECT * FROM user_info WHERE gender = :gender AND country = :country";
Map<String, Object> params = new HashMap<>();
params.put("gender", gender);
params.put("country", country);
Map<String, Long> results = new HashMap<>();
// Execute Your Query Here like: users = jdbcTemplate.query(query, params, ...

对于thos参数,您可以检查例如gender not null append gender=:gender to main query。

juzqafwq

juzqafwq2#

是的,您得到的错误是正确的,因为您的查询值不存在,我建议您进行以下更改。。。

@Repository
interface UserRepository: JpaRepository<User, Long> {

@Query(
    nativeQuery = true,
    value = "SELECT * FROM user_info WHERE country =:country"
)
fun getUsersWithoutGender( country: String?, pageable: Pageable): Page<User>

 @Query(
    nativeQuery = true,
    value = "SELECT * FROM user_info WHERE gender =:gender AND country =:country"
)
fun getUsersWithoutCountry(gender: String?, pageable: Pageable): Page<User>

 @Query(
    nativeQuery = true,
    value = "SELECT * FROM user_info WHERE gender =:gender AND country =:country"
)
fun getUsers(gender: String?, country: String?, pageable: Pageable): Page<User>

@Query(
    nativeQuery = true,
    value = "SELECT * FROM user_info"
)
fun getallUsers(): Page<User>

}

在你的控制器里

RestController
@RequestMapping(
path = [
    "/api/v1/"
]
)
class UserController(
@Autowired private val userService: UserService
) {

@GetMapping("users")
fun getUsers(
    @RequestParam(required = true) page: Int,
    @RequestParam(required = false) gender: String?,
    @RequestParam(required = false) country: String?
): Page<User> {

if(country == null && gender =! null){
    return userService.getUsersWithoutCountry(gender,PageRequest.of(page, 10))
} else if (gender== null && country =! null){
    return userService.getUsersWithoutGender(country,PageRequest.of(page, 10))
}else if (gender && country == null){
    return userService.getAllUsers()
}else {
    return userService.getUsers(gender, country, PageRequest.of(page, 10))    
}
}

}

这样,所有查询都将运行,因为它们没有空值。

uqxowvwt

uqxowvwt3#

最后,我用jpaspecificationexecutor解决了这个问题,它有助于创建动态查询。代码如下。 UserSpecification.kt ```
import com.example.demo.entity.User
import org.springframework.data.jpa.domain.Specification
import javax.persistence.criteria.CriteriaBuilder
import javax.persistence.criteria.CriteriaQuery
import javax.persistence.criteria.Root
import java.text.MessageFormat.format

object UserSpecification {

fun countryContains(country: String?): Specification<User>? {
    return country?.let {
        Specification { root: Root<User>, _: CriteriaQuery<*>, criteriaBuilder: CriteriaBuilder ->
            criteriaBuilder.like(root.get("country"), format("%{0}%", country))
        }
    }
}

fun genderContains(gender: String?): Specification<User>? {
    return gender?.let {
        Specification { root: Root<User>, _: CriteriaQuery<*>, criteriaBuilder: CriteriaBuilder ->
            criteriaBuilder.equal(root.get<String>("gender"), gender)
        }
    }
}

}
`UserRepository.kt`
@Repository
interface UserRepository: JpaRepository<User, Long>, JpaSpecificationExecutor {

}
`UserServiceImpl.kt`
@Service
class UserServiceImpl(
@Autowired private val userRepository: UserRepository
): UserService {

override fun getUsers(gender: String?, country: String?, pageable: Pageable): Page<User> {
    return userRepository.findAll(
        where(
            countryContains(country)
        ).and(
            genderContains(gender)
        ), pageable
    )
}

}

相关问题