JDBC QueryRunner(开源框架)之查询 详解
来源:互联网 发布:安德罗妮淘宝 编辑:程序博客网 时间:2024/05/22 14:52
QueryRunner查询数据库& QueryRunner如何封装起来的
一、简单描述JDBC获取连接Connection后能做什么?
首先 查看相关API
(一).使用类和方法
- QueryRunner(接口的方法如下两个):
- update(connection,sql,object…objs) //进行增删改方法
- query(connection,sql,ResultSetHandler,object…objs)//查询方法
-
- ResultSetHandler接口
- 常用实现类:
- BeanHandler 封装一个实体对象
- BeanListHandler 封装 一组多个实体对象到list
- ScalarHandler 获取单个值
- MapListHanlder 封装 一组map到list
(二)在详细的解析了JDBC使用C3P0 或 DBCP获取了连接Connection 之后
进一步的需要对数据库进行数据的增删改查一系列的操作
其中大多数操作(其实可以封装在DAO里)不外乎(操作这些共同的方法)
public interface DAO<T> { /* 一、批量处理的方法 * * @param connection: 数据库连接 * @param sql: SQL语句 * @param args: 填充占位符的Object []类型的可变参数 */void batch(Connection connection,String sql,Object[] ...args);/* 二、返回具体的一个值 如 平均成绩 总数 * * @param connection: 数据库连接 * @param sql: SQL语句 * @param args: 填充占位符的可变参数 */<E> E getForValue(Connection connection,String sql,Object ...args);/* 三、返回一个T的一个集合相当于查询所有记录 * * @param connection: 数据库连接 * @param sql: SQL语句 * @param args: 填充占位符的可变参数 */List<T> getForList(Connection connection,String sql,Object ...args);/* 四、返回一个T的对象 * * @param connection: 数据库连接 * @param sql: SQL语句 * @param args: 填充占位符的可变参数 */T get(Connection connection,String sql,Object ...args) throws SQLException;/* 五、增删改操作 * * INSERT UPDATE DELETE * @param connection: 数据库连接 * @param sql: SQL语句 * @param args: 填充占位符的可变参数 */ void update(Connection connection,String sql,Object ...args) throws SQLException;}
二、此文主要解析使用框架QueryRunner 进行 ★查询qruery()操作
//正如我们平时使用最流行的 方法进行操作 不多说 上代码
<1>首先导入jar包(驱动和连接池的不算)
commons-dbutils-1.3.jar
<2>封装使用C3P0获取连接和关闭连接 这两个方法封装如下:
public class JDBCUtils {//数据库连接池值应该被初始化一次放在静态代码块中private static DataSource datasource=null;static{ datasource =new ComboPooledDataSource("helloc3p0");}public static Connection getConnection() throws SQLException{ return datasource.getConnection();}//用完资源后需要关闭/*释放资源:ConnectionStatementResultSet1 尽量晚创建早释放2 后使用的先关闭*/public static void release(ResultSet rs,Statement statement,Connection conn){ if(rs!=null){ try{ rs.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(statement!=null){ try{ statement.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }} if(conn!=null){ try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
<3>步创建QueryRunner 实例对象 调用query()方法
例一、以最复杂查询所有对象的键值对为例如下:
//分析所有对象的键值对 ①键值对需要放在Map集合中 多个对象需要放在集合中 所以如下
//不同的查询方法只是返回结果需要实现的ResultSetHandler接口对象不同
//测试查询List
@Testpublic void testMapList() throws Exception{ Connection conn =JDBCUtils.getConnection(); //创建QueryRunner对象 QueryRunner qr = new QueryRunner(); //调用方法其query查询方法 try{ //下面需要根据查询方法创建ResultSetHandler对象 //将结果集中的每一行数据都封装到一个Map里,然后再存放到List List<Map<String, Object>> query = qr.query(conn, "select * from 表名 where 字段名=?", new MapListHandler(),"女"); }catch (Exception e){ System.out(e.getMasage()); }finally{ //关闭资源 JDBCUtils.release(conn, null, null); } //此处作测试直接遍历Map打印 否则返回 for (Map<String, Object> map : query) { Set<Entry<String, Object>> entrys = map.entrySet(); Iterator<Entry<String, Object>> iterator = entrys.iterator(); while (iterator.hasNext()) { Map.Entry<String, Object> entry = iterator.next(); String key = entry.getKey(); Object value = entry.getValue(); System.out.print(key+"\t"+value+" |||| "); } System.out.println(); }}
}
例二、查询返回某个值如(总数和 或 平均分)
实现如下:
//测试查询单个值@Testpublic void testScalar() throws Exception{ Connection conn =JDBCUtils.getConnection(); //创建QueryRunner对象 QueryRunner qr = new QueryRunner(); //调用方法 Object query = qr.query(conn, "select count(*) from student", new ScalarHandler()); //此处测试直接打印(实际应用中返回结果) System.out.println(query); //关闭连接 JDBCUtils.release(conn, null, null);}
三、在没有使用QueryRunner 框架之前是如何实现的呢?
使用的操作实现类有两个是prepareStatement和Statement
使用的结果处理有ResultSetMetaData实现类获取结果对象的对应值
★★那么prepareStatement和Statement它们有什么区别呢???
第一:
prepareStatement会先初始化SQL先把这个SQL提交到数据库中进行预处理,多次使用可提高效率。createStatement不会初始化,没有预处理,没次都是从0开始执行SQL
第二:
prepareStatement可以替换变量在SQL语句中可以包含?,可以用ps=conn.prepareStatement("select* from Cust where ID=?");int sid=1001;ps.setInt(1, sid);rs = ps.executeQuery();可以把?替换成变量。而Statement只能用int sid=1001;Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery("select * from Cust where ID="+sid);来实现。
第三:
prepareStatement会先初始化SQL,先把这个SQL提交到数据库中进行预处理,多次使用可提高效率。createStatement不会初始化,没有预处理,没次都是从0开始执行SQL
例一:
使用方式一:获取对象为statement进行查询单个对象如下
/**一、使用statement测试查询单个对象 * * @throws Exception */@Testpublic void testQuery() throws Exception{ Connection connection =JDBCUtils.getConnection(); //获取执行命令对象 Statement statement = connection.createStatement(); //执行★ ResultSet set = statement.executeQuery("select sex,name from 表名"); while(set.next()){ // Object id = set.getObject(1);//得到第一列 Object name = set.getObject(2);//得到第2列 Object sex = set.getObject(1);//得到第3列 // Object email = set.getObject(4);//得到第4列 // Object borndate = set.getObject(5);//得到第5列 //输出一个就行测试 System.out.println(name+"\t"+sex); } //释放资源 JDBCUtils.release(set, statement,connection); }}
例二:
使用方式二:使用PreparedStatement 的对象prepareStatement 改进方式一
查询所有对象如:
public List<T> query(Class<T> clazz, String sql, Object... objects) {Connection connection = null;PreparedStatement statement = null;ResultSet set = null; List<T> list=new ArrayList<>(); try { //1.获取连接 connection = JDBCUtils.getConnection(); //2.获取PreparedStatement对象prepareStatement statement = connection.prepareStatement(sql); //为sql占位符 赋值 for (int i = 0; i < objects.length; i++) { statement.setObject(i+1, objects[i]); } //3.执行sql 进行executeQuery()查询操作并处理结果 set= statement.executeQuery(); //创建ResultSetMetaData对象获取查询结果的对象对应值 ResultSetMetaData metaData = set.getMetaData(); while(set.next()){ //通过反射创建对象 T t = clazz.newInstance();//实体类必须有无参构造 //遍历结果集 for (int i = 0; i < metaData.getColumnCount(); i++) { //得到列名 String name = metaData.getColumnLabel(i+1); //得到列对应的值 Object value = set.getObject(name); //通过反射设置属性 Field field = clazz.getDeclaredField(name); //利用反射对private私有属性进行暴力破解 field.setAccessible(true); //调用封装的实体类中的set()方法给属性赋值 field.set(t, value); } // 将对象放入ArrayList集合中 list.add(t);//将t添加到list } //返回最终结果 return list; } catch (Exception e) { throw new RuntimeException(e.getMessage()); }finally{ //关闭连接 JDBCUtils.release(connection, statement, set); }}
四、分析总结
在使用QueryRunner 之前我们的操作对象有两个
1.prepareStatement和Statement调用其方法: execute()进行查询 相当于 QueryRunner的query()方法 executeUpdate()进行增删改 相当于 QueryRunner的update()方法2、使用apache下的PropertyUtils将对象赋予查询的结果 import org.apache.commons.beanutils.PropertyUtils; PropertyUtils.setProperty(t, name, value);2.处理结果方法有ResultSetMetaData的对象 调用其方法: metaData.getColumnCount()获取结果集长度 //获取其列名或别名 String name = metaData.getColumnLabel(i+1); //获取其列名或别名对应的值 Object value = set.getObject(name); //将获取值放入对象中 PropertyUtils.setProperty(t, name, value); 相当于相当于 QueryRunner的ResultSetHandler的不同实现对象方法
0 0
- JDBC QueryRunner(开源框架)之查询 详解
- java-jdbc工具类(QueryRunner)
- QueryRunner 之 query函数
- 使用jdbc编写查询框架
- SSH框架之Hibernate的查询详解(2)、hql查询优化
- 网络爬虫之java基础篇QueryRunner(Ⅲ)
- 网络爬虫之java基础篇QueryRunner(Ⅲ)
- java学习之:JDBC(查询)
- jdbc之分页查询
- JDBC&&c3p0、事务、批处理、多线程 于一体的经典秘方QueryRunner (common-dbutils)
- QueryRunner
- QueryRunner
- QueryRunner
- queryRUNNER
- Android开源框架之SlidingMenu详解
- JDBC详解系列(一)之流程
- SSH框架之Hibernate的查询详解(1)、debug断点调试
- SSH:Spring框架(JDBC访问数据库及配置详解)
- 文章标题
- xUtils系列之BitmapUtils
- 收藏的几个链接
- Verilog 编程实验(6)-4位移位寄存器的设计与实现
- 【OpenCL编程任务一】输出进行运算设备的名称
- JDBC QueryRunner(开源框架)之查询 详解
- 143.Sort Colors II-排颜色 II(中等题)
- Java中类与类的关系
- JavaScript的任意拖拽改变盒子的宽高<案例>
- 51Nod-1406-与查询
- Jsp入门<1>Jsp入门基础简介与工作原理详解
- 微信小程序学习(5)_事件
- 第一次写博客
- 类与类之间的几种关系