第13章:JDBC编程

13.1 JDBC基础

JDBC定义了一套标准接口,即访问数据库的通用API,不同的数据库厂商根据各自数据库的特点去实现这些接口

13.2 第一个JDBC程序

  1. 引入ojdbc6.jar
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCTest {
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		//1. 要使用JDBC接口,需要先将对应数据库的具体实现类加载进来,jdk6以后不需显示加载驱动
		Class.forName("oracle.jdbc.driver.OracleDriver");
		//2. 根据url连接参数,找到与之匹配的Driver对象,调用其方法获取连接
		Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@192.168.41.128:1521:fcrhost","c50hst","c50hst");
		Statement stmt = conn.createStatement();
		ResultSet rs = stmt.executeQuery("select * from teacher");
		while(rs.next()){
			System.out.println(rs.getString("id"));
			System.out.println(rs.getString("name"));
			System.out.println(rs.getString("title"));
		}
		//3. 依次关闭ResultSet,Statement,Connection等资源
		rs.close();
		stmt.close();
		conn.close();
	}
}

13.3 Connection

代表数据库连接对象,每个Connection代表一个物理连接会话,要想访问数据库,必须先获得数据库连接

13.3.1 方法
1. Statement createStatement()
2. PreparedStatement prepareStatement(String sql)
3. CallableStatement prepareCall(String sql)
4. Savepoint setSavepoint():创建保存点
5. Savepoint setSavepoint(String name):以指定名字创建保存点
6. void setTransactionIsolation(int level):设置事务隔离级别
7. void rollback()
8. void rollback(Savepoint savepoint):回滚事务到指定保存点
9. void setAutoCommit(boolean autoCommit):关闭自动提交,即打开事务
10. void commit():提交事务
11. DatabaseMetaData getMetaData():获取数据库的描述信息

13.4 Statement

可以执行任何语句,只不过使用其不同方法,执行不同种语句时,返回值不同

13.4.1 方法
1. ResultSet executeQuery(String sql):执行select语句时返回查询结果对应的ResultSet对象,非select语句也可以执行但是返回的ResultSet对象无法操作
2. int executeUpdate(String sql):一般用于DML(select、insert、update、delete)DDL(create、drop)语句,DDL时返回0,DML时返回受影响的行数
3. boolean execute(String sql):执行select语句返回true,其它情况基本返回false
4. ResultSet getResultSet():如果其execute方法返回true,获取查询出的结果集
5. int getUpdateCount():如果其execute方法返回false,获取修改条数
boolean bl = stmt.execute("select  * from teacher");
if(bl){
	ResultSet st = stmt.getResultSet();
	while(st.next()){
		System.out.println(st.getString(2));
	}
}else{
	int upc = stmt.getUpdateCount();
	System.out.println(upc);
}

13.5 PreparedStatement

允许使用"?“进行占位,其实就是比Statement多了setXxx方法,为占位符”?"赋值。且创建PreparedStatement对象时,需要传入sql,而Statement是在调用其对象的executeXxxx方法中传入的sql

13.5.1 作用
  1. 为Statement接口的子接口
  2. 多次执行时比Statement效率高
  3. 防止SQL注入
//如果将userName输入为'or true or',那么语句变为select * from jdbc_test where jdbc_name='' or true or '' and jdbc_desc='';此时不输密码,也可以登录成功
String sql = "select * from jdbc_test where jdbc_name='"+userName+"'and jdbc_desc='"+userPass+"'";
13.5.2 方法
PreparedStatement pstmt = conn.prepareStatement("select * from teacher where id=?");
//1. void setXxx(int parameterIndex, Xxx x):为第parameterIndex个占位符赋值为Xxx类型的值x
pstmt.setString(1,"2");
ResultSet rs = pstmt.executeQuery();
--对Oracle中二进制长对象的处理(Blob、Clob)
--数据库语句:
--create table liu(a blob);
//java语句
PreparedStatement p = conn.prepareStatement("insert into liu values(?)");
File f = new File("C:\\Users\\ThinkPad\\Desktop\\截图\\1.png");
InputStream it = new FileInputStream(f);
//p.setBinaryStream(1, it);也可以
p.setBlob(1, it);
int i = p.executeUpdate();

13.6 CallableStatement

可以执行存储过程,其实就是比PreparedStatement多了registerOutParameter与getXxx方法,为占位符"?"对应的数据设置类型,并获取该值

13.6.1 作用
  1. 为PreparedStatement接口的子接口
  2. 通常用于调用存储过程
13.6.2 方法
//存储过程add_pro用于拼接传入的第一个与第二个字符串作为第三个字符串
CallableStatement pstmt = conn.prepareCall("call add_pro(?,?,?)");
//1. void registerOutParameter(int parameterIndex, int sqlType):将存储过程中占位符代表的返回列注册为sqlType值对应的类型
pstmt.registerOutParameter(3,Types.VARCHAR);
pstmt.setString(1, "wu");
pstmt.setString(2, "sihan");
pstmt.execute();
//2. Xxx getXxx(int parameterIndex):返回第parameterIndex占位符代表的值
System.out.println(pstmt.getString(3));

13.7 ResultSet

13.7.1 详解
  1. 代表结果集对象
  2. 默认情况下ResultSet不可以滚动也不可以更新
  3. 可以通过以下方法开启滚动与更新功能
