一.PrepareStatment(pstmt)
pstmt的预编译模式可以在多次sql需要多次执行相同操作但是参数产生变化的时候,只需要在第一次把SQL语句写好,
并且通过pstmt.addBatch();来进行区分.
例如:
//想多次对stu表的不同姓名的人的年龄进行修改
PrepareStatment pstmt = conn.prepareStatment(“UPDATE stu SET age=? WHERE name=?;”);
pstmt.setInt(1,20);
//?表示占位符,当参数需要变化时,用占位符表示,并且要插入对应类型的参数,表中age的类型为int,所以setInt
pstmt.setString(2,"张三")
//()中的1和2代表SQL语句中的占位符?的位置,1代表第一个?,2代表第二个?
pstmt.addBatch();//此时通过addBatch来表示上面的查询语句要存在缓存中,最后执行
pstmt.setInt(1,24);
pstmt.setString(2,"李四");
pstmt.addBatch();
//此时插入第二个人的信息,并且通过addBatch来截断,并且把第二个人的信息也存到缓存中,最后执行
pstmt.addBatch("DELETE FROM stu WHERE name = '王五’”);
//addBatch也可以直接写SQL数据,并且也直接存到缓存中最后执行
pstmt.executeBatch();//通过executeBatch来执行上述所有的sql操作.
二.事务操作
1.将数据库的几个操作封装成一个事务,只有当左右条件都执行完毕没有错误,才会写入数据库
例如:银行转账,A向B转账,A的数据库执行了修改操作,如果B没有收到钱的话,A与B的数据库都不会发生变化
Connection conn = null;
try {//通过将整个需要作为一个事务操作的sql语句一起选中,通过try catch包装成一个事务,在系统之前捕获异常
conn = Jdbcutil.getConnection();
//设置提交方式为手动提交
//开启事务,设置提交方式的自动为false也就是将自动提交改为手动
conn.setAutoCommit(false);
//创建一个预处理对象
PreparedStatement pstmt = conn.prepareStatement("UPDATE money SET m =? WHERE `name`=?");
pstmt.setObject(1,700);
pstmt.setObject(2,"曹云金");
pstmt.addBatch();
QueryRunner qr = new QueryRunner();
String name = "曹云金";
int a = 100/0;
//模拟转账过程中发生失败,程序会抛出异常这时候不会向下运行,之前调到下面的运行回滚操作,并且输出"转账失败"
pstmt.setObject(1,1300);
pstmt.setObject(2,"郭德纲");
pstmt.addBatch();
pstmt.executeBatch();
conn.commit();
} catch (Exception e) {
//回滚到事务开始的状态
try {
conn.rollback();
System.out.println("转账失败");
} catch (SQLException e1) {
e1.printStackTrace();
}
}
三.DButils-QueryRunner
1.dbutils是Apache提供的一个开源的方便操作jdbc的jar包
2.QueryRunner类是该jar包的核心类,所有的数据库操作方法都在此类中,增删改查都是使用这个类
QueryRunner操作数据库增删改查分为两种:
(1)update(增,删,改)
Connection conn = Jdbcutil.getConnection();
//建立一个QueryRunner对象,用来执行SQL语句
QueryRunner qr = new QueryRunner();
//调用update方法,可以执行增,删,改等sql语句
qr.update(conn, "insert into stu values(null,'张益达',55)");
/*qr.update(数据库连接对象,sql语句,如果sql语句中有占位符-这里可以插入参数(可以插入动态参数))*/
conn.close();//关闭连接
(2)query(查询)
1.query方法接收的是ResultSetHandler接口类型的对象,这使得我们可以传入不同的该接口的实现类对象,这样就可以根据我们的需求传入参数,也就是说这个接口是我们与query方法之间的协议,约定,当我们传入的对象实现了ResultSetHandler接口时,QueryRunner就能帮我们将结果集中的数据封装起来,返回给我们,而且因为这里是接口的引用作为参数,那么我们也可以自定义一个类T实现ResultSetHandler接口,将T的对象传入进去,如何操作ResultSet中的数据,我们可以写在T类复写的handle方法中,这也就是ResultSetHandler接口提供给我们的可扩展性.
Connection conn = Jdbcutil.getConnection();
QueryRunner qr = new QueryRunner();
String sql = "select * from stu;";
Stu query = qr.query(conn, sql, new ResultSetHandler<Stu>() {
@Override
public Stu handle(ResultSet resultSet) throws SQLException {
while (resultSet.next()) {
Stu stu = new Stu();
stu.setName(resultSet.getString(2));
System.out.println(stu.getName());
}
return null;
}
});
1)BeanHandler: 查询返回单个对象
Stu query = qr.query(conn, sql, new BeanHandler<Stu>(Stu.class));
2)BeanListHandler: 查询返回list集合,集合元素是指定的对象
List<Stu> query = qr.query(conn, sql, new BeanListHandler<>(Stu.class));
3) ArrayHandler, 查询返回结果记录的第一行,封装对对象数组, 即返回:Object
Object[] query1 = qr.query(conn, sql, new ArrayHandler());
4)ArrayListHandler, 把查询的每一行都封装为对象数组,再添加到list集合中
List<Object[]> query = qr.query(conn, sql, new ArrayListHandler());
5) ScalarHandler (通常单行单列的时候用)
Object query1 = qr.query(conn, sql, new ScalarHandler<>());
6) MapHandler 查询返回结果的第一条记录封装为map
List<Map<String, Object>> query = qr.query(conn, sql, new MapListHandler());