jdbc 的sql语句怎么写多条件查询

时间:2023-01-31 02:54:52
有个表 有id age name sex class等字段 
想做个jdbc的多条件查询 这些条件可以为空也可以不为空
简单的页面像这样:
jdbc 的sql语句怎么写多条件查询

用传统的
ps = con.prepareStatement(sql);
ps.setString(1, name);
这种方法 好像不行
求大大们指点啊 jdbc 的sql语句怎么写多条件查询

28 个解决方案

#1


。。jdbc不是注入sql语句吗。自己and不就好?

#2


为啥不行?是你的 sql 没写好吧?把SQL贴完整点看看。

#3


可以的啊,还有注意你的变量类型。ps.setString(1, name);age可能是int的就不能用setString了。其他应该没什么问题

#4


利用到了一个小技巧

就是  where 1=1  永为真


select * from 表  where 1=1

然后在根据传递过来的值是否有  在动态拼接成一个完整的sql

最后类似这样


select * from 表  where 1=1 and  字段1 = 'xx'  and 字段2='yy'


#5


引用 1 楼 zengfuqing 的回复:
。。jdbc不是注入sql语句吗。自己and不就好?


引用 2 楼 ldh911 的回复:
为啥不行?是你的 sql 没写好吧?把SQL贴完整点看看。


比如说有时候就输入id  
那sql就是  
 select * from student t where t.id=?

那有时候会 输入 age 和 name 
sql又变成
select * from student t where t.name=? and t.age=?
 
如果用stringbuffer的话

 Stringbuffer  sql="select * from student t ";
if( 字段中至少有一个不为空或者""){
 sql.append(" where ");
}
if(id != null|| !"".equale(id)){
 sql.append(" t.id=?");
}
if(name!=null || !"".equale(name)){
 sql.append( " t.name=? ");
}
....
ps = con.prepareStatement(sql);
    ps.setString(1, id);
....

这个的setString 就无法确定了

#6


判断也可以解决嘛。。

#7


引用 6 楼 zengfuqing 的回复:
判断也可以解决嘛。。


其实我是想问有没有这种

  sql.append(" name=?").setString(name);

这种类 或者方法的东西

#8


你的问题是可变参数的SQL组装。

这个要么就借助数据访问组件,比如Hibernate、MyBatis之类的;要么就只能自己写分支条件来处理。

另外如果是确定使用某种数据库(比如Oracle),或者使用了支持NamedParameterStatement,可以这样:

import oracle.jdbc.OraclePreparedStatement; // 这个是Oracle数据库的驱动才提供的

        String sql = "Select * From employees Where 1=1 And (:pName IS null OR first_name = :pName) And (:pSalary IS null OR salary = :pSalary)"; // 注意这句YD的SQL
        Connection con = openConnection(); // 数据库连接获取略
        OraclePreparedStatement stat = (OraclePreparedStatement) con.prepareStatement(sql); 
        stat.setObjectAtName("pName", null);
        stat.setObjectAtName("pSalary", 2500);
        ResultSet rs = stat.executeQuery();
        int cols = rs.getMetaData().getColumnCount();
        while (rs.next()) {
            for (int i = 1; i <= cols; i++) {
                System.out.print(rs.getString(i) + "\t");
            }
            System.out.println();
        }

不过总的来说还是建议老老实实用成熟的数据访问组件。

#9


引用 8 楼 ldh911 的回复:
你的问题是可变参数的SQL组装。

这个要么就借助数据访问组件,比如Hibernate、MyBatis之类的;要么就只能自己写分支条件来处理。

另外如果是确定使用某种数据库(比如Oracle),或者使用了支持NamedParameterStatement,可以这样:

import oracle.jdbc.OraclePreparedStatement; // 这个是Oracle数据库的驱动才提供的

        String sql = "Select * From employees Where 1=1 And (:pName IS null OR first_name = :pName) And (:pSalary IS null OR salary = :pSalary)"; // 注意这句YD的SQL
        Connection con = openConnection(); // 数据库连接获取略
        OraclePreparedStatement stat = (OraclePreparedStatement) con.prepareStatement(sql); 
        stat.setObjectAtName("pName", null);
        stat.setObjectAtName("pSalary", 2500);
        ResultSet rs = stat.executeQuery();
        int cols = rs.getMetaData().getColumnCount();
        while (rs.next()) {
            for (int i = 1; i <= cols; i++) {
                System.out.print(rs.getString(i) + "\t");
            }
            System.out.println();
        }

