com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:您的SQL语法中有错误;查看与您的MySQL服务器版本对应的手册,以便在' @ gmail.com'附近使用正确的语法。在第1行
我不知道问题在哪里
public List<UserModel> listUser(String emailParam) throws SQLException {
List<UserModel> users = new ArrayList<>();
Connection conn = null;
PreparedStatement pre = null;
ResultSet rs = null;
// Get Connection
conn = dataSource.getConnection();
// fetch query
String fetchUser = "SELECT * FROM user WHERE email = " + emailParam;
pre = conn.prepareStatement(fetchUser);
// execute query
rs = pre.executeQuery();
// fetch data using resultSet interface;
while (rs.next()) {
Integer id = rs.getInt("id");
String firstName = rs.getString("firstName");
...
String email = rs.getString("email");
Boolean isActive = rs.getBoolean("isActive");
Boolean isLibrarian = rs.getBoolean("isLibrarian");
// insert into user constructor
UserModel theUser = new UserModel(id, firstName, lastName, gender,
department, idNo, contactNo, address, email, null,
isLibrarian, isActive);
// insert into ArrayList
users.add(theUser);
}
// close connection
close(conn, pre, rs);
return users;
}
问题在哪里提前谢谢。
答案 0 :(得分:2)
错误发生在AssertionError: 16 columns passed, passed data had 18 columns
:
listUser()
您在插入用户时设法使用预准备语句,并且在查询时需要执行相同的操作:
// fetch query
String fetchUser = "SELECT * FROM user WHERE email = " + emailParam;
pre = conn.prepareStatement(fetchUser);
答案 1 :(得分:2)
总的来说,准备陈述有两个主要用法: 1)最小化执行查询时的准备时间 2)为了安全 - 除其他外“查询重写”
我还对本文底部的选择中的语法错误进行了观察。
如果您要准备语句,那么最好先做一次,然后“记住”您获得的preparedStatement。不要一遍又一遍地准备相同的查询。
对于准备好的查询处理,大多数(如果不是全部)DBMS的工作如下: 1)将模板查询发送到DBMS进行解析和优化。这个的输出可以通过几个不同的名称来识别,但出于此目的,我们可以将其称为“可执行计划”。这是PrepareXXX电话。 2)DBMS会记住第二阶段的所有细节,即当您通过prepdQuery.executeQuery()(或类似)调用发送数据时。这具有发送数据并将其插入准备好的查询的可执行计划的效果。
这将始终涉及两次网络旅行(一次准备,一次执行)。但是....
...如果您需要使用不同的数据(例如,不同的电子邮件)再次运行相同的查询,只需执行第二步 - 这将绕过与解析和计划相关的开销。这将显着提高您的吞吐量 - 特别是对于单行操作,例如上面显示的插入(很可能是选择)。
替代方法是字符串连接方法,它总是需要解析等和执行 - 但至少它只能通过网络进行一次。这适用于运行时间较长的查询(解析时间与执行时间相比无关紧要)或查询逻辑是动态的(根据用户输入在运行时组成)。
但是,如果您确实发送了与用户输入连接的查询文本,请确保解决上面的第2点(查询重写)。
此外,最后,您的连锁SQL缺少单引号。 查询必须如下所示(必须引用文本) select ... from ... where email ='email@domain.com';
因此,您的连接必须如下所示: String fetchUser =“SELECT * FROM user WHERE email ='”+ emailParam +“'”;
什么是查询重写?如果用户输入的emailParam看起来像这样: emailParam =“';从用户全部删除;选择'你好' 尝试将其插入您的选择但不要运行它,除非您有用户表的备份副本(或者您很幸运)。 另外,请注意,你从不在周围放置引号?准备好的查询中的占位符 - 即使参数是文本或日期值。