Java- select 使用 SQLite 的列中的某些行
Java- select certain rows from column with SQLite
抱歉,如果标题不准确。
我正在使用自定义 class 从 SQLite 数据库中获取数据。
例如:
下面的方法应该是 return 用户列表,这些用户是某个部门的成员。
USER table 中的每个用户都有一列,其中包含他所属部门的 ID。
目前我正在获取所有用户,然后将他们的部门 ID 与我要查找的部门的 targetID 进行比较。
有没有办法只获取具有特定部门 ID 的一组用户,这样我就不必检查每个人的部门 ID?
private List<User> getDepartmentMembers(int targetID) {
List<User> members = new ArrayList<User>();
Connection c = null;
Statement statement = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:TheatroData.sqlite");
c.setAutoCommit(false);
statement = c.createStatement();
ResultSet rs = statement.executeQuery( "SELECT * FROM USERS;" );
while ( rs.next() ) {
int id = rs.getInt(Constants.ID_KEY);
if (id == targetID ){
User tmp = null;
int position = rs.getInt(Constants.POSITION_KEY);
if (position == Constants.DEPARTMENT_HEAD)
tmp = new DepartmentHead();
else if (position == Constants.DEPARTMENT_MANAGER)
tmp = new DepartmentManager();
else if (position == Constants.DEPARTMENT_MEMBER);
tmp = new GruntUser();
tmp.setID(id);
tmp.setName(rs.getString(Constants.NAME_KEY));
tmp.setPosition(position);
tmp.setUsername(rs.getString(Constants.USERNAME_KEY));
tmp.setLastname(rs.getString(Constants.SURNAME_KEY));
tmp.setDepartment(targetID);
tmp.setPassword(rs.getString(Constants.PASS_KEY));
members.add(tmp);
}
}
rs.close();
statement.close();
c.close();
} catch ( Exception e ) {
System.err.println( e + " -in getDepartmentMembers" + e.getClass().getName() + ": " + e.getMessage());
}
return members;
}
我在想我需要这样的东西:
ResultSet rs = statement.executeQuery( "SELECT * FROM USERS where department = ?;", targetID );
我只是传递了一个错误的陈述。正确方法:
ResultSet rs = statement.executeQuery( "SELECT * FROM USERS where department = "+targetID+";");
是的,您实际上回答了您自己的问题。你也可以这样做。
String query = "SELECT * FROM USERS where department = (?)";
PreparedStatement statement = c.prepareStatement(sql);
statement.setInt(1, targetId);
ResultSet rs = statement.executeQuery();
while(rs.next()){
//you get only records that have id = targetId
}
//close rs, statement and connection!!!
在理想的世界里,你可以像你写的那样做:
ResultSet rs = statement.executeQuery( "SELECT * FROM USERS WHERE department = ?;", targetID );
但是,来自 JDBC 的 executeQuery 当前不提供参数绑定的可能性。所以你必须使用 "Prepared Statements".
而不是
statement = c.createStatement();
ResultSet rs = statement.executeQuery( "SELECT * FROM USERS;" );
做:
prepared = c.prepareStatement("SELECT * FROM USERS WHERE department = ?;");
prepared.setString(1, targetID);
ResultSet rs = prepared.executeQuery();
当您需要多个参数时,您可以使用不同的语法来替换它,例如“?001”。参见 SQLite Documentation: C/C++ Interface 第 5 节。
同时删除 Java 编码以供您自己选择正确的部门。
由于 CluelessStudent 提出了不同的解决方案,涉及字符串连接,我想说以下内容:
I would definitively discourage string concatenation! You always
should use argument binding and not string concatenation! String
concatenation is a huge security risk, since it can be used for so
called "SQL injection attacks". See Wikipedia: SQL Injection
抱歉,如果标题不准确。 我正在使用自定义 class 从 SQLite 数据库中获取数据。
例如: 下面的方法应该是 return 用户列表,这些用户是某个部门的成员。 USER table 中的每个用户都有一列,其中包含他所属部门的 ID。
目前我正在获取所有用户,然后将他们的部门 ID 与我要查找的部门的 targetID 进行比较。 有没有办法只获取具有特定部门 ID 的一组用户,这样我就不必检查每个人的部门 ID?
private List<User> getDepartmentMembers(int targetID) {
List<User> members = new ArrayList<User>();
Connection c = null;
Statement statement = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:TheatroData.sqlite");
c.setAutoCommit(false);
statement = c.createStatement();
ResultSet rs = statement.executeQuery( "SELECT * FROM USERS;" );
while ( rs.next() ) {
int id = rs.getInt(Constants.ID_KEY);
if (id == targetID ){
User tmp = null;
int position = rs.getInt(Constants.POSITION_KEY);
if (position == Constants.DEPARTMENT_HEAD)
tmp = new DepartmentHead();
else if (position == Constants.DEPARTMENT_MANAGER)
tmp = new DepartmentManager();
else if (position == Constants.DEPARTMENT_MEMBER);
tmp = new GruntUser();
tmp.setID(id);
tmp.setName(rs.getString(Constants.NAME_KEY));
tmp.setPosition(position);
tmp.setUsername(rs.getString(Constants.USERNAME_KEY));
tmp.setLastname(rs.getString(Constants.SURNAME_KEY));
tmp.setDepartment(targetID);
tmp.setPassword(rs.getString(Constants.PASS_KEY));
members.add(tmp);
}
}
rs.close();
statement.close();
c.close();
} catch ( Exception e ) {
System.err.println( e + " -in getDepartmentMembers" + e.getClass().getName() + ": " + e.getMessage());
}
return members;
}
我在想我需要这样的东西:
ResultSet rs = statement.executeQuery( "SELECT * FROM USERS where department = ?;", targetID );
我只是传递了一个错误的陈述。正确方法:
ResultSet rs = statement.executeQuery( "SELECT * FROM USERS where department = "+targetID+";");
是的,您实际上回答了您自己的问题。你也可以这样做。
String query = "SELECT * FROM USERS where department = (?)";
PreparedStatement statement = c.prepareStatement(sql);
statement.setInt(1, targetId);
ResultSet rs = statement.executeQuery();
while(rs.next()){
//you get only records that have id = targetId
}
//close rs, statement and connection!!!
在理想的世界里,你可以像你写的那样做:
ResultSet rs = statement.executeQuery( "SELECT * FROM USERS WHERE department = ?;", targetID );
但是,来自 JDBC 的 executeQuery 当前不提供参数绑定的可能性。所以你必须使用 "Prepared Statements".
而不是
statement = c.createStatement();
ResultSet rs = statement.executeQuery( "SELECT * FROM USERS;" );
做:
prepared = c.prepareStatement("SELECT * FROM USERS WHERE department = ?;");
prepared.setString(1, targetID);
ResultSet rs = prepared.executeQuery();
当您需要多个参数时,您可以使用不同的语法来替换它,例如“?001”。参见 SQLite Documentation: C/C++ Interface 第 5 节。
同时删除 Java 编码以供您自己选择正确的部门。
由于 CluelessStudent 提出了不同的解决方案,涉及字符串连接,我想说以下内容:
I would definitively discourage string concatenation! You always should use argument binding and not string concatenation! String concatenation is a huge security risk, since it can be used for so called "SQL injection attacks". See Wikipedia: SQL Injection