不过总的来说还是建议老老实实用成熟的数据访问组件。

额...   用的就是oracl 的数据库 
(:pName IS null OR first_name = :pName)
这句是说 如果pName为null的话 就略过了吗?

#10


判断然后拼装。

#11


引用 8 楼 ldh911 的回复:
你的问题是可变参数的SQL组装。

这个要么就借助数据访问组件,比如Hibernate、MyBatis之类的;要么就只能自己写分支条件来处理。

另外如果是确定使用某种数据库(比如Oracle),或者使用了支持NamedParameterStatement,可以这样:

import oracle.jdbc.OraclePreparedStatement; // 这个是Oracle数据库的驱动才提供的

        String sql = "Select * From employees Where 1=1 And (:pName IS null OR first_name = :pName) And (:pSalary IS null OR salary = :pSalary)"; // 注意这句YD的SQL
        Connection con = openConnection(); // 数据库连接获取略
        OraclePreparedStatement stat = (OraclePreparedStatement) con.prepareStatement(sql); 
        stat.setObjectAtName("pName", null);
        stat.setObjectAtName("pSalary", 2500);
        ResultSet rs = stat.executeQuery();
        int cols = rs.getMetaData().getColumnCount();
        while (rs.next()) {
            for (int i = 1; i <= cols; i++) {
                System.out.print(rs.getString(i) + "\t");
            }
            System.out.println();
        }

不过总的来说还是建议老老实实用成熟的数据访问组件。


按照你提供的模板写了一个 可是运行起来报了org.apache.commons.dbcp.DelegatingPreparedStatement cannot be cast to oracle.jdbc.OraclePreparedStatement 这个错误  求指导 这个该怎么转换呢?

   con=dataSource.getConnection();
ops=(OraclePreparedStatement) con.prepareStatement(FINDPANA);


 spring的配置
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:8080:test"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</bean>

大大 求指点一下啊 jdbc 的sql语句怎么写多条件查询

#12


你用了数据库连接池,所以类型被重新包装了;还是老老实实用数据访问组件安全。

试试看:
ops = (OraclePreparedStatement) con.prepareStatement(FINDPANA).getInnermostDelegate();

#13


引用 12 楼 ldh911 的回复:
你用了数据库连接池,所以类型被重新包装了;还是老老实实用数据访问组件安全。

试试看:
ops = (OraclePreparedStatement) con.prepareStatement(FINDPANA).getInnermostDelegate();

早上好! 早上试了一下 你说的方法  提示了The method getInnermostDelegate() is undefined for the type PreparedStatement 这个错误... 弱弱地再问一下这个方法是哪个类的啊?

#14


如果是写在sql语句里面的话,用or连接写条件,判断为空,为空字符串,和应匹配的字符串相不相等!

#15


引用 14 楼 ganshenml 的回复:
如果是写在sql语句里面的话,用or连接写条件,判断为空,为空字符串,和应匹配的字符串相不相等!
用or的话结果出来的和预想的就不一样了

#16


jdbc 的sql语句怎么写多条件查询 先验证你要查询的条件是否为空 。不空就直接拼接上去。空就不拼接 。。

#17


引用 15 楼 u011434924 的回复:
Quote: 引用 14 楼 ganshenml 的回复:

如果是写在sql语句里面的话,用or连接写条件,判断为空,为空字符串,和应匹配的字符串相不相等!
用or的话结果出来的和预想的就不一样了

(a is null or a='' or a=字段)为什么不可以呢?

#18


引用 17 楼 ganshenml 的回复:
Quote: 引用 15 楼 u011434924 的回复:

Quote: 引用 14 楼 ganshenml 的回复:

如果是写在sql语句里面的话,用or连接写条件,判断为空,为空字符串,和应匹配的字符串相不相等!
用or的话结果出来的和预想的就不一样了

(a is null or a='' or a=字段)为什么不可以呢?

不好意思 我理解错了  我以为你是说把原来的and 改成 or

