多添件组合查询
先给项目搭个架子(建包)
- com.baidu.custmer.domain
- com.baidu.custmer.dao
- com.baidu.custmer.service
- com.baidu.custmer.web.servlet
四个包分别负责不同的层:领域对象、持久层、业务层、web层
多条件查询流程
- 页面发出查询请求,向服务器发送查询信息(就是一个表单信息)
- 服务器接收请求,Servlet处理请求
- 把request域中的表单信息封装到domain对象中
- 调用业务层service方法,传递条件,这个条件就是第二步的domain对象,并且返回一个List集合
- 并且把结果集保存在request域中
- 转发到显示查询结果的页面中
- 业务层(这里的业务层其实什么事也没有做,只是调用了Dao中的方法,如果项目够大就会体现出业务层)
**4. Dao中进行查询 **
** 这里就只演示多条件查询有关的代码了 **
com.baidu.custmer.domain
就是一个customer类,domain领域对象
package cn.itcast.cstm.domain;
/**
* 领域对象
* 与表单和数据库表对应
*/
public class Customer {
private String cid;//主键id
private String cname;//姓名
private String gender;//性别
private String birthday;//生日
private String cellphone;//电话
private String email;//邮箱
private String description;//描述
public Customer() {
}
public Customer(String cid, String cname, String gender, String birthday, String cellphone, String email, String description) {
this.cid = cid;
this.cname = cname;
this.gender = gender;
this.birthday = birthday;
this.cellphone = cellphone;
this.email = email;
this.description = description;
}
public String getCid() {
return cid;
}
public void setCid(String cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getCellphone() {
return cellphone;
}
public void setCellphone(String cellphone) {
this.cellphone = cellphone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "Customer{" +
"cid='" + cid + '\'' +
", cname='" + cname + '\'' +
", gender='" + gender + '\'' +
", birthday='" + birthday + '\'' +
", cellphone='" + cellphone + '\'' +
", email='" + email + '\'' +
", description='" + description + '\'' +
'}';
}
}
com.baidu.custmer.web.servlet
我们希望在一个Servlet中可以有多个请求处理方法!我们要求客户端发送请求时,必须多给出一个参数,用来说明要调用的方法请求处理方法的签名必须与service相同,即返回值和参数,以及声明的异常都相同!客户端页面必须传递名为method的参数!像这里传递的method参数值就是query。
<form action="<c:url value='/CustomerServlet'/>" method="post">
<input type="hidden" name="method" value="query">
<table border="0" align="center" width="40%" style="margin-left: 100px;">
<tr>
<td width="100px">客户名称</td>
<td width="40%">
<input type="text" name="cname"/>
</td>
</tr>
<tr>
<td>客户性别</td>
<td>
<select name="gender">
<option value="">==请选择性别==</option>
<option value="男">男</option>
<option value="女">女</option>
</select>
</td>
</tr>
<tr>
<td>手机</td>
<td>
<input type="text" name="cellphone"/>
</td>
<td>
<label id="cellphoneError" class="error"> </label>
</td>
</tr>
<tr>
<td>邮箱</td>
<td>
<input type="text" name="email"/>
</td>
<td>
<label id="emailError" class="error"> </label>
</td>
</tr>
<tr>
<td> </td>
<td>
<input type="submit" value="搜索"/>
<input type="reset" value="重置"/>
</td>
<td> </td>
</tr>
</table>
</form>
这里的CustomerServlet继承自BaseServlet ,BaseServlet是继承自HttpServlet,
这就是BaseServlet其实就是避免一个项目中servlet暴增。
@WebServlet("/CustomerServlet")
public class CustomerServlet extends BaseServlet {
private CustomerService customerService = new CustomerService();
private CustomerDao customerDao = new CustomerDao();
/**
* 多条件组合查询
*
* @param request
* @param response
* @return
*/
public String query(HttpServletRequest request, HttpServletResponse response) {
/*
1.封装表单数据到Customer对象中,他只有四个属性(cname,gender,cellphone,email)其实就是条件
2.使用Customer调用service方法,得到List<Customer>
3.保存到request域中
4.转发到list.jsp
*/
Customer criteria=CommonUtils.toBean(request.getParameterMap(),Customer.class);
List<Customer> cstmList=customerService.query(criteria);
request.setAttribute("cstmList",cstmList);
return "f:/list.jsp";
}
}
com.baidu.custmer.service
这里的service层就是简单的调用了Dao中的方法而已。
/**
* 业务层
*/
public class CustomerService {
private CustomerDao customerDao = new CustomerDao();
/**
* 多条件组合查询
* @param criteria
* @return
*/
public List<Customer> query(Customer criteria) {
return customerDao.query(criteria);
}
}
com.baidu.custmer.dao
这个地方真的是学到了。哈哈哈!
我们从com.baidu.custmer.web.servlet中的查询条件表单form中可以发现,他其实是是有多个条件,我们不知道用户怎么查,例如:用户选几个条件,这里还会涉及排列组合问题吗?确实我第一次就是想到了排列组合,那要写多少sql语句那,又有多少层if–else判断条件呢?万一客户要求增加form中的查询条件,那不就白费了。……怎么办呢
dao中多条件查询流程(重点)
1. 给出sql模板(重点就是sql怎么写,怎么判断条件)
* 先给出一个sql语句前半部分
* 判断条件,完成sql中追加where字句
* 不用纠结用户是否会使用哪个条件不使用哪个条件也就是判断中的是否是写and还是where,我们用1=1这样一个废话,代替了条件,后面全部写and即可,(这里虽然基础但是第一次见还是觉得很屌!!!)*
* 创建一个ArrayList用来装载参数值
2. 给出参数
3. 使用BeanListHandler结果集处理器调用query方法
/**
* 持久层
*/
public class CustomerDao {
private QueryRunner qr = new TxQueryRunner();
/**
* 多条件组合查询
*
* @param criteria
* @return
*/
public List<Customer> query(Customer criteria) {
try {
/*
1.给出sql模板
2.给出参数
3.调用query方法,使用BeanListHandler结果集处理器
*/
//1.给sql模板
//先给出一个sql语句前半部分
StringBuilder sql = new StringBuilder("select * from t_customer where 1=1");
//判断条件,完成sql中追加where字句
//创建一个ArrayList用来装载参数值
List<Object> params = new ArrayList<>();
String cname = criteria.getCname();
if (cname != null && !cname.trim().isEmpty()) {
sql.append(" and cname like ?");
params.add("%"+cname+"%");
}
String gender = criteria.getGender();
if (gender != null && !gender.trim().isEmpty()) {
sql.append(" and gender=?");
params.add(gender);
}
String cellphone = criteria.getCellphone();
if (cellphone != null && !cellphone.trim().isEmpty()) {
sql.append(" and cellphone like ?");
params.add("%"+cellphone+"%");
}
String email = criteria.getEmail();
if (email != null && !email.trim().isEmpty()) {
sql.append(" and email like ?");
params.add("%"+email+"%");
}
/*
执行query
*/
return qr.query(sql.toString(), new BeanListHandler<Customer>(Customer.class), params.toArray());
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}