java中的动态sql查询

gc0ot86w  于 2021-06-21  发布在  Mysql
关注(0)|答案(5)|浏览(367)

我有一个函数

public void executeMyQuery(Connection con) {
    PreparedStatement ps = con.prepareStatement("SELECT * FROM STUDENT WHERE ID = ?");
    ps.setInt(1, 7);
    ps.executeQuery();
}

如果我运行这个,它会工作得很好。但我想这样做。
如果我要设置它应该包括where子句(返回匹配行)
如果我不设置int,它应该排除where子句(返回整个表)
或者是否有任何方法可以动态删除或修改where子句后面的字符串。

wtzytmuj

wtzytmuj1#

您必须动态构建查询,在方法开始时检查 idnull 或同等 0 . 为了方便起见,可以在where子句中使用技巧 1=1 所以where子句可以一直包含在查询中。

public void executeMyQuery( Connection con, Integer id) {
String query = "SELECT *FROM STUDENT WHERE 1=1";
if(id != null){
   query += "AND ID = ?";
}
PreparedStatement ps = con.prepareStatement(query);

if(id != null){
   ps.setInt(1, id);
}
ps.executeQuery();}
ylamdve6

ylamdve62#

michaeldz在他的答案中接近于解决方案,但是代码中有一个问题:他在一个不存在的preparedstatement上调用setint。
尝试以下操作:

public void executeMyQuery( Connection con, int Id) {
    StringBuffer sql = new StringBuffer();
    sql.append("Select * FROM STUDENT");
    if(Id > -1) {
        sql.append(" Where ID = ?");
    }
    preparedStatement ps = con.prepareStatement(sql.toString());
    if(ID > -1) {
        ps.setInt(1, Id);
    }
    ps.executeQuery();   // You might want to catch the result of the query as well
}

希望这有帮助!

bwleehnv

bwleehnv3#

您可以在程序中定义两个preparedstatement—一个没有 WHERE ID = ? 条款,还有另外一个。
此外,你应该保持 PreparedStatements 并且可以重复使用,所以你最好把它们存储为一个字段,等等。
然后,当需要获取数据时,可以调用第一个准备好的语句,也可以调用第二个语句。

ztyzrc3y

ztyzrc3y4#

动态sql使用基于字符串的sql的缺点

其他答案展示了如何使用基于字符串的jdbc实现动态sql。使用字符串串联动态构建sql字符串有许多缺点,包括:
如果意外地将用户输入连接到sql查询,则sql注入的风险很高
当动态sql变得更复杂时,在非平凡的情况下很难避免语法错误
另外,当您使用纯jdbc(只支持索引绑定变量)而不是springjdbctemplate、mybatis、jooq等实用程序时,您必须手动匹配 ? 占位符及其相应的索引,这是另一个微妙的错误来源。

使用查询生成器

在某种程度上,当您更频繁地实现动态sql查询时,查询生成器肯定会有所帮助。最流行的是:
jooq(用于动态sql查询)
jpa条件查询(用于动态jpal查询)
有许多其他的选择,或多或少都是维护良好。对于非常简单的情况(如您的问题中的情况),您还可以构建自己的简单 predicate 生成器。
免责声明:我为jooq背后的公司工作。

bxgwgixi

bxgwgixi5#

如果null/coalesce对此工作得很好,那么如果传递null,它将选择字段等于自身的位置。

SELECT * 
FROM STUDENT 
WHERE 1 = 1
and ID = ifNull(:ID, ID)

我也建议你用别的什么?对于你的变量,当你有两个变量的时候很好,但是当你有很多变量的时候,很难跟踪或者修改。我找到了https://github.com/dejlek/jlib/blob/master/src/main/java/com/areen/jlib/sql/namedparameterstatement.java 很简单,做了一些修改以满足我的特殊需要,但是sql更容易阅读,在intellijdb控制台中进行替换在开发sql时更容易。

相关问题