使用mybatis完成高级查询(多条件查询)的核心代码

时间:2021-05-28 05:36:53
1.创建一个Query对象(查询对象)
里面放一些查询的条件,它就是一个JavaBean
创建一个包 cn.itsource.query 和我们的domain在同一级
取名就为XxxQuery -> ProductQuery /TeacherQuery

2.查询的时候需要从前台传入Query对象
List<Product> queryAll(ProductQuery query)

3.mapper的配置是完成高级查询(一定把query传过来)
<where>
<if test="条件是否存在">
and 条件
</if>
</where>
4.前台准备一个查询表单(下例)
<form action="/product" method="post">
名称:<input type="text" name="productName" value="${query.productName}" />
从<input type="number" name="minSalePrice" value="${query.minSalePrice}" >
到<input type="number" name="maxSalePrice" value="${query.maxSalePrice}" >
<input type="submit" value="..查询.." />
</form>
value中是做回显的
注意:所有的name是都Query对象中的属性
5.在Servlet要提收并且封装Query对象(下例)
ProductQuery query = new ProductQuery();
//接收商品名称参数,并且放到query对象
String productName = req.getParameter("productName");
if(isNotBlank(productName)){
query.setProductName(productName);
}
注意:调用的时候要使用传入query的那一个方法

query对象:

package cn.itsource.query;

/**
* 封装商品的查询条件
* */

public class ProductQuery {
//商品名称
private String productName;
//商品最低价格
private Double minSalePrice;
//商品最高价格
private Double maxSalePrice;

public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Double getMinSalePrice() {
return minSalePrice;
}
public void setMinSalePrice(Double minSalePrice) {
this.minSalePrice = minSalePrice;
}
public Double getMaxSalePrice() {
return maxSalePrice;
}
public void setMaxSalePrice(Double maxSalePrice) {
this.maxSalePrice = maxSalePrice;
}

/**
* 提供一个判断条件方法 用于在对象映射文件中直接使用(${whereSql})
* select * from product ${whereSql}
*
* 动态拼接字符串(sql条件) 第一个条件必须是where开头,后面的必须是and
* 1=1这种方法不是很好。查询效率很低!
* */

/*
public String getWhereSql(){
StringBuffer whereSql = new StringBuffer(" where 1=1 ");
if(productName!=null && !"".equals(productName)){
whereSql.append("and productName like '%").append(productName).append("%'");
}
if(minSalePrice!=null){
whereSql.append("and salePrice >").append(minSalePrice);
}
if(maxSalePrice!=null){
whereSql.append("and salePrice <").append(maxSalePrice);
}
return whereSql.toString();
}
*/


/**
* 第二种方法拼接sql
* */

/*
public String getWhereSql(){
StringBuffer whereSql = new StringBuffer();
if(productName!=null && !"".equals(productName)){
whereSql.append("and productName like '%").append(productName).append("%'");
}
if(minSalePrice!=null){
whereSql.append("and salePrice >").append(minSalePrice);
}
if(maxSalePrice!=null){
whereSql.append("and salePrice <").append(maxSalePrice);
}
//String replaceFirst(String replaceFirst,String replaceMent) 将第一个替换成你想要的 将and替换成where
return whereSql.toString().replaceFirst("and", "where");
}
*/

}

ProductMapper.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">


<mapper namespace="cn.itsource.domain.ProductMapper">


<!-- ProductQuery查询对象里面有拼接多条件查询sql
<select id="queryAll" parameterType="cn.itsource.query.ProductQuery" resultType="Product">
select * from product ${whereSql}
</select>
-->


<!--
mybatis框架有解决多条件查询 使用where标签
where标签的特点: 1.它会自动在条件前面加上where
2.如果条件前面有and(但只有一个条件),会自动把and替换成where
3.where标签里面如果没有条件,就不会添加where
-->