#19


引用 18 楼 u011434924 的回复:
Quote: 引用 17 楼 ganshenml 的回复:

Quote: 引用 15 楼 u011434924 的回复:

Quote: 引用 14 楼 ganshenml 的回复:

如果是写在sql语句里面的话,用or连接写条件,判断为空,为空字符串,和应匹配的字符串相不相等!
用or的话结果出来的和预想的就不一样了

(a is null or a='' or a=字段)为什么不可以呢?

不好意思 我理解错了  我以为你是说把原来的and 改成 or
没事,慢慢弄就明白了!

#20


引用 13 楼 u011434924 的回复:
早上好! 早上试了一下 你说的方法  提示了The method getInnermostDelegate() is undefined for the type PreparedStatement 这个错误... 弱弱地再问一下这个方法是哪个类的啊?


apache DBCP 组件的方法:
http://commons.apache.org/proper/commons-dbcp/apidocs/org/apache/commons/dbcp/managed/ManagedConnection.html

本意是申请从连接池所管理的Connection中,获取到原生的 PreparedStatement 实现类(也即是Oracle所提供的)。

#21


引用 20 楼 ldh911 的回复:
Quote: 引用 13 楼 u011434924 的回复:

早上好! 早上试了一下 你说的方法  提示了The method getInnermostDelegate() is undefined for the type PreparedStatement 这个错误... 弱弱地再问一下这个方法是哪个类的啊?


apache DBCP 组件的方法:
http://commons.apache.org/proper/commons-dbcp/apidocs/org/apache/commons/dbcp/managed/ManagedConnection.html

本意是申请从连接池所管理的Connection中,获取到原生的 PreparedStatement 实现类(也即是Oracle所提供的)。


jdbc 的sql语句怎么写多条件查询
是不是包版本太低了啊... 找不到你说的这个类...

#22


引用 21 楼 u011434924 的回复:
jdbc 的sql语句怎么写多条件查询
是不是包版本太低了啊... 找不到你说的这个类...


俺只能表示:I don't known...

#23


引用 22 楼 ldh911 的回复:
Quote: 引用 21 楼 u011434924 的回复:

jdbc 的sql语句怎么写多条件查询
是不是包版本太低了啊... 找不到你说的这个类...


俺只能表示:I don't known...

 
DelegatingConnection con= (DelegatingConnection) dataSource.getConnection();
OraclePreparedStatement ps= (OraclePreparedStatement) con.getInnermostDelegate().prepareStatement(FINDPANA);

这样子写竟然会报 nullpointException   还是在prepareStatement(FINDPANA)这个方法的时候报的错误... 

#24


一个传参费这么大的劲?

Stringbuffer  sql="select * from student t ";
if( 字段中至少有一个不为空或者""){
 sql.append(" where ");
 list.add(val1);
}
if(id != null|| !"".equale(id)){
 sql.append(" t.id=?");
 list.add(val2);
}
if(name!=null || !"".equale(name)){
 sql.append( " t.name=? ");
 list.add(val3);
}
....
ps = con.prepareStatement(sql);
for (...list...){
    ps.setString(i, list.get(i));
}
....

#25


获取提交表单数据的值,判断提交的值为不为null如果不为null那么就and连接否则不连接

#26


遇到一样的问题,在线等。

#27


创建个list 比如

List<object> param = new ArrayList<Object>();
if(id != null|| !"".equale(id)){
 sql.append(" t.id=?");
 param.add(id);
}

最后设置参数的时候

for(int i =0; i < param.size(); i ++) {
  ps.setString(i + 1, param.get(i));
}

#28




引用 24 楼 forgetsam 的回复:
一个传参费这么大的劲?

Stringbuffer  sql="select * from student t ";
if( 字段中至少有一个不为空或者""){
 sql.append(" where ");
 list.add(val1);
}
if(id != null|| !"".equale(id)){
 sql.append(" t.id=?");
 list.add(val2);
}
if(name!=null || !"".equale(name)){
 sql.append( " t.name=? ");
 list.add(val3);
}
....
ps = con.prepareStatement(sql);
for (...list...){
    ps.setString(i, list.get(i));
}
....


