版权声明:本文为博主原创文章,未经博主允许不得转载。
- <版权声明:本文为博主原创文章,未经博主允许不得转载
- <span style="font-size:18px;color:#000000;">在Web开发中会遇到不定条件查询,所谓不定条件就是在页面端有多个查询条件约束,而这些条件用户可以选择也可以不选择,这样就会造成SQL语句的变化,因此不能将SQL语句写死,另外这也给SQL语句的参数赋值造成了一定影响,前几天上课做一个简单小示例,我上网搜索了一下,发现网上的做法有很多,受CSDN上xulu_258的一篇博客(启发,我做了一下细化及一些改进页面端JSP如下</span>
- <%@ page pageEncoding="GBK" %>
- <html>
- <head>
- <title>MainPerson.jsp</title>
- <style type="text/css">@IMPORT url("/Neu_pro/css/style.css");</style>
- </head>
- <body>
- <br>
- <br>
- <form action="/Neu_pro/queryperson.html" method="post">
- <!-- 数据查询条件区 -->
- <div class="query">
- <table>
- <caption>
- 员工管理
- <hr>
- </caption>
- <tr class="title">
- <td colspan="100">查询条件</td>
- </tr>
- <tr>
- <td>姓名</td>
- <td>
- <input type="text" name="qpname">
- </td>
- <td>身份证</td>
- <td>
- <input type="text" name="qpnumber">
- </td>
- </tr>
- <tr>
- <td>学历</td>
- <td>
- <select name="qxl">
- <option value="">==不限==</option>
- <option value="1">高中以下</option>
- <option value="2">高中</option>
- <option value="3">专科</option>
- <option value="4">本科</option>
- </select>
- </td>
- <td>技术职称</td>
- <td>
- <select name="qjszc">
- <option value="">==不限==</option>
- <option value="01">初级职称</option>
- <option value="02">中级职称</option>
- <option value="03">副高级职称</option>
- <option value="04">高级职称</option>
- </select>
- </td>
- </tr>
- <tr>
- <td>工资[B]</td>
- <td>
- <input type="number" step="0.01" name="bsal">
- </td>
- <td>工资[E]</td>
- <td>
- <input type="number" step="0.01" name="esal">
- </td>
- </tr>
- </table>
- </div>
- <!-- 数据迭代区(以表格形式显示查询结果) -->
- <div class="data">
- ${rows }
- </div>
- <!-- 按钮区 -->
- <div class="button">
- <table>
- <tr>
- <td>
- <input type="submit" name="next" value="查询">
- <input type="submit" name="next" value="添加">
- <input type="submit" name="next" value="删除" disabled="disabled">
- </td>
- </tr>
- </table>
- </div>
- </form>
- </body>
- </html>
获取页面端数据的Servlet如下:
将页面端获取的数据放到数组中去,作为参数传给查询方法queryperson();
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- String pname=request.getParameter("qpname");
- String pnumber=request.getParameter("qpumber");
- String xl=request.getParameter("qxl");
- String jszc=request.getParameter("qjszc");
- String bsal=request.getParameter("bsal");
- String esal=request.getParameter("esal");
- String val[]={pname,pnumber,xl,jszc,bsal,esal};
- PersonServices service=new PersonServices();
- try {
- List<Map<String,String>> rows=service.queryperson(val);
- request.setAttribute("rows", rows);
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
关键的数据库操作部分:
将页面端获取到的查询参数还原,然后用StringBuilder来new一个基本的查询语句,例如:"select * from person(表名) where 1=1", where 1=1是为了考虑到后面我们添加条件时直接用and,而不是在重复的使用if语句来判断用where还是and. 然后用if判断如果不为空则sql.append("and name=?"),依次类推。
同时,如果该条件不为空,则将改值放到List中,因为List的有序性,为我们以后的问号赋值提供了便利,赋值时我们只需要便利List即可,因为问号是和List中的参数值是一一对应的。
- public List<Map<String,String>> queryperson(String...val)throws Exception
- {
- Connection conn=null;
- PreparedStatement psmt=null;
- ResultSet rs=null;
- try{
- String pname=val[0];
- String pnumber=val[1];
- String xl=val[2];
- String jszc=val[3];
- String bsal=val[4];
- String esal=val[5];
- conn=DBUtils.getConnection();
- List<Object> pars=new ArrayList<>();
- StringBuilder sql=new StringBuilder()
- .append("SELECT X.PID,X.PNAME,X.PNUMBER,X.PSEX,")
- .append(" TO_CHAR(X.PDATE,'YYYY-MM-DD') PDATE,")
- .append(" X.MZ,X.XL,X.PMAIL,X.PHONE")
- .append(" FROM PERSON X")
- .append(" WHERE 1=1")
- ;
- if(pname!=null&&pname.equals("")){
- sql.append("AND pname like ?");
- pars.add("%"+pname+"%");
- }
- if(pnumber!=null&&pnumber.equals("")){
- sql.append("AND X.PNUMBER= ?");
- pars.add(pnumber);
- }
- if(xl!=null&&xl.equals("")){
- sql.append("AND X.XL= ?");
- pars.add(xl);
- }
- if(jszc!=null&&jszc.equals("")){
- sql.append("AND X.JSZC= ?");
- pars.add(jszc);
- }
- if(bsal!=null&&bsal.equals("")){
- sql.append("AND X.BSAL>= ?");
- pars.add(bsal);
- }
- if(esal!=null&&esal.equals("")){
- sql.append("AND X.ESAL<= ?");
- pars.add(esal);
- }
- sql.append(" ORDER BY X.PNAME");
- System.out.println(sql);
- System.out.println(pars);
- psmt=conn.prepareStatement(sql.toString());
- int index=1;
- for (Object parm : pars) {
- psmt.setObject(index++, parm);
- }
- rs=psmt.executeQuery();
- ResultSetMetaData rsmd=rs.getMetaData();
- int count=rsmd.getColumnCount();
- int init_size=((int)(count/0.75))+2;
- List<Map<String,String>> rows=new ArrayList<>();
- Map<String,String> ins=null;
- while(rs.next()){
- ins=new HashMap<>(init_size);
- for(int i=1;i<=count;i++){
- ins.put(rsmd.getColumnLabel(i).toLowerCase(),rs.getString(i));
- }
- rows.add(ins);
- }
- return rows;
- }finally{
- }
- //return null;
- }
查询结果的处理,查询出的结果我们利用ResultSetMetaData将结果集的每一行都封装到List<Map<String,String>>中,ResultSetMetaData是ResultSet的子类但是它保留结果集的完整结构,我们可以利用它获取每一列的名称,并且还能获得一共有多少列,方便我们计算Map的初始容量,但是由于map的无序性造成了封装的数据杂乱无章,在页面端无法有序显示,这一点我还没有解决