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

这是在学生信息管理系统中遇到的,因为当时还没有学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;
    }
posted @ 2017-11-07 11:47  测试开发分享站  阅读(251)  评论(0编辑  收藏  举报