引用 22 楼 ldh911 的回复:
Quote: 引用 21 楼 u011434924 的回复:

jdbc 的sql语句怎么写多条件查询
是不是包版本太低了啊... 找不到你说的这个类...


俺只能表示:I don't known...



非常感谢大家  

#1


。。jdbc不是注入sql语句吗。自己and不就好?

#2


为啥不行?是你的 sql 没写好吧?把SQL贴完整点看看。

#3


可以的啊,还有注意你的变量类型。ps.setString(1, name);age可能是int的就不能用setString了。其他应该没什么问题

#4


利用到了一个小技巧

就是  where 1=1  永为真


select * from 表  where 1=1

然后在根据传递过来的值是否有  在动态拼接成一个完整的sql

最后类似这样


select * from 表  where 1=1 and  字段1 = 'xx'  and 字段2='yy'


#5


引用 1 楼 zengfuqing 的回复:
。。jdbc不是注入sql语句吗。自己and不就好?


引用 2 楼 ldh911 的回复:
为啥不行?是你的 sql 没写好吧?把SQL贴完整点看看。


比如说有时候就输入id  
那sql就是  
 select * from student t where t.id=?

那有时候会 输入 age 和 name 
sql又变成
select * from student t where t.name=? and t.age=?
 
如果用stringbuffer的话

 Stringbuffer  sql="select * from student t ";
if( 字段中至少有一个不为空或者""){
 sql.append(" where ");
}
if(id != null|| !"".equale(id)){
 sql.append(" t.id=?");
}
if(name!=null || !"".equale(name)){
 sql.append( " t.name=? ");
}
....
ps = con.prepareStatement(sql);
    ps.setString(1, id);
....

这个的setString 就无法确定了

#6


判断也可以解决嘛。。

#7


引用 6 楼 zengfuqing 的回复:
判断也可以解决嘛。。


其实我是想问有没有这种

  sql.append(" name=?").setString(name);

这种类 或者方法的东西

#8


你的问题是可变参数的SQL组装。

这个要么就借助数据访问组件,比如Hibernate、MyBatis之类的;要么就只能自己写分支条件来处理。

另外如果是确定使用某种数据库(比如Oracle),或者使用了支持NamedParameterStatement,可以这样:

import oracle.jdbc.OraclePreparedStatement; // 这个是Oracle数据库的驱动才提供的

        String sql = "Select * From employees Where 1=1 And (:pName IS null OR first_name = :pName) And (:pSalary IS null OR salary = :pSalary)"; // 注意这句YD的SQL
        Connection con = openConnection(); // 数据库连接获取略
        OraclePreparedStatement stat = (OraclePreparedStatement) con.prepareStatement(sql); 
        stat.setObjectAtName("pName", null);
        stat.setObjectAtName("pSalary", 2500);
        ResultSet rs = stat.executeQuery();
        int cols = rs.getMetaData().getColumnCount();
        while (rs.next()) {
            for (int i = 1; i <= cols; i++) {
                System.out.print(rs.getString(i) + "\t");
            }
            System.out.println();
        }

不过总的来说还是建议老老实实用成熟的数据访问组件。

#9


引用 8 楼 ldh911 的回复:
你的问题是可变参数的SQL组装。

这个要么就借助数据访问组件,比如Hibernate、MyBatis之类的;要么就只能自己写分支条件来处理。

另外如果是确定使用某种数据库(比如Oracle),或者使用了支持NamedParameterStatement,可以这样:

import oracle.jdbc.OraclePreparedStatement; // 这个是Oracle数据库的驱动才提供的

        String sql = "Select * From employees Where 1=1 And (:pName IS null OR first_name = :pName) And (:pSalary IS null OR salary = :pSalary)"; // 注意这句YD的SQL
        Connection con = openConnection(); // 数据库连接获取略
        OraclePreparedStatement stat = (OraclePreparedStatement) con.prepareStatement(sql); 
        stat.setObjectAtName("pName", null);
        stat.setObjectAtName("pSalary", 2500);
        ResultSet rs = stat.executeQuery();
        int cols = rs.getMetaData().getColumnCount();
        while (rs.next()) {
            for (int i = 1; i <= cols; i++) {
                System.out.print(rs.getString(i) + "\t");
            }
            System.out.println();
        }