//1. resultSetType:设置是否可以滚动,只有允许任意前后滚动才能使用除next()以外的修改指针指向的方法
//ResultSet.TYPE_FORWARD_ONLY:只能向后滚动
//ResultSet.TYPE_SCROLL_INSENSITIVE:支持任意前后滚动,底层数据库改变不影响ResultSet内容
//ResultSet.TYPE_SCROLL_SENSITIVE:支持任意前后滚动,底层数据库改变影响ResultSet内容
//以上两个常量需要数据库驱动支持,对于有些数据库驱动而言,这两个值没有什么区别
//2. resultSetConcurrency:设置是否允许更改,只有允许更改才可以使用Result对象的updateXxx相关方法
//可更新结果集需满足条件:所有数据来自同一表,选出数据集必须包含主键列(针对mysql有效,对于oracle无效)
//ResultSet.CONCUR_READ_ONLY:只读
//ResultSet.CONCUR_UPDATABLE:允许更新
//注意select * from teacher语句是不允许被更新的,必须写成select id,name,title from teacher
Statement st = conn.createStatement(int resultSetType, int resultSetConcurrency);
13.7.2 方法
1. void close():释放ResultSet对象
2. boolean absolute(int row):将结果集的记录指针移动到第row行,如果row为负数,移动到倒数第row行,如果指针指向一条有效记录返回true
3. void beforeFirst():指针指向首行之前,即初始状态
4. boolean first():指针指向首行,如果指针指向一条有效记录,返回true
5. boolean previous():指向上一行
6. boolean next():指向下一行
7. boolean last():指向最后一行
8. void afterLast():指向最后一行之后
9. getXxx(int columnIndex):获取指针所在行的第columnIndex列的值
//Blob getBlob(int/String column):可以获取数据库中Blob类型数据
//Blob类有getBinaryStream()方法,将Blob对象转为输入流对象 
10. getXxx(String columnLabel):获取指针所在行的名为columnLabel列的值
11. updateXxx(int columIndex,Xxx value):更新指针所在行的第columIndex列的内容为value
12. updateXxx(String columnLabel,Xxx value)
13. updateRow():调用updateXxx方法后,在指针没离开该行前,必须调用该方法将数据写入数据库,否则修改不会被提交

13.8 ResultSetMetaData

获取ResultSet的描述信息(元数据)

13.8.1 方法
1. int getColumnCount():获取ResultSet列数量
2. String getColumnName(int column):获取第column列的列名
3. int getColumnType(int column):获取第column列的数据类型

13.9 事务处理

13.9.1 事务的概念

事务是由一步或几步数据库操作序列组成的逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行,程序和事务是两个不同概念,一般而言一段程序包含多个事务

13.9.2 事务的特性
  1. 原子性
  2. 一致性
  3. 隔离性
  4. 持续性
13.9.3 数据库的事务组成
  1. 一组dml语句(select、insert、update、delete)
  2. 一条ddl(create)语句或一条dcl(grant revoke)语句:因为ddl和dcl语句会导致事务立即提交
13.9.4 数据库提交事务方式
  1. 显示提交:commit
  2. 自动提交:ddl、dcl
13.9.5 数据库回滚事务

显示回滚:rollback

13.10 使用连接池管理连接

  1. 使用DriverManager获取Connection对象时,每个Connection对象对应一个物理数据库连接,频繁打开关闭该连接会造成系统性能低下
  2. 数据库连接池:程序启动时,系统主动建立足够多的数据库连接,并将这些连接组成一个连接池,每次应用请求数据库连接时,无需重新打开连接,而是从连接池中取出已有连接使用,使用后也不关闭,而是将连接归还连接池,大大提升性能
  3. JDBC提供一个接口javax.sql.DataSource代表数据源,一个数据源包含连接池和连接池管理两部分,习惯上把DataSource也称为连接池
  4. C3P0与DBCP提供了对DataSource的实现
13.10.1 C3P0编程
  1. 引入c3p0-0.9.1.2.jar
  2. C3P0可以自动清理不再使用的Connection、Statement、ResultSet对象
import java.beans.PropertyVetoException;
import java.io.FileNotFoundException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class JDBCTest {
	public static void main(String[] args)
			throws ClassNotFoundException, SQLException, FileNotFoundException, PropertyVetoException {
		ComboPooledDataSource ds = new ComboPooledDataSource();
		ds.setDriverClass("oracle.jdbc.driver.OracleDriver");
		ds.setJdbcUrl("jdbc:oracle:thin:@192.168.41.128:1521:fcrhost");
		ds.setUser("c50hst");
		ds.setPassword("c50hst");
		// 设置连接池最大连接数
		ds.setMaxPoolSize(40);
		// 设置连接池最小连接数
		ds.setMinPoolSize(2);
		// 设置连接池初始连接数
		ds.setInitialPoolSize(10);
		// 设置连接池的缓存Statement的最大数
		ds.setMaxStatements(180);
		Connection conn = ds.getConnection();
		Statement stmt = conn.createStatement();
		ResultSet rs = stmt.executeQuery("select * from teacher");
		while (rs.next()) {
			System.out.println(rs.getString("id"));
			System.out.println(rs.getString("name"));
			System.out.println(rs.getString("title"));
		}
	}
}

发布了32 篇原创文章 · 获赞 0 · 访问量 944

猜你喜欢

转载自blog.csdn.net/hanzong110/article/details/102554229