尚硅谷之JDBC
(4)是否需要传递Connection?
A:不需要传递Connection对象:
前提是不考虑事务而且QueryRunner对象创建时指定数据源,这样在QueryRunner的所有增删改查方法中都会从数据源中自己获取连接
B:必须传递Connection对象
如果有事务,必须传递Connection对象,因为同一个事务的多条语句必须在一个Connection连接中完成
public static void main(String[] args) throws Exception{ //1、通过数据库连接池来获取连接 DataSource ds = new ComboPooledDataSource("mypool"); //2、传sql,并执行,并接收结果 String sql = "insert into t_goods(pname,price,description)values(?,?,?)"; QueryRunner qr = new QueryRunner(ds); int len = qr.update(sql, "电源",78,"充电必备");//自己到数据库连接池中拿连接 System.out.println(len>0?"添加成功":"添加失败"); } |
public static void main(String[] args)throws Exception{ //1、通过数据库连接池来获取连接 DataSource ds = new ComboPooledDataSource("mypool"); QueryRunner qr = new QueryRunner(); //从web页面传过来,有这样的数据 int uid = 1; int[] pids = {5,6,7}; int[] amount = {1,1,1}; double[] price = {560,58,68}; String sql1 = "insert into t_order(ordertime,sumprice,uid)values(now(),?,?)"; String sql2 = "insert into t_detail(oid,pid,amount)values(?,?,?)"; //2、获取连接 Connection conn = null; try { conn = ds.getConnection(); conn.setAutoCommit(false);//手动提交事务 double sumprice = 0; for(int i=0; i<amount.length; i++){ sumprice += amount[i] * price[i]; } //返回的是自增的键值 Object object = qr.insert(conn, sql1, new ScalarHandler(), sumprice,uid); Object[][] params = new Object[pids.length][3]; for(int i=0;i<params.length;i++){ for(int j=0; j<params[i].length; j++){ params[i][0] = object;//订单编号 params[i][1] = pids[i];//产品编号 params[i][2] = amount[i];//每一件产品的数量 } } qr.insertBatch(conn, sql2, new ScalarHandler(), params);//如果没有自增的键值,那么返回值是null //提交事务 conn.commit(); } catch (Exception e) { //回滚事务 if(conn!=null){ conn.rollback(); } } finally{ if(conn!=null){ //在关闭之前,要设置conn的事务方式为自动提交 conn.setAutoCommit(true); //关闭连接 DbUtils.closeQuietly(conn); } } } |
使用QueryRunner类实现查询
- public Object query(Connection conn, String sql, ResultSetHandler rsh,Object... params) throws SQLException:执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句的置换参数。该方法会自行处理 PreparedStatement 和 ResultSet 的创建和关闭。
- public Object query(String sql, ResultSetHandler rsh, Object... params) throws SQLException: 几乎与第一种方法一样;唯一的不同在于它不将数据库连接提供给方法,并且它是从提供给构造方法的数据源(DataSource) 或使用的setDataSource 方法中重新获得 Connection。
- public Object query(Connection conn, String sql, ResultSetHandler rsh) throws SQLException : 执行一个不需要置换参数的查询操作。
- public Object query( String sql, ResultSetHandler rsh) throws SQLException : 执行一个不需要置换参数的查询操作。
ResultSetHandler接口
该接口用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式。
ResultSetHandler 接口提供了一个单独的方法:Object handle (java.sql.ResultSet rs)
该方法的返回值将作为QueryRunner类的query()方法的返回值。
@Test public void testResultSetHandler() { // 1.创建QueryRunner的实例 QueryRunner qr = new QueryRunner(); Connection conn = null; try { // 2.获取连接 conn = JDBCTools.getConnection(); class MyResultSetHandler implements ResultSetHandler{ @Override public Object handle(ResultSet rs) throws SQLException { Student stu = new Student(); if (rs.next()) { stu.setId(rs.getInt(1)); stu.setSname(rs.getString(2)); stu.setSex(rs.getString(3)); stu.setMajor(rs.getString(4)); stu.setClasses(rs.getString(5)); } return stu; } } String sql = "select sno,sname,sex,major,classes from t_stu where sno =?"; // 3、使用query方法 // QueryRunner 的 query 方法的返回值取决于其 ResultSetHandler 参数的handle 方法的返回值 Object obj = qr.query(conn, sql, new MyResultSetHandler(),1); System.out.println(obj); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCTools.free(null, null, conn); } } |
- ArrayHandler:把结果集中的第一行数据转成对象数组。
- ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
- BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
- BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
- ColumnListHandler:将结果集中某一列的数据存放到List中。
- KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
- MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
- MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List