JSP高级查询---条件过滤

本文详细介绍了一种在Java环境中动态构建SQL查询语句的方法,通过使用StringBuilder拼接SQL语句并结合参数列表来实现灵活的条件筛选。文章探讨了如何避免硬编码条件,采用动态参数化方式,以增强SQL查询的灵活性和安全性。此外,还介绍了封装查询条件到Query对象中,以及如何优化WHERE子句的处理,以提高查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要是对SQL语句的拼接

@Override
	public List<Product> query(String name, BigDecimal minSalePrice, BigDecimal maxSalePrice) {
		
		StringBuilder sql = new StringBuilder(80);
		sql.append("SELECT * FROM product WHERE 1=1");
		//封装占位符参数
		List<Object> parameters = new ArrayList<>();
		//商品名称
		if(StringUtils.isNotBlank(name)) {
			sql.append(" AND productName LIKE ?");
			parameters.add("%"+name+"%");
		}
		//最低价格
		if(minSalePrice != null) {
			sql.append(" AND salePrice >= ?");
			parameters.add(minSalePrice);
		}
		//最高价格
		if(minSalePrice != null) {
			sql.append(" AND salePrice <= ?");
			parameters.add(maxSalePrice);
		}
		System.out.println("SQL="+sql);
		System.out.println("参数="+parameters);
		return JdbcTemplate.query(sql.toString(),new BeanListHandler<>(Product.class), parameters.toArray());
	}

在拼接SQL语句时,先用“SELECT * FROM product WHERE 1=1”,再进行拼接的原因是:
因为无法确定哪个条件作为第一个条件【第一个条件前用WHERE】所以使用“WHERE 1=1”一定满足的条件占为第一,之后再有其他判断条件用“AND”连接即可。

注意:
SQL语句中要注意空格隔断问题,否则会报SQL语句错误。
**
**
**
**

抽取Query对象

把查询的条件作为query方法的参数:
1):但是如果查询条件过多,此时参数就很多。
------>解决方案:把多个查询条件封装到查询对象(QueryObject)中。
2):谁拥有数据,就应该包含操作该数据的方法。

抽取对应具体类进行封装(如:ProductQueryObject)

//封装了商品的对象的查询条件
@Data
public class ProductQueryObject {
	private String name;
	private BigDecimal minSalePrice;
	private BigDecimal maxSalePrice;
	
	//封装占位符参数
	private List<Object> parameters = new ArrayList<>();
	
	//拼接SQL语句,同时拼接一个未知参数(?)就向参数集合中加入对应的参数值
	public String getQuery() {
		StringBuilder sql = new StringBuilder(80);
		sql.append(" WHERE 1=1");
		//商品名称
		if(StringUtils.isNotBlank(name)) {
			sql.append(" AND productName LIKE ?");
			parameters.add("%"+name+"%");
		}
		//最低价格
		if(minSalePrice != null) {
			sql.append(" AND salePrice >= ?");
			parameters.add(minSalePrice);
		}
		//最高价格
		if(minSalePrice != null) {
			sql.append(" AND salePrice <= ?");
			parameters.add(maxSalePrice);
		}
		
		return sql.toString();
	}
	//返回对应的参数集合
	public List<Object> getParameters() {
		return parameters;
	}
}

对实现类的修改(ProductDaoImple)

public class ProductDAOImpl implements IProductDAO{	
	@Override
	public List<Product> listAll() {
		String sql= "SELECT * FROM product";
		return JdbcTemplate.query(sql,new BeanListHandler<>(Product.class));
	}

	@Override
	public List<Product> query(ProductQueryObject qo) {
		String sql ="SELECT * FROM product"+qo.getQuery();
		List<Object> parameters = qo.getParameters();
		
		System.out.println("SQL="+sql);
		System.out.println("参数="+parameters);
		
		return JdbcTemplate.query(sql.toString(),new BeanListHandler<>(Product.class),
				qo.getParameters().toArray());
	}
	
}

对接口的修改(IProductDao)

public interface IProductDAO {
	List<Product> listAll();
	
	//高级查询
	List<Product> query(ProductQueryObject qo);
}

测试类(ProductDaoTest)

public class ProductDAOTest {

	private IProductDAO dao = new ProductDAOImpl();

	@Test
	public void testListAll() {
		List<Product> list = dao.listAll();
		for(Product p : list) {
			System.out.println(p);
		}
	}
	@Test
	public void testquery() {
		ProductQueryObject qo = new ProductQueryObject();
		qo.setName("M");
		qo.setMinSalePrice(new BigDecimal("100"));
		qo.setMaxSalePrice(new BigDecimal("200"));
		//===================================================
		List<Product> list = dao.query(qo);
		System.out.println(list.size());
		for(Product p : list) {
			System.out.println(p);
		}
	}
}

解决WHERE 1=1 问题

方法一: 使用集合+循环:
修改ProductQueryObject类

//封装了商品的对象的查询条件
@Data
public class ProductQueryObject {
	private String name;
	private BigDecimal minSalePrice;
	private BigDecimal maxSalePrice;
	
	//封装占位符参数
	private List<Object> parameters = new ArrayList<>();
	//封装体条件参数
	private List<Object> conditions = new ArrayList<>();
	
	//拼接SQL语句,同时拼接一个未知参数(?)就向参数集合中加入对应的参数值
	public String getQuery() {
		StringBuilder sql = new StringBuilder(80);
		//商品名称
		if(StringUtils.isNotBlank(name)) {
			conditions.add("productName LIKE ?");
			parameters.add("%"+name+"%");
		}
		//最低价格
		if(minSalePrice != null) {
			conditions.add("salePrice >= ?");
			parameters.add(minSalePrice);
		}
		//最高价格
		if(minSalePrice != null) {
			conditions.add("salePrice <= ?");
			parameters.add(maxSalePrice);
		}
		//-----------------------取出参数拼接SQL语句-------------------------------
		if(conditions.size()==0) {
			return "";
		}
		for(int i= 0; i<conditions.size(); i++) {
			if(i == 0) {//第一个条件
				sql.append(" WHERE ");
			}else {
				sql.append(" AND ");
			}
			sql.append(conditions.get(i));
		}
		//------------------------------------------------------------------------
		
		return sql.toString();
	}
	//返回对应的参数集合
	public List<Object> getParameters() {
		return parameters;
	}
}

方法二:在集合元素之间使用AND连接,再在第一个元属前加WHERE

//-----------------------取出参数拼接SQL语句-------------------------------
		if(conditions.size()==0) {
			return "";
		}
		String queryString = StringUtils.join(conditions," AND ");
		//------------------------------------------------------------------------
		
		return sql.append(" WHERE ").append(queryString).toString();
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值