<select id="queryAll" parameterType="cn.itsource.query.ProductQuery" resultType="Product">
select * from product
<where>
<if test="productName!=null">
and productName like concat("%",#{productName},"%")
</if>
<if test="minSalePrice!=null">
and salePrice > #{minSalePrice}
</if>
<if test="maxSalePrice!=null">
<![CDATA[
and salePrice < #{maxSalePrice}
]]>

</if>
</where>
</select>


</mapper>

在dao(接口)层准备一个高级查询的方法直接传入ProductQuery:

package cn.itsource.dao;

import java.util.List;

import cn.itsource.domain.Product;
import cn.itsource.query.ProductQuery;

public interface IProductDao {


/**
* 查询所有信息
* */

List<Product> List();

/**
* 通过查询条件查询到对应的商品数据
* */

List<Product> queryAll(ProductQuery query);
}

ProductServlet类:

package cn.itsource.web.servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.itsource.dao.IProductDao;
import cn.itsource.dao.impl.ProductDaoImpl;
import cn.itsource.domain.Product;
import cn.itsource.query.ProductQuery;

@WebServlet("/product")
public class ProductServlet extends HttpServlet{

private static final long serialVersionUID = 1L;
IProductDao dao = new ProductDaoImpl();

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
//声明query对象,用于下面接收参数后把参数放到query对象
ProductQuery query = new ProductQuery();
req2query(req, query);

//查询到所有数据
List<Product> productList = dao.queryAll(query);
// 把query放入作用域中,用于完成回显
req.setAttribute("query", query);
//把查询到的数据放到作用域中
req.setAttribute("productList", productList);
req.getRequestDispatcher("/WEB-INF/product/list.jsp").forward(req, resp);
}

//传入一个request对象,返回一个query对象
public void req2query(HttpServletRequest req, ProductQuery query) {
//接收参数 拿到商品名称
String productName = req.getParameter("productName");
if(isNotBlank(productName)){
//把这个参数设置到ProductQuery对象中
query.setProductName(productName);
}
//拿到商品最低价格
String minSalePrice = req.getParameter("minSalePrice");
if(isNotBlank(minSalePrice)){
//把这个参数设置到ProductQuery对象中
query.setMinSalePrice(Double.valueOf(minSalePrice));
}
//拿到商品最高价格
String maxSalePrice = req.getParameter("maxSalePrice");
if(isNotBlank(maxSalePrice)){
//把这个参数设置到ProductQuery对象中
query.setMaxSalePrice(Double.valueOf(maxSalePrice));
}
}

//提供一个方法判断 str不为空也不等于空字符串
public boolean isNotBlank(String str){
return str!=null && !"".equals(str);
}

}

mybatis核心配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
<!-- 关联db.properties文件 -->
<properties resource="db.properties" ></properties>

<!-- 配置别名 type:表示需要配置别名的类 alias:别名名称 -->
<typeAliases>
<typeAlias alias="Product" type="cn.itsource.domain.Product"/>
</typeAliases>

<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</dataSource>
</environment>
</environments>

<!-- 关联对象映射文件 -->
<mappers>
<mapper resource="cn/itsource/domain/ProductMapper.xml" />
</mappers>
</configuration>

前端显示页面的jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
table{
border-collapse: collapse;
width: 600px;
text-align: center;
}

table th,table td {
border:1px solid black;
}

</style>

<title>Insert title here</title>
</head>
<body>

<form action="/product" method="post">
商品名称:<input type="text" name="productName" value="${query.productName}">
<input type="text" name="minSalePrice" value="${query.minSalePrice}">
<input type="text" name="maxSalePrice" value="${query.maxSalePrice}">
<input type="submit" value="查询">
</form>

<table>
<tr>
<th>id</th>
<th>productName</th>
<th>dir_id</th>
<th>salePrice</th>
<th>supplier</th>
<th>brand</th>
<th>cutoff</th>
<th>costPrice</th>
</tr>
<c:forEach items="${productList}" var="p" >
<tr>
<td>${p.id}</td>
<td>${p.productName}</td>
<td>${p.dir_id}</td>
<td>${p.salePrice}</td>
<td>${p.supplier}</td>
<td>${p.brand}</td>
<td>${p.cutoff}</td>
<td>${p.costPrice}</td>
</tr>
</c:forEach>
</table>

</body>
</html>