不过总的来说还是建议老老实实用成熟的数据访问组件。

额...   用的就是oracl 的数据库 
(:pName IS null OR first_name = :pName)
这句是说 如果pName为null的话 就略过了吗?

#10


判断然后拼装。

#11


引用 8 楼 ldh911 的回复:
你的问题是可变参数的SQL组装。

这个要么就借助数据访问组件,比如Hibernate、MyBatis之类的;要么就只能自己写分支条件来处理。

另外如果是确定使用某种数据库(比如Oracle),或者使用了支持NamedParameterStatement,可以这样:

import oracle.jdbc.OraclePreparedStatement; // 这个是Oracle数据库的驱动才提供的

        String sql = "Select * From employees Where 1=1 And (:pName IS null OR first_name = :pName) And (:pSalary IS null OR salary = :pSalary)"; // 注意这句YD的SQL
        Connection con = openConnection(); // 数据库连接获取略
        OraclePreparedStatement stat = (OraclePreparedStatement) con.prepareStatement(sql); 
        stat.setObjectAtName("pName", null);
        stat.setObjectAtName("pSalary", 2500);
        ResultSet rs = stat.executeQuery();
        int cols = rs.getMetaData().getColumnCount();
        while (rs.next()) {
            for (int i = 1; i <= cols; i++) {
                System.out.print(rs.getString(i) + "\t");
            }
            System.out.println();
        }

不过总的来说还是建议老老实实用成熟的数据访问组件。


按照你提供的模板写了一个 可是运行起来报了org.apache.commons.dbcp.DelegatingPreparedStatement cannot be cast to oracle.jdbc.OraclePreparedStatement 这个错误  求指导 这个该怎么转换呢?

   con=dataSource.getConnection();
ops=(OraclePreparedStatement) con.prepareStatement(FINDPANA);


 spring的配置
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:8080:test"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</bean>

大大 求指点一下啊 jdbc 的sql语句怎么写多条件查询

#12


你用了数据库连接池,所以类型被重新包装了;还是老老实实用数据访问组件安全。

试试看:
ops = (OraclePreparedStatement) con.prepareStatement(FINDPANA).getInnermostDelegate();

#13


引用 12 楼 ldh911 的回复:
你用了数据库连接池,所以类型被重新包装了;还是老老实实用数据访问组件安全。

试试看:
ops = (OraclePreparedStatement) con.prepareStatement(FINDPANA).getInnermostDelegate();

早上好! 早上试了一下 你说的方法  提示了The method getInnermostDelegate() is undefined for the type PreparedStatement 这个错误... 弱弱地再问一下这个方法是哪个类的啊?

#14


如果是写在sql语句里面的话,用or连接写条件,判断为空,为空字符串,和应匹配的字符串相不相等!

#15


引用 14 楼 ganshenml 的回复:
如果是写在sql语句里面的话,用or连接写条件,判断为空,为空字符串,和应匹配的字符串相不相等!
用or的话结果出来的和预想的就不一样了

#16


jdbc 的sql语句怎么写多条件查询 先验证你要查询的条件是否为空 。不空就直接拼接上去。空就不拼接 。。

#17


引用 15 楼 u011434924 的回复:
Quote: 引用 14 楼 ganshenml 的回复:

如果是写在sql语句里面的话,用or连接写条件,判断为空,为空字符串,和应匹配的字符串相不相等!
用or的话结果出来的和预想的就不一样了

(a is null or a='' or a=字段)为什么不可以呢?

#18


引用 17 楼 ganshenml 的回复:
Quote: 引用 15 楼 u011434924 的回复:

Quote: 引用 14 楼 ganshenml 的回复:

如果是写在sql语句里面的话,用or连接写条件,判断为空,为空字符串,和应匹配的字符串相不相等!
用or的话结果出来的和预想的就不一样了

(a is null or a='' or a=字段)为什么不可以呢?

不好意思 我理解错了  我以为你是说把原来的and 改成 or

#19


引用 18 楼 u011434924 的回复:
Quote: 引用 17 楼 ganshenml 的回复:

Quote: 引用 15 楼 u011434924 的回复:

Quote: 引用 14 楼 ganshenml 的回复:

