QueryRunner类
1.QueryRunner类
* 使用 Apache提高的工具包DbUtils简化原生JDBC操作数据库的步骤
* DbUtils核心内容:
* org.apache.commons.dbutils.QueryRunner类:用来执行sql语句
* org.apache.commons.dbutils.DbUtils类:用来释放资源
* org.apache.commons.dbutils.ResultSetHandler接口:用来接收查询的结果集
*
* QueryRunner类
* 构造方法
* QueryRunner() 空参数构造方法
* 如果使用空参数构造方法创建对象,那么使用update方法和query方法时,必须传递conn对象
* QueryRunner(DataSource ds) 带连接池的构造方法
* 如果使用的是带连接池的构造方法,那么QueryRunnery类会自动的从连接池中获取conn对象
* 使用完毕会自动把conn对象归还给连接池
* 使用update方法和query方法时就必须传递conn对象了
* 成员方法:
* 用来执行insert,update,delete语句的方法:update
* int update(Connection conn, String sql, Object... params) 给空参数构造方法使用
* int update(String sql, Object... params) 给带连接池的构造方法使用
* 方法的参数:
* Connection conn:数据库的连接对象,可以使用连接池的工具类获取,给空参数构造方法使用
* String sql:要执行的sql语句,可以使用?占位符
* Object... params:?占位符的实际参数
* 方法的返回值:
* int:影响数据库的有效行数
* 用来执行select语句的方法:query
* <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) 给空参数构造方法使用
* <T> T query(String sql, ResultSetHandler<T> rsh, Object... params) 给带连接池的构造方法使用
* 方法的参数:
* Connection conn:数据库的连接对象,可以使用连接池的工具类获取,给空参数构造方法使用
* String sql:要执行的sql语句,可以使用?占位符
* Object... params:?占位符的实际参数
* ResultSetHandler<T> rsh:是一个接口,用来接收查询的结果集,可以传递ResultSetHandler的9种实现类
* 方法的返回值:
* <T> T:是一个泛型,query方法传递的ResultSetHandler接口的实现类不同,对查询结果有不同的处理方式
* 返回的查询结果也不同,所以使用一个泛型;传递哪个实现类对象,就返回那种结果集
* QueryRunner的使用步骤
* 1.创建QueryRunner对象
* 2.调用QueryRunner中的方法update/query执行sql语句,获取结果
* 3.处理结果
1.1创建DbUtils的增删改的工具类
public class Demo01DbUtils { public static void main(String[] args) throws SQLException { //insert(); //update(); delete(); } /* * 使用QueryRunnery对象对数据库表中的数据进行删除 */ private static void delete() throws SQLException { //1.创建QueryRunner对象(使用带连接池的) QueryRunner qr = new QueryRunner(C3P0UtilsXML.getDataSource()); //2.调用QueryRunner中的方法update/query执行sql语句,获取结果 String sql = "DELETE FROM category WHERE cid IN(?,?,?)"; int row = qr.update(sql, 1,8,10); //3.处理结果 if(row>0){ System.out.println(row+"行数据删除成功!"); }else{ System.out.println("数据删除失败!"); } } /* * 使用QueryRunnery对象对数据库表中的数据进行修改 */ private static void update() throws SQLException { //1.创建QueryRunner对象(使用带连接池的) QueryRunner qr = new QueryRunner(C3P0UtilsXML.getDataSource()); //2.调用QueryRunner中的方法update/query执行sql语句,获取结果 String sql = "UPDATE category SET cname=? WHERE cid = ?"; //多个?占位符的实际参数可以写在第一个Object数组中(可变参数底层就是一个数组) Object[] params = {"零食",4}; int row = qr.update(sql, params); //3.处理结果 System.out.println(row); } /* * 使用QueryRunnery对象往数据库表中添加数据 */ private static void insert() throws SQLException { //1.创建QueryRunner对象(使用空参数的) QueryRunner qr = new QueryRunner(); //获取数据库连接对象,使用连接池获取 Connection conn = C3P0UtilsXML.getConnection(); //2.调用QueryRunner中的方法update/query执行sql语句,获取结果 String sql = "INSERT INTO category(cname) VALUES(?)"; int row = qr.update(conn, sql, "玩具"); //3.处理结果 System.out.println(row); } }
1.2创建DbUtils的查的工具类(beanHandler(qr);beanListHandler(qr);scalarHandler(qr);这三种是重要的,其他的了解)
package cn.itcast.demo04.DbUtils; import java.sql.SQLException; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.ArrayHandler; import org.apache.commons.dbutils.handlers.ArrayListHandler; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.ColumnListHandler; import org.apache.commons.dbutils.handlers.KeyedHandler; import org.apache.commons.dbutils.handlers.MapHandler; import org.apache.commons.dbutils.handlers.MapListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; import cn.itcast.demo01.Utils.C3P0UtilsXML; import cn.itcast.demo03.domain.Category; /* * 使用QueryRunner对数据库表中的数据进行查询 * <T> T query(String sql, ResultSetHandler<T> rsh, Object... params) 给带连接池的构造方法使用 */ public class Demo02DbUtils { public static void main(String[] args) throws SQLException { //创建QueryRunner对象,传递连接池 QueryRunner qr = new QueryRunner(C3P0UtilsXML.getDataSource()); //arrayHandler(qr); //arrayListHandler(qr); beanHandler(qr); beanListHandler(qr); scalarHandler(qr); //mapHandler(qr); //mapListHandler(qr); //columnListHandler(qr); //keyedHandler(qr); } /* * 使用QueryRunner对数据库表中的数据进行查询 * 结果集使用KeyedHandler(了解) * * 构造方法: * KeyedHandler() 默认使用第一列 * KeyedHandler(int columnIndex)指定列的索引 * KeyedHandler(String columnName) 指定列名 * * KeyedHandler会把查询出来的每一行数据,存储到一个Map集合中 * key:字段名称,cid,cname;使用String类型 * value:字段的值,2,家电;数据类型有多种,使用Object类型 * 多行数据,存储到多个Map集合中 * key:构造方法中指定的列,不指定默认使用第一列;每列的数据类型不同,使用Object类型 * value:存储每行数据的Map集合 Map<String,Object> * * query方法的返回值: * 指定的列 存储每行数据的Map集合 * Map<Obejct,Map<String,Object>> */ private static void keyedHandler(QueryRunner qr) throws SQLException { //使用QueryRunner中的方法query执行查询的sql语句 //拼接查询的sql语句 String sql = "SELECT * FROM category"; //Map<Object,Map<String,Object>> mapmap = qr.query(sql, new KeyedHandler());//外层的Map集合的key默认使用第一列 //Map<Object,Map<String,Object>> mapmap = qr.query(sql, new KeyedHandler(2));//外层的Map集合的key 指定列的索引为2 cname Map<Object,Map<String,Object>> mapmap = qr.query(sql, new KeyedHandler("cid"));//外层的Map集合的key 指定列名 cname //处理结果集 //遍历外层存储多行数据的Map集合,获取每一行数据 for(Object wcKey:mapmap.keySet()){ //使用wcKey获取外层的值,就是存储每行数据的Map集合 Map<String,Object> map = mapmap.get(wcKey); //遍历存储每行数据的Map集合 for(String key : map.keySet()){ //根据key获取value值 Object value = map.get(key); System.out.print("外层Map集合指定的列:"+wcKey+"-->"+key+"="+value+"\t"); } System.out.println(); } } /* * 使用QueryRunner对数据库表中的数据进行查询 * 结果集使用ColumnListHandler(掌握) * ColumnListHandler用来查询指定的列 * * 构造方法: * ColumnListHandler() 空参数,默认查询第一列数据 * ColumnListHandler(int columnIndex) :传递列的索引,从1开始 * ColumnListHandler(String columnName) :传递列名,字段名 * * query方法的返回值: * 查询的列不同,数据类型有多种,使用Object类型 * 每列有多个数据,存储到一个List集合 * List<Object> * */ private static void columnListHandler(QueryRunner qr) throws SQLException { //使用QueryRunner中的方法query执行查询的sql语句 //拼接查询的sql语句 String sql = "SELECT * FROM category"; //List<Object> list = qr.query(sql, new ColumnListHandler());//默认查询第一列数据 cid //List<Object> list = qr.query(sql, new ColumnListHandler(2));//传递列的索引 2 cname List<Object> list = qr.query(sql, new ColumnListHandler("cid"));//传递列名称 cname //处理结果集 for (Object o : list) { System.out.println(o); } } /* * 使用QueryRunner对数据库表中的数据进行查询 * 结果集使用MapListHandler(了解) * * 把结果的每一行数据,存在在Map集合中 * key:字段名称,cid,cname;使用String类型 * value:字段的值,2,家电;数据类型有多种,使用Object类型 * 多行数据存储到多个Map集合中 * 多个Map集合存储到List集合 * * query方法的返回值: * List<Map<String,Object>> */ private static void mapListHandler(QueryRunner qr) throws SQLException { //使用QueryRunner中的方法query执行查询的sql语句 //拼接查询的sql语句 String sql = "SELECT * FROM category"; List<Map<String,Object>> list = qr.query(sql, new MapListHandler()); //处理结果集 //遍历存储多行数据的List集合,获取每一行数据 for (Map<String, Object> map : list) { //遍历存储每行数据的Map集合 for(Map.Entry<String, Object> entry: map.entrySet()){ //使用Entry中的方法getKey和getValue获取健和值 String key = entry.getKey(); Object value = entry.getValue(); System.out.print(key+"="+value+"\t"); } //打印完没行数据之后换行 System.out.println(); } } /* * 使用QueryRunner对数据库表中的数据进行查询 * 结果集使用MapHandler(了解) * * MapHandler会把查询的多行结果的第一行取出来存储到一个Map集合中 * key:字段名称,cid,cname;使用String类型 * value:字段的值,2,家电;数据类型有多种,使用Object类型 * query方法的返回值: * Map<String,Object> */ private static void mapHandler(QueryRunner qr) throws SQLException { //使用QueryRunner中的方法query执行查询的sql语句 //拼接查询的sql语句 String sql = "SELECT * FROM category"; Map<String,Object> map = qr.query(sql, new MapHandler()); //处理结果集 Set<String> set = map.keySet(); for(String key : set){ //根据key获取value值 Object value = map.get(key); System.out.print(key+"="+value+"\t"); } } /* * 使用QueryRunner对数据库表中的数据进行查询 * 结果集使用ScalarHandler(重点) * * ScalarHandler用于查询的sql语句返回结果是一个单一的值 * 1.聚合函数:sum(),count(),max(),min(),avg() * SELECT COUNT(*) FROM category * 2.查询某一行的某一个字段 * SELECT cname FROM category WHERE cid = ?; * query方法的返回值: * 查询的结果数据类型有多种,返回值只用Object */ private static void scalarHandler(QueryRunner qr) throws SQLException { //使用QueryRunner中的方法query执行查询的sql语句 //拼接查询的sql语句 //String sql = "SELECT COUNT(*) FROM category";//3 //Object obj = qr.query(sql, new ScalarHandler()); String sql = "SELECT cname FROM category WHERE cid = ?";//家电 Object obj = qr.query(sql, new ScalarHandler(), 2); //处理结果集 System.out.println(obj); } /* * 使用QueryRunner对数据库表中的数据进行查询 * 结果集使用BeanListHandler(重点中的重点) * * 构造方法: * BeanListHandler(Class<T> type) 传递javabean的class文件对象,传递Category.class * * BeanListHandler会把结果集的每一行数据存储到一个javabean中 * 多行数据存储到多个javabean中 * 多个javabean存储到一个List集合中 * * BeanListHandler内部也会通过反射技术创建javabean对象 * * 注意: * javabean对象中必须有空参数构造方法,BeanHandler会使用空参数构造方法创建对象 * * query方法的返回值: * List<javabean> List<Category> */ private static void beanListHandler(QueryRunner qr) throws SQLException { //使用QueryRunner中的方法query执行查询的sql语句 //拼接查询的sql语句 String sql = "SELECT * FROM category where cid in (?,?,?)"; //Object[] params = {2,3,4}; Object[] params = {20,30,40}; List<Category> list = qr.query(sql, new BeanListHandler<>(Category.class), params); System.out.println(list);//查询不到数据,返回的是一个空List集合 //处理结果集 for (Category c : list) { System.out.println(c); } } /* * 使用QueryRunner对数据库表中的数据进行查询 * 结果集使用BeanHandler(重点) * * 构造方法: * BeanHandler(Class<T> type) 传递javabean的class文件对象,传递Category.class * * BeanHandler会把查询的多行结果中的第一行取出来,存储到一个javabean对象中 * BeanHandler会根据参数传递的javabean的class文件对象,使用反射技术创建javabean对象 * 使用反射技术中的setXXX方法,给javabean对象赋值 * Object(Category) obj = clazz.newInstance(); * Method setXXXMethod = clazz.getMethod("setXXX"); * setXXXMethod.invoke(obj,"1"); * setXXXMethod.invoke(obj,"服装"); * * 注意: * javabean对象中必须有空参数构造方法,BeanHandler会使用空参数构造方法创建对象 * * query方法的返回值:传递哪个javabean对象,就返回对应的对象 * Category query(Category.class) */ private static void beanHandler(QueryRunner qr) throws SQLException { //使用QueryRunner中的方法query执行查询的sql语句 //拼接查询的sql语句 String sql = "SELECT * FROM category where cid in (?,?,?)"; Category c = qr.query(sql, new BeanHandler<>(Category.class), 1,2,3); //处理结果集 System.out.println(c); } /* * 使用QueryRunner对数据库表中的数据进行查询 * 结果集使用ArrayListHandler(了解) * 把查询的每一行数据存储到一个Object类型的数组中 * 多行数据存储到多个Object数组中 * 多个Object数组存到ArrayList集合中 * query方法的返回值: * ArrayList<Object[]> */ private static void arrayListHandler(QueryRunner qr) throws SQLException { //使用QueryRunner中的方法query执行查询的sql语句 //拼接查询的sql语句 //String sql = "SELECT * FROM category"; String sql = "SELECT * FROM category where cid >10"; List<Object[]> list = qr.query(sql, new ArrayListHandler()); //System.out.println(list.getClass());//class java.util.ArrayList //System.out.println(list);//[] 如果没有查询到数据,那么会返回一个空集合 System.out.println(list.size());//0 如果没有查询到数据,那么会返回一个空集合 //处理结果集 //遍历存储每行数据的List集合,获取每一行数据(Object[]) for (Object[] arr : list) { //遍历存储没行数据的数组 for (Object o : arr) { System.out.print(o+"\t"); } //打印完每行数据之后换行 System.out.println(); } } /* * 使用QueryRunner对数据库表中的数据进行查询 * 结果集使用ArrayHandler(了解) * 把查询的多行结果的第一行取出来,存储到一个数组 * 每列的数据类型不同,所以数组使用Object类型 * query方法的返回值: * Object[] */ private static void arrayHandler(QueryRunner qr) throws SQLException { //使用QueryRunner中的方法query执行查询的sql语句 //拼接查询的sql语句 //String sql = "SELECT * FROM category"; String sql = "SELECT * FROM category where cid >10"; Object[] arr = qr.query(sql, new ArrayHandler()); System.out.println(arr);//null 没有查询到数据返回的是null //处理结果集 for (Object o : arr) { System.out.print(o+"\t"); } } }