Java Spring JDBComany
我收到以下错误,这表明我没有在结果集上调用Java Spring JDBComany,java,spring,spring-jdbc,jdbctemplate,Java,Spring,Spring Jdbc,Jdbctemplate,我收到以下错误,这表明我没有在结果集上调用next(),但我看到的是(即调试断点在rs.next()上停止并按预期填充) Servlet[dispatcherServlet]在具有路径的上下文中的Servlet.service() []引发异常[请求处理失败;嵌套异常为 org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback;SQL的未分类SQLException[选择 m、 用户名、m.pass
next()
,但我看到的是(即调试断点在rs.next()
上停止并按预期填充)
Servlet[dispatcherServlet]在具有路径的上下文中的Servlet.service()
[]引发异常[请求处理失败;嵌套异常为
org.springframework.jdbc.UncategorizedSQLException:
PreparedStatementCallback;SQL的未分类SQLException[选择
m、 用户名、m.password、t.name作为成员的权限m JOIN
a.member\u id=m.member\u id加入管理员
t、 admin_type_id=a.admin_type_id,其中m.username=?];SQL状态
[24000];错误代码[0];结果集可能未正确定位
您需要调用next。;嵌套异常为
org.postgresql.util.PSQLException:结果集未正确定位,
也许你需要打电话给下一个。]根本原因
org.postgresql.util.PSQLException:结果集未正确定位,
也许你下次需要打电话
代码
SQL
结果
在您的代码中:
while (rs.next()) {
String authority = rs.getString("authority");
roles.add( new SimpleGrantedAuthority(authority));
}
User user = new User(rs.getString("username"), rs.getString("password"), roles);
return user;
您正在while循环之外调用rs.getString
,因此即使rs.next()
不为真,也有可能是这样。但更重要的是,当您打破循环时,rs.next()
已返回false,因此您的get
将不再工作。您没有提到在哪一行抛出异常,但我认为这是最可能的原因
在获取权限时,您应该随时填充用户信息,例如在第一行。但不要等到您已经处理了所有行
例如:
public User extractData(ResultSet rs) throws SQLException, DataAccessException {
Collection<SimpleGrantedAuthority> roles = new ArrayList<>();
User user = null;
while (rs.next()) {
if (user == null) {
user = new User(rs.getString("username"), rs.getString("password"), roles);
}
String authority = rs.getString("authority");
roles.add( new SimpleGrantedAuthority(authority));
}
if (user == null) {
throw new MyException("User not found");
}
return user;
}
public User extractData(ResultSet rs)抛出SQLException、DataAccessException{
集合角色=新的ArrayList();
User=null;
while(rs.next()){
if(user==null){
用户=新用户(rs.getString(“用户名”)、rs.getString(“密码”)、角色);
}
字符串权限=rs.getString(“权限”);
添加(新的SimpleGrantedAuthority(authority));
}
if(user==null){
抛出新的MyException(“未找到用户”);
}
返回用户;
}
或者,对于这种样板代码,只需使用Hibernate之类的框架即可。另一种方法是:
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
return ofNullable(userName)
.map(u -> namedParameterJdbcTemplate.query(
"SELECT m.username, m.password, t.name as authority " +
"FROM members m " +
"JOIN administrator a ON a.member_id = m.member_id " +
"JOIN admin_type t ON t.admin_type_id = a.admin_type_id " +
"WHERE m.username = :username",
Map.of("username", userName),
UserMapper.userWithRolesResultExtractor)
)
.orElseThrow(() -> new UsernameNotFoundException(
format("Given username: %s does not exist in database", username)));
}
在另一个类中创建以下映射器(以重用它):
@UtilityClass
公共类用户映射器{
公共静态最终结果文本提取器userWithRolesResultExtractor=(结果集)->{
User=null;
while(resultSet.next()){
if(resultSet.isFirst()){
user=新用户(resultSet.getString(“用户名”),
resultSet.getString(“密码”)
新HashSet());
}
user.getRoles().add(新的SimpleGrantedAuthority(rs.getString(“authority”)));
}
返回用户;
};
}
正如Sebastiaan所提到的,有几种ORM可以帮助您编写更少的代码,但性能较差
警察局。在我的示例中,我使用了Set
而不是List
来避免重复
while (rs.next()) {
String authority = rs.getString("authority");
roles.add( new SimpleGrantedAuthority(authority));
}
User user = new User(rs.getString("username"), rs.getString("password"), roles);
return user;
public User extractData(ResultSet rs) throws SQLException, DataAccessException {
Collection<SimpleGrantedAuthority> roles = new ArrayList<>();
User user = null;
while (rs.next()) {
if (user == null) {
user = new User(rs.getString("username"), rs.getString("password"), roles);
}
String authority = rs.getString("authority");
roles.add( new SimpleGrantedAuthority(authority));
}
if (user == null) {
throw new MyException("User not found");
}
return user;
}
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
return ofNullable(userName)
.map(u -> namedParameterJdbcTemplate.query(
"SELECT m.username, m.password, t.name as authority " +
"FROM members m " +
"JOIN administrator a ON a.member_id = m.member_id " +
"JOIN admin_type t ON t.admin_type_id = a.admin_type_id " +
"WHERE m.username = :username",
Map.of("username", userName),
UserMapper.userWithRolesResultExtractor)
)
.orElseThrow(() -> new UsernameNotFoundException(
format("Given username: %s does not exist in database", username)));
}
@UtilityClass
public class UserMapper {
public static final ResultSetExtractor<User> userWithRolesResultExtractor = (resultSet) -> {
User user = null;
while (resultSet.next()) {
if (resultSet.isFirst()) {
user = new User(resultSet.getString("username"),
resultSet.getString("password")
new HashSet<>());
}
user.getRoles().add(new SimpleGrantedAuthority(rs.getString("authority"))));
}
return user;
};
}