java数据库编程,JDBC连接(原生数据库连接)
JDBC严格来讲不属于一门技术,它属于一种服务。所有的操作流程都是固定的。JDBC是java提供的数据库操作的一个标准(它就是一组相关的标准接口),而不同的数据库生产商要依此标准进行自己的数据库操作类的的具体实现提供。
1.1 JDBC 连接
在实际的项目开发中,JDBC的使用一共分为以下几种形式:
(1)JDBC-ODBC桥连接形式:利用微软提供的ODBC进行数据库的连接操作,而后JDBC访问ODBC的函数库实现数据的操作;流程:程序 -> JDBC -> ODBC ->数据库,这样的操作性能很差,但是支持度是最高的,并且不需要配置任何第三方驱动程序;
(2)JDBC连接形式:利用不同数据库驱动的生产商提供的JDBC驱动程序进行数据库的操作;流程:程序 -> JDBC -> 数据库,性能好;
(3)JDBC 网络连接;流程:程序 -> JDBC连接协议 -> 数据库,实际使用是最多的。
(4)JDBC协议连接,使用特定数据库生产商提供的协议标准进行数据库的操作,难度较大,一般不用。
如果要进行JDBC操作,可使用java.sql 包进行开发,在这个包中就由以下几个类和接口组成:
类:DriverManager
接口:Connection、Statement、PreparedStatement、ResultSet。
JDBC操作流程分如下4步:
(1)加载数据库驱动;
(2)依靠DriverManager类连接数据库;
(3)进行数据库操作(CRUD)依靠Statement、PreparedStatement、ResultSet完成;
(4)关闭数据库连接。
下面按照指定的步骤来实现数据库的连接操作。
1、配置数据库驱动程序
本次将使用oracle数据库提供的数据库连接的支持,但是如果要想进行oracle的连接请一定要保证打开两个服务:监听、实例服务;随后需要配置数据库的驱动程序,引入ojdbc14.jar包
2、驱动加载
所有的数据库驱动加载是想容器加载,利用Class.forName()进行加载,Oracle 的驱动程序类名称:oracle.jdbc.driver.OracleDriver。
如果没有配置驱动程序则会出现找不到类的异常。
private static final String DRIVER =“oracle.jdbc.driver.OracleDriver”;
//加载数据库驱动
Class.forName(DRIVER);//向容器加载驱动连接类
3、数据库连接操作
如果要进行数据库的连接操作那么一定使用的java.sql.DriverManager程序类,那么这个类没有定义构造方法(私有化),所以如果想要操作这个类看可以使用他的静态方法;
连接数据库:public static Connection getConnection(String url, String user, String password) throws SQLException ;
这个方法返回一个Connection接口对象,每一个Connection接口对象都表示一个数据库连接,方法需要三个参数:
url:连接地址,jdbc:oracle:thin:@ip:port:SID
user:用户名
password:密码
4.关闭数据库连接
只要是牵扯到资源操作,那么一定要解决的问题:必须关闭资源,关闭资源就等同于释放资源,所以提供了AutoCloseable接口,但是这个接口不能够用正常的思路调用。
范例:使用AutoCloseable
package day2;
class MyAuto implements AutoCloseable{
@Override
public void close() throws Exception {
System.out.println("该资源被关闭!!!!");
}
public void print(){
System.out.println("正常访问!!!");
}
}
public class AutoTest {
public static void main(String[] args) {
try (MyAuto myAuto = new MyAuto()){//要在try对象中实例化对象
myAuto.print();//正常执行类的操作
}catch (Exception e){
e.printStackTrace();
}
}
}
正常访问!!!
该资源被关闭!!!!
AutoCloseable这种使用形式虽然看起来是自动完成了操作,但是用的几率不高;
范例:数据库连接
package day2;
import java.sql.Connection;
import java.sql.DriverManager;
public class TestDemo {
private static final String DRIVER_NAME ="oracle.jdbc.driver.OracleDriver";
private static final String URL ="jdbc:oracle:thin:@ip:1521/pdbcore";
private static final String USER ="user";
private static final String PASSWORD ="password";
public static void main(String[] args) throws Exception {
//第一步:加载数据库驱动
Class.forName(DRIVER_NAME);//向容器加载驱动连接类
//第二部:取得数据库连接对象
Connection con = DriverManager.getConnection(URL,USER,PASSWORD);
System.out.println(con);
//第三部:关闭数据库连接
con.close();
}
}
思考:为什么java.sql.Connection接口呀通过DriverManager类打开?
整个数据库连接对象的取得使用的设计模式就是工厂设计模式。
1.2 利用Statement接口实现数据的CURD操作
java.sql.Connection接口只是负责数据库的连接使用,它不具备数据的操作能力,只有ava.sql.Statement具有数据操作能力。通过Connection中的方法取得Statement对象。方法如下:
实例化Statement对象:public Statement createStatement() throws SQLException
但是如果使用Statement大部分情况下操作都是DML,所以在Statement接口中提供有如下两种方法:
数据更新操作: public int executeUpdate(String sql) throws SQLException,在执行更新操作中返回的int数据是该更新影响的行数。
数据查询操作: public ResultSet executeQuery(String sql) throws SQLException
创建序列
create SEQUENCE trading.myseq;
创建表:
drop table trading.member_dp purge;
create table trading.member_dp(
mid number,
name VARCHAR2(50),
age number(3),
birthday date,
note clob,
constraint pk_mid primary key(mid)
);
1.3 数据更新操作
数据更新分为:INSERT、UPDATE、DELETE三种形式。
范例:增加数据
insert into trading.member_dp (mid,name,age,birthday,note)
values(
trading.myseq.nextval,'张三',20,to_date('2002-01-06','yyyy-mm-dd'),'一个大学生'
)
package day2;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class TestDemo {
private static final String DRIVER_NAME ="oracle.jdbc.driver.OracleDriver";
private static final String URL ="jdbc:oracle:thin:@ip:1521/pdbcore";
private static final String USER ="USER";
private static final String PASSWORD ="PASSWORD";
public static void main(String[] args) throws Exception {
//第一步:加载数据库驱动
Class.forName(DRIVER_NAME);//向容器加载驱动连接类
//第二部:取得数据库连接对象
Connection con = DriverManager.getConnection(URL,USER,PASSWORD);
System.out.println(con);
//第三部,获取数据库操作
Statement statement = con.createStatement();//创建数据库操作
String sql ="insert into trading.member_dp (mid,name,age,birthday,note)\n" +
"values\n" +
"(trading.myseq.nextval,'张三',20,to_date('2002-01-06','yyyy-mm-dd'),'一个大学生')";
int len = statement.executeUpdate(sql);//影响的行数
System.out.println("影响的行数:"+len);
//第四部:关闭数据库连接
con.close();
}
}
范例:数据更新
package day2;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class TestDemo {
private static final String DRIVER_NAME ="oracle.jdbc.driver.OracleDriver";
private static final String URL ="jdbc:oracle:thin:@ip:1521/pdbcore";
private static final String USER ="USER";
private static final String PASSWORD ="PASSWORD";
public static void main(String[] args) throws Exception {
//第一步:加载数据库驱动
Class.forName(DRIVER_NAME);//向容器加载驱动连接类
//第二部:取得数据库连接对象
Connection con = DriverManager.getConnection(URL,USER,PASSWORD);
System.out.println(con);
//第三部,获取数据库操作
Statement statement = con.createStatement();//创建数据库操作
String sql ="update trading.member_dp a set a.name='李思',a.age=15,a.birthday =to_date('2007-01-06','yyyy-mm-dd') where a.mid=2";
int len = statement.executeUpdate(sql);//影响的行数
System.out.println("影响的行数:"+len);
//第四部:关闭数据库连接
con.close();
}
}
范例:删除数据
package day2;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class TestDemo {
private static final String DRIVER_NAME ="oracle.jdbc.driver.OracleDriver";
private static final String URL ="jdbc:oracle:thin:@ip:1521/pdbcore";
private static final String USER ="USER";
private static final String PASSWORD ="PASSWORD";
public static void main(String[] args) throws Exception {
//第一步:加载数据库驱动
Class.forName(DRIVER_NAME);//向容器加载驱动连接类
//第二部:取得数据库连接对象
Connection con = DriverManager.getConnection(URL,USER,PASSWORD);
System.out.println(con);
//第三部,获取数据库操作
Statement statement = con.createStatement();//创建数据库操作
String sql ="delete trading.member_dp a where a.mid between 3 and 5";
int len = statement.executeUpdate(sql);//影响的行数
System.out.println("影响的行数:"+len);
//第四部:关闭数据库连接
con.close();
}
}
1.4 数据查询操作
在进行数据查询操作的过程中,最麻烦的问题是需要将所有查询结果进行保留,而程序操作的只是这些查询结果,为了保存这样的查询结果,使用java.sql.ResultSet接口,在ResultSet处理结果的时候实际上是根据数据类型进行处理的。
范例:查询全部
package day2;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Date;
public class TestDemo {
private static final String DRIVER_NAME ="oracle.jdbc.driver.OracleDriver";
private static final String URL ="jdbc:oracle:thin:@ip:1521/pdbcore";
private static final String USER ="USER";
private static final String PASSWORD ="PASSWORD";
public static void main(String[] args) throws Exception {
//第一步:加载数据库驱动
Class.forName(DRIVER_NAME);//向容器加载驱动连接类
//第二部:取得数据库连接对象
Connection con = DriverManager.getConnection(URL,USER,PASSWORD);
System.out.println(con);
//第三部,获取数据库操作
Statement statement = con.createStatement();//创建数据库操作
String sql ="select mid,name,age,birthday,note from trading.member_dp";
ResultSet rs = statement.executeQuery(sql);
//知道循环条件,但是不知道循环次数,选择while循环
while (rs.next()){//移动指针,同时判断是否还有数据行
int mid = rs.getInt("mid");
String name = rs.getString("name");
int age = rs.getInt("age");
Date birthDay = rs.getDate("birthday");
String note = rs.getString("note");
System.out.println("主键:" + mid + ",姓名:" + name + ",年龄:" + age + ",生日:" + birthDay + ",备注:" + note);
}
//第四部:关闭数据库连接
con.close();
}
}
主键:2,姓名:李思,年龄:15,生日:2007-01-06,备注:一个大学生
主键:1,姓名:张三,年龄:20,生日:2002-01-06,备注:一个大学生
主键:6,姓名:王大同,年龄:10,生日:2012-12-28,备注:小学生
注:以上的代码sql中已经都明确写出了要查询的列名称,所以在使用getXxx()方法读取数据的时候就可以不写列名称,直接编写序号就可以了
while (rs.next()){//移动指针,同时判断是否还有数据行
int mid = rs.getInt(1);
String name = rs.getString(2);
int age = rs.getInt(3);
Date birthDay = rs.getDate(4);
String note = rs.getString(5);
System.out.println("主键:" + mid + ",姓名:" + name + ",年龄:" + age + ",生日:" + birthDay + ",备注:" + note);
}
1.5 Statement存在的问题
Statement有一个最为严重的问题,在于:所有的操作都需要使用完整的sql语句进行,那么这个时候如果假设数据是由用户自己输入的,就会产生问题。
范例:Statement存在的问题
package day2;
import java.sql.*;
import java.util.Date;
public class TestDemo {
private static final String DRIVER_NAME ="oracle.jdbc.driver.OracleDriver";
private static final String URL ="jdbc:oracle:thin:@ip:1521/pdbcore";
private static final String USER ="trading";
private static final String PASSWORD ="PASSWORD";
public static void main(String[] args) throws Exception {
//第一步:加载数据库驱动
Class.forName(DRIVER_NAME);//向容器加载驱动连接类
//第二部:取得数据库连接对象
Connection con = DriverManager.getConnection(URL,USER,PASSWORD);
System.out.println(con);
//第三部,获取数据库操作
String name = "张海生";
int age = 14;
String birthDay = "2008-08-21";
String note = "帅帅男生";
Statement statement = con.createStatement();//创建数据库操作
String sql ="insert into trading.member_dp (mid,name,age,birthday,note)\n" +
"values\n" +
"(trading.myseq.nextval,'"+name+"',"+age+",to_date('"+birthDay+"','yyyy-mm-dd'),'"+note+"')";
System.out.println(sql);
int len = statement.executeUpdate(sql);
System.out.println("执行条数:" + len);
//PreparedStatement
//第四部:关闭数据库连接
con.close();
}
}
正常插入
如果 String name = "Mr'SMITH";就会报错
insert into trading.member_dp (mid,name,age,birthday,note)
values
(trading.myseq.nextval,'Mr'SMITH',14,to_date('2008-08-21','yyyy-mm-dd'),'帅帅男生')
Exception in thread "main" java.sql.SQLException: ORA-00917: 缺失逗号
在SQL语句中,单引号是作为字符串的标记,所以如果内容本身包含有字符串,那么这种拼凑的处理过程就不能够使用了。
1.6 使用PreparedStatement实现数据库操作
Statement开发中不要使用,永远优先考虑使用PreparedStatement接口,这是Statement的子接口,使用预处理的方式来进行操作。如果想要取得PreparedStatement接口的实例化对象,那么继续用Connection接口完成,在Connection提供有这样一个操作方法:public PreparedStatement prepareStatement(String sql) throws SQLException
所谓的预处理指的是在执行sql语句的时候,是在创建PreparedStatement接口时,而具体的内容使用“?”来进行占位,而后利用一系列的setXxx()方法设置内容。
由于创建PreparedStatement接口的时候就已经准备好了sql语句,所以在执行sql的时候就不再需要传递sql语句了,使用PreparedStatement接口的如下方法实现数据库操作:
更新操作:public int executeUpdate() throws SQLException
查询操作:public ResultSet executeQuery() throws SQLException;
关于数据库中的日期时间描述,在程序中日期时间的描述就是java.util.Date,但是这个类下有三个字类,分别是java.sql.Date、java.sql.Time、java.sql.Timestamp。
如果要想将java.util.Date变为具体的子类对象,那么必须依靠long数据类型:
java.util.Date 类存在有构造:public long getTime();
java.sql.Date类的构造:public Date(long date)
范例:采用PreparedStatement改进以上问题(新增)
package day2;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDemo {
private static final String DRIVER_NAME ="oracle.jdbc.driver.OracleDriver";
private static final String URL ="jdbc:oracle:thin:@ip:1521/pdbcore";
private static final String USER ="trading";
private static final String PASSWORD ="PASSWORD";
public static void main(String[] args) throws Exception {
//第一步:加载数据库驱动
Class.forName(DRIVER_NAME);//向容器加载驱动连接类
//第二部:取得数据库连接对象
Connection con = DriverManager.getConnection(URL,USER,PASSWORD);
System.out.println(con);
//第三部,获取数据库操作
String name = "Mr'SMITH";
int age = 14;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd");
String birthDayStr = "2008-08-21";
Date birthDay = sdf.parse(birthDayStr);
String note = "帅帅男生";
Statement statement = con.createStatement();//创建数据库操作
String sql ="insert into trading.member_dp (mid,name,age,birthday,note) values (trading.myseq.nextval,?,?,?,?)";
PreparedStatement ps = con.prepareStatement(sql);//已经预处理了sql
ps.setString(1,name);
ps.setInt(2,age);
ps.setDate(3,new java.sql.Date(birthDay.getTime()));
ps.setString(4,note);
// System.out.println(sql);
int len = ps.executeUpdate();
System.out.println("执行条数:" + len);
//第四部:关闭数据库连接
con.close();
}
}
范例:采用PreparedStatement改进以上问题(修改)
package day2;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDemo {
private static final String DRIVER_NAME ="oracle.jdbc.driver.OracleDriver";
private static final String URL ="jdbc:oracle:thin:@ip:1521/pdbcore";
private static final String USER ="trading";
private static final String PASSWORD ="PASSWORD";
public static void main(String[] args) throws Exception {
//第一步:加载数据库驱动
Class.forName(DRIVER_NAME);//向容器加载驱动连接类
//第二部:取得数据库连接对象
Connection con = DriverManager.getConnection(URL,USER,PASSWORD);
System.out.println(con);
//第三部,获取数据库操作
int mid = 7;
String name = "Mr张";
int age = 14;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd");
String birthDayStr = "21-03-21";
Date birthDay = sdf.parse(birthDayStr);
String note = "帅帅男生啊啊啊";
Statement statement = con.createStatement();//创建数据库操作
String sql = "update trading.member_dp a set a.name=?,a.age=?,a.birthday=?,a.note=? where a.mid=?";
PreparedStatement ps = con.prepareStatement(sql);//已经预处理了sql
ps.setString(1,name);
ps.setInt(2,age);
ps.setDate(3,new java.sql.Date(birthDay.getTime()));
ps.setString(4,note);
ps.setInt(5,mid);
// System.out.println(sql);
int len = ps.executeUpdate();
System.out.println("执行条数:" + len);
//第四部:关闭数据库连接
con.close();
}
}
新增、修改、删除同理!!!
范例:查询全部
package day2;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDemo {
private static final String DRIVER_NAME ="oracle.jdbc.driver.OracleDriver";
private static final String URL ="jdbc:oracle:thin:@ip:1521/pdbcore";
private static final String USER ="USER";
private static final String PASSWORD ="PASSWORD";
public static void main(String[] args) throws Exception {
//第一步:加载数据库驱动
Class.forName(DRIVER_NAME);//向容器加载驱动连接类
//第二部:取得数据库连接对象
Connection con = DriverManager.getConnection(URL,USER,PASSWORD);
System.out.println(con);
//第三部,获取数据库操作
String sql ="select mid,name,age,birthday,note from trading.member_dp order by mid";
PreparedStatement ps = con.prepareStatement(sql);//已经预处理了sql
ResultSet rs = ps.executeQuery();
//知道循环条件,但是不知道循环次数,选择while循环
while (rs.next()){//移动指针,同时判断是否还有数据行
int mid = rs.getInt("mid");
String name = rs.getString("name");
int age = rs.getInt("age");
Date birthDay = rs.getDate("birthday");
String note = rs.getString("note");
System.out.println("主键:" + mid + ",姓名:" + name + ",年龄:" + age + ",生日:" + birthDay + ",备注:" + note);
}
//第四部:关闭数据库连接
con.close();
}
}
范例:单查询
package day2;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDemo {
private static final String DRIVER_NAME ="oracle.jdbc.driver.OracleDriver";
private static final String URL ="jdbc:oracle:thin:@ip:1521/pdbcore";
private static final String USER ="USER";
private static final String PASSWORD ="PASSWORD";
public static void main(String[] args) throws Exception {
//第一步:加载数据库驱动
Class.forName(DRIVER_NAME);//向容器加载驱动连接类
//第二部:取得数据库连接对象
Connection con = DriverManager.getConnection(URL,USER,PASSWORD);
System.out.println(con);
//第三部,获取数据库操作
String sql ="select mid,name,age,birthday,note from trading.member_dp where mid = ? order by mid";
PreparedStatement ps = con.prepareStatement(sql);//已经预处理了sql
ps.setInt(1,6);
ResultSet rs = ps.executeQuery();
//知道循环条件,但是不知道循环次数,选择while循环
if (rs.next()){//移动指针,同时判断是否还有数据行
int mid = rs.getInt("mid");
String name = rs.getString("name");
int age = rs.getInt("age");
Date birthDay = rs.getDate("birthday");
String note = rs.getString("note");
System.out.println("主键:" + mid + ",姓名:" + name + ",年龄:" + age + ",生日:" + birthDay + ",备注:" + note);
}else {
System.out.println("查询数据不存在!!!");
}
//第四部:关闭数据库连接
con.close();
}
}
范例,模糊查询
package day2;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDemo {
private static final String DRIVER_NAME ="oracle.jdbc.driver.OracleDriver";
private static final String URL ="jdbc:oracle:thin:@ip:1521/pdbcore";
private static final String USER ="USER";
private static final String PASSWORD ="PASSWORD";
public static void main(String[] args) throws Exception {
//第一步:加载数据库驱动
Class.forName(DRIVER_NAME);//向容器加载驱动连接类
//第二部:取得数据库连接对象
Connection con = DriverManager.getConnection(URL,USER,PASSWORD);
//第三部,获取数据库操作
String keyWord ="张";
String sql ="select mid,name,age,birthday,note from trading.member_dp where name like ? order by mid";
PreparedStatement ps = con.prepareStatement(sql);//已经预处理了sql
ps.setString(1,"%"+keyWord+"%");
ResultSet rs = ps.executeQuery();
//知道循环条件,但是不知道循环次数,选择while循环
while (rs.next()){//移动指针,同时判断是否还有数据行
int mid = rs.getInt("mid");
String name = rs.getString("name");
int age = rs.getInt("age");
Date birthDay = rs.getDate("birthday");
String note = rs.getString("note");
System.out.println("主键:" + mid + ",姓名:" + name + ",年龄:" + age + ",生日:" + birthDay + ",备注:" + note);
}
//第四部:关闭数据库连接
con.close();
}
}
主键:1,姓名:张三,年龄:20,生日:2002-01-06,备注:一个大学生
主键:7,姓名:Mr张,年龄:14,生日:0021-01-21,备注:帅帅男生啊啊啊
主键:8,姓名:张海生,年龄:14,生日:2008-08-21,备注:帅帅男生
总结:占位符只能设置数据,不能设置表字段名称。
范例:分页查询
package day2;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDemo {
private static final String DRIVER_NAME ="oracle.jdbc.driver.OracleDriver";
private static final String URL ="jdbc:oracle:thin:@ip:1521/pdbcore";
private static final String USER ="USER";
private static final String PASSWORD ="PASSWORD";
public static void main(String[] args) throws Exception {
//第一步:加载数据库驱动
Class.forName(DRIVER_NAME);//向容器加载驱动连接类
//第二部:取得数据库连接对象
Connection con = DriverManager.getConnection(URL,USER,PASSWORD);
//第三部,获取数据库操作
int currentPage = 1;
int lineSize=3;
String sql ="select * from (" +
"select mid,name,age,birthday,note ,rownum r from trading.member_dp where rownum <=? order by mid" +
") temp where temp.r>?";
PreparedStatement ps = con.prepareStatement(sql);//已经预处理了sql
ps.setInt(1,currentPage * lineSize);
ps.setInt(2,(currentPage-1) * lineSize);
ResultSet rs = ps.executeQuery();
//知道循环条件,但是不知道循环次数,选择while循环
while (rs.next()){//移动指针,同时判断是否还有数据行
int mid = rs.getInt("mid");
String name = rs.getString("name");
int age = rs.getInt("age");
Date birthDay = rs.getDate("birthday");
String note = rs.getString("note");
System.out.println("主键:" + mid + ",姓名:" + name + ",年龄:" + age + ",生日:" + birthDay + ",备注:" + note);
}
//第四部:关闭数据库连接
con.close();
}
}
范例:统计查询
package day2;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDemo {
private static final String DRIVER_NAME ="oracle.jdbc.driver.OracleDriver";
private static final String URL ="jdbc:oracle:thin:@ip:1521/pdbcore";
private static final String USER ="USER";
private static final String PASSWORD ="PASSWORD";
public static void main(String[] args) throws Exception {
//第一步:加载数据库驱动
Class.forName(DRIVER_NAME);//向容器加载驱动连接类
//第二部:取得数据库连接对象
Connection con = DriverManager.getConnection(URL,USER,PASSWORD);
//第三部,获取数据库操作
String sql ="select count(1) from trading.member_dp";
PreparedStatement ps = con.prepareStatement(sql);//已经预处理了sql
ResultSet rs = ps.executeQuery();
//知道循环条件,但是不知道循环次数,选择while循环
while (rs.next()){//移动指针,同时判断是否还有数据行
int count = rs.getInt(1);
System.out.println("返回行数:"+count);
}
//第四部:关闭数据库连接
con.close();
}
}
1.7 批处理
若干条语句一起执行,在PreparedStatement接口与Statement接口中都定义了批处理的操作方法。
Statement接口中:
(1)追加批处理:public void addBatch( String sql ) throws SQLException;
(2)执行批处理:public int[] executeBatch() throws SQLException;
PreparedStatement接口:
(1)追加批处理:public void addBatch() throws SQLException;
(2)执行批处理:public int[] executeBatch() throws SQLException;
范例:
package day2;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class TestDemo {
private static final String DRIVER_NAME ="oracle.jdbc.driver.OracleDriver";
private static final String URL ="jdbc:oracle:thin:@ip:1521/pdbcore";
private static final String USER ="USER";
private static final String PASSWORD ="PASSWORD";
public static void main(String[] args) throws Exception {
//第一步:加载数据库驱动
Class.forName(DRIVER_NAME);//向容器加载驱动连接类
//第二部:取得数据库连接对象
Connection con = DriverManager.getConnection(URL,USER,PASSWORD);
//第三部,获取数据库操作
Statement statement =con.createStatement();//已经预处理了sql
statement.addBatch("insert into trading.member_dp (mid,name,age,birthday,note)\n" +
"values\n" +
"(trading.myseq.nextval,'张si',20,to_date('2002-01-06','yyyy-mm-dd'),'一个大学生')");
statement.addBatch("insert into trading.member_dp (mid,name,age,birthday,note)\n" +
"values\n" +
"(trading.myseq.nextval,'张wu',20,to_date('2002-01-06','yyyy-mm-dd'),'一个大学生')");
statement.addBatch("insert into trading.member_dp (mid,name,age,birthday,note)\n" +
"values\n" +
"(trading.myseq.nextval,'张liu',20,to_date('2002-01-06','yyyy-mm-dd'),'一个大学生')");
statement.addBatch("insert into trading.member_dp (mid,name,age,birthday,note)\n" +
"values\n" +
"(trading.myseq.nextval,'张qi',20,to_date('2002-01-06','yyyy-mm-dd'),'一个大学生')");
statement.addBatch("insert into trading.member_dp (mid,name,age,birthday,note)\n" +
"values\n" +
"(trading.myseq.nextval,'张ba',20,to_date('2002-01-06','yyyy-mm-dd'),'一个大学生')");
statement.addBatch("update trading.member_dp a set a.name='李思',a.age=15,a.birthday =to_date('2007-01-06','yyyy-mm-dd') where a.mid=6");
int[] a = statement.executeBatch();
System.out.println(Arrays.toString(a));
//第四部:关闭数据库连接
con.close();
}
}
[1, 1, 1, 1, 1, 1]
假如有一条语句出现了错误,那么错误代码之前的语句都将正常执行,事物也会提交,这种操作很不合理,所有我们需要事物控制管理。
在JDBC中,所有事物都是自动提交的,要想控制这些操作,在Connection接口中,有几个方法可以实现。
(1)自动提交控制:public void setAutoCommit(boolean autoCommit) throws SQLException;
(2)提交:public void commit() throws SQLException;
(3)回滚:public void rollback() throws SQLException;
package day2;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class TestDemo {
private static final String DRIVER_NAME ="oracle.jdbc.driver.OracleDriver";
private static final String URL ="jdbc:oracle:thin:@ip:1521/pdbcore";
private static final String USER ="USER";
private static final String PASSWORD ="PASSWORD";
public static void main(String[] args) throws Exception {
//第一步:加载数据库驱动
Class.forName(DRIVER_NAME);//向容器加载驱动连接类
//第二部:取得数据库连接对象
Connection con = DriverManager.getConnection(URL,USER,PASSWORD);
//第三部,获取数据库操作
Statement statement =con.createStatement();//已经预处理了sql
con.setAutoCommit(false);//取消事物自动提交
try{
statement.addBatch("insert into trading.member_dp (mid,name,age,birthday,note)\n" +
"values\n" +
"(trading.myseq.nextval,'李jiu',20,to_date('2002-01-06','yyyy-mm-dd'),'一个大学生')");
statement.addBatch("insert into trading.member_dp (mid,name,age,birthday,note)\n" +
"values\n" +
"(trading.myseq.nextval,'李wu',20,to_date('2002-01-06','yyyy-mm-dd'),'一个大学生')");//
// statement.addBatch("insert into trading.member_dp (mid,name,age,birthday,note)\n" +
// "values\n" +
// "(trading.myseq.nextval,'李wu',20,to_date('2002-01-06','yyyy-mm-dd')'一个大学生')");//错误sql代码,缺少一个逗号
statement.addBatch("insert into trading.member_dp (mid,name,age,birthday,note)\n" +
"values\n" +
"(trading.myseq.nextval,'李liu',20,to_date('2002-01-06','yyyy-mm-dd'),'一个大学生')");
statement.addBatch("insert into trading.member_dp (mid,name,age,birthday,note)\n" +
"values\n" +
"(trading.myseq.nextval,'李qi',20,to_date('2002-01-06','yyyy-mm-dd'),'一个大学生')");
statement.addBatch("insert into trading.member_dp (mid,name,age,birthday,note)\n" +
"values\n" +
"(trading.myseq.nextval,'李ba',20,to_date('2002-01-06','yyyy-mm-dd'),'一个大学生')");
statement.addBatch("update trading.member_dp a set a.name='李思',a.age=15,a.birthday =to_date('2007-01-06','yyyy-mm-dd') where a.mid=6");
int[] a = statement.executeBatch();
System.out.println(Arrays.toString(a));
con.commit();//没有错误则正常提交
}catch (Exception e){
e.printStackTrace();
con.rollback();//事物回滚
}
//第四部:关闭数据库连接
con.close();
}
}
[1, 1, 1, 1, 1, 1]