如果是写在sql语句里面的话,用or连接写条件,判断为空,为空字符串,和应匹配的字符串相不相等!
用or的话结果出来的和预想的就不一样了

(a is null or a='' or a=字段)为什么不可以呢?

不好意思 我理解错了  我以为你是说把原来的and 改成 or
没事,慢慢弄就明白了!

#20


引用 13 楼 u011434924 的回复:
早上好! 早上试了一下 你说的方法  提示了The method getInnermostDelegate() is undefined for the type PreparedStatement 这个错误... 弱弱地再问一下这个方法是哪个类的啊?


apache DBCP 组件的方法:
http://commons.apache.org/proper/commons-dbcp/apidocs/org/apache/commons/dbcp/managed/ManagedConnection.html

本意是申请从连接池所管理的Connection中,获取到原生的 PreparedStatement 实现类(也即是Oracle所提供的)。

#21


引用 20 楼 ldh911 的回复:
Quote: 引用 13 楼 u011434924 的回复:

早上好! 早上试了一下 你说的方法  提示了The method getInnermostDelegate() is undefined for the type PreparedStatement 这个错误... 弱弱地再问一下这个方法是哪个类的啊?


apache DBCP 组件的方法:
http://commons.apache.org/proper/commons-dbcp/apidocs/org/apache/commons/dbcp/managed/ManagedConnection.html

本意是申请从连接池所管理的Connection中,获取到原生的 PreparedStatement 实现类(也即是Oracle所提供的)。


jdbc 的sql语句怎么写多条件查询
是不是包版本太低了啊... 找不到你说的这个类...

#22


引用 21 楼 u011434924 的回复:
jdbc 的sql语句怎么写多条件查询
是不是包版本太低了啊... 找不到你说的这个类...


俺只能表示:I don't known...

#23


引用 22 楼 ldh911 的回复:
Quote: 引用 21 楼 u011434924 的回复:

jdbc 的sql语句怎么写多条件查询
是不是包版本太低了啊... 找不到你说的这个类...


俺只能表示:I don't known...

 
DelegatingConnection con= (DelegatingConnection) dataSource.getConnection();
OraclePreparedStatement ps= (OraclePreparedStatement) con.getInnermostDelegate().prepareStatement(FINDPANA);

这样子写竟然会报 nullpointException   还是在prepareStatement(FINDPANA)这个方法的时候报的错误... 

#24


一个传参费这么大的劲?

Stringbuffer  sql="select * from student t ";
if( 字段中至少有一个不为空或者""){
 sql.append(" where ");
 list.add(val1);
}
if(id != null|| !"".equale(id)){
 sql.append(" t.id=?");
 list.add(val2);
}
if(name!=null || !"".equale(name)){
 sql.append( " t.name=? ");
 list.add(val3);
}
....
ps = con.prepareStatement(sql);
for (...list...){
    ps.setString(i, list.get(i));
}
....

#25


获取提交表单数据的值,判断提交的值为不为null如果不为null那么就and连接否则不连接

#26


遇到一样的问题,在线等。

#27


创建个list 比如

List<object> param = new ArrayList<Object>();
if(id != null|| !"".equale(id)){
 sql.append(" t.id=?");
 param.add(id);
}

最后设置参数的时候

for(int i =0; i < param.size(); i ++) {
  ps.setString(i + 1, param.get(i));
}

#28




引用 24 楼 forgetsam 的回复:
一个传参费这么大的劲?

Stringbuffer  sql="select * from student t ";
if( 字段中至少有一个不为空或者""){
 sql.append(" where ");
 list.add(val1);
}
if(id != null|| !"".equale(id)){
 sql.append(" t.id=?");
 list.add(val2);
}
if(name!=null || !"".equale(name)){
 sql.append( " t.name=? ");
 list.add(val3);
}
....
ps = con.prepareStatement(sql);
for (...list...){
    ps.setString(i, list.get(i));
}
....


引用 22 楼 ldh911 的回复:
Quote: 引用 21 楼 u011434924 的回复:

jdbc 的sql语句怎么写多条件查询
是不是包版本太低了啊... 找不到你说的这个类...


俺只能表示:I don't known...



非常感谢大家