在 Java 中使用准备好的语句更改语句
Change statement with prepared statement in Java
我创建了使用语句插入数据库的方法。
我必须用准备好的陈述来改变它。我看过文档,但我没看懂。
这是我写的代码:
public void ajouterEntreprise(Entreprise e) {
Statement stm;
try {
stm = cnx.createStatement();
String query = "INSERT INTO `user`(`nom`, `email`, `password`, `tel`,`role`,`offre`) VALUES ('" + e.getNom() + "','" + e.getEmail() + "','" + e.getPassword() + "','" + e.getTel() + " ', " + e.getRole().getId() + ",'" + e.getOffre() + "')";
stm.executeUpdate(query);
} catch (SQLException ex) {
Logger.getLogger(ServiceEntreprise.class.getName()).log(Level.SEVERE, null, ex);
}
}
您当前的代码不安全,因为您将值连接到查询字符串中。这会使您的代码容易受到 SQL 注入的攻击。为了解决这个问题,您需要切换到准备好的语句,在语句文本中使用参数占位符,然后在执行前在语句上设置值。
使用准备好的语句的一个例子是(为简洁起见省略了一些列):
try (PreparedStatement pstmt = cnx.prepareStatement(
"INSERT INTO `user`(`nom`, `email`, ...) values (?, ?, ...)")) {
pstmt.setString(1, e.getNom());
pstmt.setString(2, e.getEmail());
// ...
pstmt.executeUpdate();
}
你可以这样做
String sql= "INSERT INTO `user`(`nom`, `email`) VALUES (?,?)";
ps = conn.PreparedStatement(sql);
ps.setString(1, "admin");
ps.setString(2, "123456@email.com");
ps.executeUpdate();
这是因为一般的SQL都会经过多个步骤,这里涉及的两个步骤是:编译,执行。
当SQL处于编译阶段时,会根据语法树解析生成SQL,例如
select * from table where name = 'jhon';
这个SQL经过一个完整的编译阶段会生成一个select语句,下一个例子,会生成两个SQL,一个是select语句,另一个是删除语句。
select * from table where name = 'jhon'; delete from table where '1' = '1'
//will be parsed into two sql
1.select * from table where name = 'jhon';
2.delete from table where '1' = '1'
但是都可以通过下面的方式填写SQL
select * from table where name ='%s';
很明显,第一个sql是通过jhon替换%s得到的,第二个sql是通过jhon得到的' ;从 table 中删除 '1' = '1 替换 %s
使用ss预编译会有什么不同sql?其中最notable的一点就是sql不会再进行语法分析和编译,只会进行字符串替换。比如第二个sql预编译填充后就变成了
select * from table where name = 'jhon'; delete from table where '1' = '1'
jhon'; delete from table where '1' = '1作为name
的查询条件
我创建了使用语句插入数据库的方法。 我必须用准备好的陈述来改变它。我看过文档,但我没看懂。
这是我写的代码:
public void ajouterEntreprise(Entreprise e) {
Statement stm;
try {
stm = cnx.createStatement();
String query = "INSERT INTO `user`(`nom`, `email`, `password`, `tel`,`role`,`offre`) VALUES ('" + e.getNom() + "','" + e.getEmail() + "','" + e.getPassword() + "','" + e.getTel() + " ', " + e.getRole().getId() + ",'" + e.getOffre() + "')";
stm.executeUpdate(query);
} catch (SQLException ex) {
Logger.getLogger(ServiceEntreprise.class.getName()).log(Level.SEVERE, null, ex);
}
}
您当前的代码不安全,因为您将值连接到查询字符串中。这会使您的代码容易受到 SQL 注入的攻击。为了解决这个问题,您需要切换到准备好的语句,在语句文本中使用参数占位符,然后在执行前在语句上设置值。
使用准备好的语句的一个例子是(为简洁起见省略了一些列):
try (PreparedStatement pstmt = cnx.prepareStatement(
"INSERT INTO `user`(`nom`, `email`, ...) values (?, ?, ...)")) {
pstmt.setString(1, e.getNom());
pstmt.setString(2, e.getEmail());
// ...
pstmt.executeUpdate();
}
你可以这样做
String sql= "INSERT INTO `user`(`nom`, `email`) VALUES (?,?)";
ps = conn.PreparedStatement(sql);
ps.setString(1, "admin");
ps.setString(2, "123456@email.com");
ps.executeUpdate();
这是因为一般的SQL都会经过多个步骤,这里涉及的两个步骤是:编译,执行。 当SQL处于编译阶段时,会根据语法树解析生成SQL,例如
select * from table where name = 'jhon';
这个SQL经过一个完整的编译阶段会生成一个select语句,下一个例子,会生成两个SQL,一个是select语句,另一个是删除语句。
select * from table where name = 'jhon'; delete from table where '1' = '1'
//will be parsed into two sql
1.select * from table where name = 'jhon';
2.delete from table where '1' = '1'
但是都可以通过下面的方式填写SQL
select * from table where name ='%s';
很明显,第一个sql是通过jhon替换%s得到的,第二个sql是通过jhon得到的' ;从 table 中删除 '1' = '1 替换 %s
使用ss预编译会有什么不同sql?其中最notable的一点就是sql不会再进行语法分析和编译,只会进行字符串替换。比如第二个sql预编译填充后就变成了
select * from table where name = 'jhon'; delete from table where '1' = '1'
jhon'; delete from table where '1' = '1作为name
的查询条件