尚硅谷之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