主要是对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();