private static final String SQL = "SELECT * FROM table_name";
....
为了执行这个SQL查询,需要使用PreparedStatement。为什么呢?
据我所知,PreparedStatement需要花费时间来预编译SQL语句。但事实证明,Statement比PreparedStatement更快。或者我理解错了吗?
private static final String SQL = "SELECT * FROM table_name";
....
为了执行这个SQL查询,需要使用PreparedStatement。为什么呢?
据我所知,PreparedStatement需要花费时间来预编译SQL语句。但事实证明,Statement比PreparedStatement更快。或者我理解错了吗?
当需要多次运行相同语句但数据不同时,使用预编译语句可以极大提升速度。这是因为SQL仅会验证查询一次,而如果您只使用语句,则每次都要验证查询。
使用PreparedStatements的另一个好处是避免导致SQL注入漏洞 - 尽管在您的情况下,您的查询非常简单,您并没有遇到过这种问题。
对于您的查询,使用准备好的语句和语句之间的差异可能可以忽略不计。
编辑:回应您下面的评论,您需要仔细查看DAO类正在做什么。例如,如果每次调用该方法时它都重新创建了准备好的语句,那么您将失去使用准备好的语句的任何好处。
您想要实现的是封装持久层,使其无需特定调用MySQL或Postgres或您正在使用的其他数据库,并同时利用准备好的语句等性能和安全性优势。为此,您需要依赖Java自身的对象,如PreparedStatement。
我个人会构建自己的DAO类来执行CRUD操作,使用Hibernate作为基础框架和Java Persistence API来封装它,这样就可以利用准备好的语句获得安全性的好处。如果您有针对重复操作的特定用例,那么我倾向于将其包装在自己的对象中。
通过XML文件,Hibernate可以配置为使用您正在使用的任何数据库供应商,因此它提供了非常简洁的持久层封装。但是,这是一个相当复杂的产品!
大多数情况下,查询并不像你的示例那样简单。如果有任何查询变化,例如任何参数在编译时间未知,则必须使用PreparedStatement以避免SQL注入漏洞。这比任何性能考虑都更重要。 如果PreparedStatement和Statement之间有任何区别,那将高度依赖于具体的JDBC驱动程序,并且大多数时候惩罚与访问数据库、执行实际查询和获取结果的成本相比微不足道。
当我们不需要多次执行查询时,Statement接口是适合的。 Statement接口的缺点。黑客可以轻松地窃取数据。例如,假设我们有一个查询,其中用户名和密码是参数,您可以为用户名='abc@example.com'和密码='abc123'提供正确的参数,实际上这是当前的情况。但黑客可以做到用户名='abc@example.com'或'1'=1和密码='',这意味着您可以成功登录。所以这在Statement中是可能发生的。解析SQL查询。
编译此查询。
优化数据获取路径。
执行查询。