(13)多条件查询(精确查询、模糊查询):动态拼接sql

来源:互联网 发布:用友t3软件数据备份 编辑:程序博客网 时间:2024/05/18 01:06

这是在学生信息管理系统中遇到的,因为当时还没有学hibernate,所以访问数据库还是用JDBC。
需求:在查询用户信息时,可以指定如下查询条件,按照用户编号精确查询;按照姓名模糊查询(输入李可以查到所有姓李的用户);按照性别查询;按照年龄范围查询。
so查询页面如下:
这里写图片描述
按照上面的组合查询条件,这个对象,应该有一个编号(精确查询),一个姓名(模糊查询),一个性别(模糊查询),两个年龄(模糊查询max,min)。这里面就有一个User对象,但是缺少一个年龄属性。
一种简单的解决方式是继承,在继承类中添加一个私有属性。
User:id、username、sex、age
UserQuery extends User :age2

public class UserQueryAction  extends ActionSupport{    private UserQuery uq;    private List<User> users=new ArrayList<User>();    private UserQueryService uqs=new UserQueryService();    @Override    public String execute() throws Exception {        return "success";    }    public String query() throws Exception {        users=uqs.query(uq);        return "success";    } }

这样对象问题解决,到数据库查询,是个动态的,要根据用输入的条件来拼接SQL,如果用户输入了某个条件值,那么就在SQL上拼接该条件,若用户没有输入,那么就不在SQL上拼接该条件。

private String generateWhere(UserQuery uq){        //判断UserQuery中哪些项,被选上,从而形成sql语句        StringBuffer buf=new StringBuffer();        //用户编号        if(uq.getId()>0){            buf.append(" and id=?");        }        //用户名        if(uq.getUsername()!=null && uq.getUsername().trim().length()>0){            buf.append(" and username=?");        }        //性别        if(uq.getSex()!=null){            buf.append(" and sex=?");        }        //最小年龄        if(uq.getAge()>0){            buf.append(" and age>=?");        }        //最大年龄        if(uq.getAge2()>0){            buf.append(" and age<=?");//注意这里仍然是age        }        return buf.toString();    }

另外一个问题,由于SQL是动态拼接出来的,那么向SQL传入参数的过程也就不确定,同样需要动态拼接SQL,来动态的设置SQL的参数。

//既然sql语句是不确定,那么preparedStatement也是不确定的。    private void prepares(UserQuery uq,PreparedStatement stmt) throws SQLException{        int count=1;        //用户编号                if(uq.getId()>0){                    stmt.setInt(count++, uq.getId());                }                //用户名                if(uq.getUsername()!=null && uq.getUsername().trim().length()>0){                    stmt.setString(count++, uq.getUsername());                }                //性别                if(uq.getSex()!=null){                    stmt.setString(count++, uq.getSex());                }                //最小年龄                if(uq.getAge()>0){                    stmt.setInt(count++, uq.getAge());                }                //最大年龄                if(uq.getAge2()>0){                    stmt.setInt(count++, uq.getAge2());                }    }

通过上面两个方法,就能够拼接成了完整的sql语句,以及stmt应该设置的值,下面就是调用这两个方法进行查询。

public ArrayList<User> query(UserQuery uq){        ArrayList<User> users=new ArrayList<User>();        Connection conn=null;        PreparedStatement stmt=null;        ResultSet rs=null;        try{            conn=jdbcUtil.getConnection();            //由于UserQuery中的属性情况,所以必须加上1=1恒成立条件            String sql="select * from user where 1=1"+this.generateWhere(uq);            stmt=conn.prepareStatement(sql);            this.prepares(uq, stmt);//已经将stmt的参数值赋好            rs=stmt.executeQuery();            while(rs.next()){                 User user=new User();                    user.setId(rs.getInt("id"));                    user.setUsername(rs.getString("username"));                    user.setSex(rs.getString("sex"));                    user.setAge(rs.getInt("age"));                    users.add(user);            }        }catch(Exception e){            e.printStackTrace();        }finally{            jdbcUtil.close(conn, stmt, rs);        }        return users;    }
原创粉丝点击