在Web开发中,多种条件的综合查询非常常见,应对这种业务需求我们通常使用下面几种方法来实现:
PS:
i.(Hibernate的条件查询Criteria Queries当然是非常方便的,本文仅探讨JDBC方式的使用)
ii.(欢迎高手、大拿们拍砖,请勿人身攻击)
1.直接将参数值拼接到SQL语句中,然后进行查询。
这种方式的安全性应当说是比较差的,一不小心就被SQL注入了。虽然可以先过滤参数值中的特殊字符,但总感觉不是很优雅。
2.先使用占位符'?'来拼接SQL,然后再通过条件判断去填充PreparedStatement。
用过这种方式的TX,都知道这种方式的复杂性。先要在拼SQL时判断一次,然后还要在填充pst时再判断一次,麻烦。
3.存储过程
本人一直不爽存储过程,以前有一个项目从MySQL迁移到MSSQL,后来又换成ORACLE,最后产品的不同版本运行在不同数据库上,当时差点要了亲命了。
其实讲这么多无非就是想要一种相对优雅简单的查询方式,前一段看到.NET中的SQLHelper受到一些启发,然后就写了这么一个类似的组件(其实我Google了半个小时都没有找到符合要求的)。
基本思想:
1.在控制器中(Servlet/Action etc...)中将查询表单中的参数值添加到查询条件列表中
2.在DAO(你明白的)中设置基本SQL
3.迭代查询条件列表,使用占位符拼接SQL
4.在DAO中拿SQL创建PreparedStatement
5.迭代查询条件列表,为pst填充值
6.接下来,没有特殊的地方了,就是正常的executeQuery,while(rs.next()){...}
将第1/2/3/5步骤的功能提取出来做成一个工具类,然后其它地方就可以随意使用了,嘿嘿
好了,不啰嗦了直接上代码吧
Parameter.java
/**
* 查询参数类,用于表示条件参数对象
* @author Lixor(at)live.cn
*
*/
public class Parameter{
private String field;
private Object value;
private String operator;
/**
*
* @param field 数据库字段名
* @param operator 数据库操作符 =、>=、<、like etc...
* @param value 参数值 Object
*/
public Parameter(String field,String operator, Object value) {
super();
this.field = field;
this.value = value;
this.operator = operator;
}
public String getField() {
return field;
}
public Object getValue() {
return value;
}
public String getOperator() {
return operator;
}
}
DynamicQuery.java
/**
* 动态查询工具类,用于拼接SQL、填充pst
* @author Lixor(at)live.cn
*
*/
public class DynamicQuery {
private static Logger logger=Logger.getLogger(DynamicQuery.class);
private String templet = " AND %s %s ?";
private String baseSql;
private ArrayList<Parameter> parameters = new ArrayList<Parameter>();
public DynamicQuery() {
}
/**
* 要求baseSql带有where条件
*
* @param baseSql
*/
public void setBaseSql(String baseSql) {
this.baseSql = baseSql;
}
public void addParameter(Parameter parameter) {
parameters.add(parameter);
}
public String generateSql() {
StringBuffer buffer = new StringBuffer(baseSql);
for (Parameter p : parameters) {
buffer.append(String.format(templet, p.getField(), p.getOperator()));
}
logger.debug(buffer);
return buffer.toString();
}
public void fillPreparedStatement(PreparedStatement pst) throws SQLException {
int count = 1;
for (Parameter p : parameters) {
pst.setObject(count, p.getValue());
count++;
}
}
}
示例:查询产品信息
QueryServlet.java
DynamicQuery query=new DynamicQuery();
query.addParameter(new Parameter("p.name" ,"like","电视"));
query.addParameter(new Parameter("p.type_id","=" ,1));
query.addParameter(new Parameter("p.productDate" ,">=",java.sql.Date.valueOf("2010-09-04")));
query.addParameter(new Parameter("p.price" ,">=",1000.0f));
ProductDao dao=new ProductDao();
List<Product> productList=dao.query(query);
request.setAttribute("productList",productList);
ProductDao.java
public List<Product> query(DynamicQuery query) {
List<Product> productList = new ArrayList<Product>();
try {
String sql = "SELECT p.id,p.name,p.price,p.productDate,p.image,p.type_id,t.name,p.description FROM tbl_product p,tbl_type t WHERE p.type_id=t.id";
query.setBaseSql(sql);
sql = query.generateSql();//如果想排序,自行在sql后添加
Connection conn = null;
try {
conn = DbUtil.getConnection();
PreparedStatement pst= conn.prepareStatement(sql);
query.fillPreparedStatement(pst);//填充pst
ResultSet rs = pst.executeQuery();
while (rs.next()) {
Product product = new Product();
……
productList.add(product);
}
rs.close();
pst.close();
} finally {
if (conn != null) {
conn.close();
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return productList;
}
感谢“jl580650”提出的pst.setObject建议,我之前是用反射做的。
分享到:
相关推荐
讨论了Java语言通过JDBC(JavaDataBaseConnectivity)访问Web数据库的实现思想及访问模式,论述了JDBC的原理及实现过程,给出了一个基于JDBC的Web数据库开发的实验模型.
实现对MySQL数据库的连接,完成全部查询和条件查询,采用JavaBean+Servlet+JSP模式,使用EL表达式和JSTL标签库
SBORM只是针对spring jdbc的一些不方便的地方,做了一些封装,更加简化日常的开发工作,基于spring jdbc的RowMapper自动实现对象映射,也勉强算的上叫ORM,只是大部分功能已经由spring jdbc实现了。 平时不太...
学生选课模块实现了学生查询所有开设课程、查询符合条件的课程、选修课程、退选课程等功能。选课界面显示课程名称、课程号、开课时间、地点、教师信息等,学生可以根据这些信息选择合适的课程进行选修。 教师管理课程...
通过表单的隐藏域保存查询条件(带条件的翻页) jstl中的注释为<%-- --%>,不能使用普通的html注释 jstl中可以调用bean的属性和方法 Servlet3.0中Filter的配置initParams={@WebInitParam(name="charset",value...
该模块主要是对老师的个人信息进行存储和索引,如姓名、年龄、婚姻状态、课程、工作时间等,并实现按不同条件对这些数据进行查询的功能。 (3)班级信息管理 该模块主要是对每个班级的基本信息进行有效管理,包括...
报表查询模块提供了人员日程汇总、文档查询统计、会议室使用情况等多种报表查询功能,用户可以通过简单的查询条件过滤报表数据,实现对办公运行状况的实时监控。系统采用三层架构设计,通过JDBC技术实现数据访问层与...
基于jsp+jdbc+servlet的个人CMS系统源码+项目说明(课程大作业).zip # FreeCMS ## 项目简介 基于jsp+jdbc+servlet的个人CMS系统,课程大作业。 ## 运行条件 - java1.8 - mysql5.7+ - 按需求下载mysql-...
动态SQL主要元素如下表所示: 8.2 元素 在MyBatis中,元素是最常用的判断语句,它类似于Java中的if语句,主要用于实现某些简单的条件选择。其基本使用示例如下: 元素 select * from t_customer where 1=1 !=null ...
C语言实现的,提供语言和(基于SQL的)数据库进行交互的“一致性”的接口 JDBC:java版本的ODBC JDBC连接数据库的步骤: 1.注册驱动(加载驱动): 注册的方式: 1.使用类加载器(使用反射的方式) Class.for...
然后设计联系人类,包含添加联系人、删除联系人、修改联系人、查询联系人等方法,这些方法通过JDBC技术操作MySQL数据库,实现联系人信息的存储和管理。 添加联系人方法,需要输入联系人姓名、性别、年龄、联系电话、...
在线选房系统是基于Servlet和JDBC等技术开发的房屋租售平台,旨在为用户提供便捷的房屋租售信息查询、在线选房和交易服务。该系统具有以下主要特点和功能: 1. **房源信息展示:** 系统展示了丰富的房屋租售信息,...
基于SSM+Mysql实现的CRM信息管理系统源码+数据库+项目说明.zip # SSM项目实战:Crm信息管理系统 ## 1. 系统的功能和简介 * 一个数据管理系统,基于SSM框架进行开发,利用Maven构建和打包。 + 有登录模块。 + 对...
根据查询方法名称和注释动态生成查询 支持查询渠道服务 通过查询方法透明触发Ebean查询 提供基本属性的实现域基类 支持透明审核(创建,最后更改) 集成自定义存储库代码的可能性 Easy Spring与自定义名称空间的...
简单的策划配置管理,可实现多条件查询配置 构建环境 java 8 + gradle 4.0+ 第三方引用 Netty 宇宙最强的java网络库,可定义各种网络通信方式,本框架中RPC、http、websocket等都基于netty的封装。 Disruptor 高性能...
2. 用户管理:选择角色添加用户,修改某个用户的信息,删除某个用户的信息,根据用户名或者角色查询符合条件的用户信息; 4. 角色管理:对角色基本信息的增删改查操作; 5. 菜单管理:在某个父级菜单下添加子菜单...
房屋租赁管理信息系统是一个基于Java JSP和JDBC技术的在线租赁服务平台,旨在简化房屋租赁流程并为房东和租客提供便利。该系统支持房源发布、搜索、预订、合同签订以及租金支付等核心功能,通过高效的数据库操作实现...
管理员登录、根据条件查询订单、删除订单、根据订单号查询订单、订单明细信息、修改订单、删除订单明细等功能 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。
* 实现了一个 **BaseService 类** ,集成了多条件的查询和增改删操作,普通 Service 只需写少量代码即可 * 完全**隔离** MyBatis Generator 生成代码和额外手写代码,以支持可持续化部署,实现了**多个MyBatis ...