jdbc连接池
是缓存在内存中的多个可重复使用的数据库连接
客户端请求连接池获得一个连接对象(Connection),然后就可以使用连接对象访问数据库
不需要客户端注册驱动程序
大大提高了数据访问性能
连接对象拿来就直接使用,不需要注册驱动及使用驱动创建连接对象
javax.sql.ConnectionPoolDataSource接口对象是提供PooledConnection对象的工厂
第三方实现连接池需要实现javax.sql.PooledConnection接口和javax.sql.ConnectionPoolDataSource接口
PooledConnection就是一个到数据库的物理连接
PooledConnection接口对象就是应用程序从连接池获得的连接所引用的对象
当应用程序关闭从连接池获得的连接时,基础物理连接会被回收而不是被关闭
由厂商实现
常见连接池产品:bonecp,dbcp,proxool,c3po
配置连接池
连接池应该是在服务器或中间件中使用,客户端通过连接池获得连接对象用来访问数据库
使用DBCP实现连接池
commons-collections-3.2.1.jar
commons-dbcp-1.4.jar
commons-pool-1.6.jar
数据库驱动(mysql-connector-java-5.1.18-bin.jar)
创建xxx.properties文件对连接池属性进行配置
使用DBCP连接池,在xxx.properties文件中对连接池属性进行配置:
driverClassName=com.mysql.jdbc.Driver //配置驱动类
url=jdbc:mysql://localhost:3306/test //配置连接字符串
username=root //登陆数据库的用户名
password=root //登陆数据库的密码
maxActive=50 //最大活动连接数,设为0为没有限制
maxIdle=20 //最大空闲连接数,设为0为没有限制
maxWait=60000 //最大等待毫秒数,设为-1为没有限制
使用连接池
Properties pro = new Properties();
//pro.load(类名.class.getResourceAsStream("/jdbc.properties"));
pro.load(new FileInputStream(“jdbc.properties”)); //读取连接池配置信息
DataSource ds = BasicDataSourceFactory.createDataSource(pro);
Connection conn = ds.getConnection();
语法
Connection con = DriverManger.getConnection(urlString);
con.setAutoCommit(false);//取消自动提交
Statement stm = con.createStatement();
stm.executeUpdate(sqlString);
con.transactionEndMethod; //con.commit() or con.rollback();
示例:
try{ con.setAutoCommit(false);
stm = con.createStatement();
stm.executeUpdate(“insert into t_user(id, name, password) values(1, ‘admin’,’admin’ )”);
con.commit(); ……数据操作代码……con.commit();}
catch(SQLException e) {try {con.rollback();} catch(Exception e){}}
并发控制
数据库并发控制就是要用正确的方式调度并发操作,使一个用户事务的执行不受其它事务的干扰,从而避免造成数据的不一致
在JDBC中,通过connection可以设置事务隔离级别来对并发进行控制
事务隔离级别就是事务执行时受打扰的程度,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越差,效率越低。
Connection中查看和设置隔离级别的方法
getTransactionIsolation():查看隔离级别
setTransactionIsolation(int level):设置隔离级别
Connection中的事务隔离级别(Connection接口中的常量)
TRANSACTION_NONE:此级别不支持事务
TRANSACTION_READ_UNCOMMITTED:此级别允许某一事务读其他事务还没有更改完的数据。允许发生脏读 、不可重复读和幻读。
TRANSACTION_READ_COMMITTED:此级别要求某一事务只能等别的事务全部更改完才能读。可以防止发生脏读,但不可重复读和幻读有可能发生。
TRANSACTION_REPEATABLE_READ:此级别要求某一事务只能等别的事务全部更改完才能读而且禁止不可重复读。也就是可以防止脏读和不可重复读,但幻读有可能发生。
TRANSACTION_SERIALIZABLE:此级别防止发生脏读、不可重复读和幻读,事务只能一个接着一个地执行,而不能并发执行。
语法
con.setTransactionIsolation(Connection.isolationLevel);
示例:
Connection con = DriverManager.getConnection
(“jdbc:mysql://localhost:3306/test”, “root”, “root”);
con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
。。。
JDBC异常处理
数据库应用程序包含以下部分
应用程序
JDBC代码
数据库
各部分不一致就可能出现异常或警告
通常使用SQLException和SQLWarning表示异常和警告信息
SQLException表示异常,如驱动不匹配,进行了数据库不支持的操作等,会导致应用程序终止
SQLWarning表示警告,如某些操作不规范但仍然能执行,不会导致应用程序终止
使用JDBC访问数据库时,下列情况会导致SQL异常的产生
JDBC与数据库服务器之间的通信信息丢失
错误的命令
使用数据库不支持的函数
访问不存在的列
SQLException类提供了数据库访问错误或其他错误的信息,主要包括:
getNextException()方法返回下一个SQL异常对象
getErrorCode()方法返回用整数表示的错误代码(由数据库厂商提供)
getMessage()方法返回用字符串表示的错误信息
SQLWarning类
是SQLException的子类
因非致命SQL状态而生成
不会导致应用程序中断运行
存储最近产生的SQL警告信息
使用getNextWaring()方法获得下一个警告信息
什么是DAO
非常流行的数据访问模式——DAO模式
Data Access Object(数据存取对象)
位于业务逻辑和持久化数据之间
实现对持久化数据的访问
DAO模式的组成
DAO模式的组成部分
DAO接口
DAO实现类
实体类
数据库连接和关闭工具类
为什么使用Properties类
public class BaseDao {
private String driver = "com.mysql.jdbc.Driver";
private String url = "jdbc:mysql://localhost:3306/epet";
private String user = "epetadmin";
private String password= “0000";
Connection conn = null;
public Connection getConnection() {
if(conn==null){
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, user, password);
} catch (Exception e) {//省略代码……}
}
return conn;// 返回连接对象
}
properties配置文件
实体类特征
属性一般使用private修饰
提供public修饰的getter/setter方法
实体类提供无参构造方法,根据业务提供有参构造
实现java.io.Serializable接口,支持序列化机制
连接池
package com.hisoft.java.tset;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import org.apache.commons.dbcp.BasicDataSourceFactory;
public class test {
Connection con;
PreparedStatement pstmt;
ResultSet ps;
public static void main(String[] args) {
test ts = new test();
ts.zz();
}
public void zz() {
try {
Properties pro = new Properties();
pro.load(new FileInputStream("C://Users//admin//workspace//JDBCandDemo//jsbc.properties"));
// pro.load(test.class.getResourceAsStream("C://Users//admin//workspace//JDBCandDemo//jsbc.properties"));
javax.sql.DataSource ds = BasicDataSourceFactory.createDataSource(pro);
con = ds.getConnection();
// String sql = "select * from dog";
// pstmt = con.prepareStatement(sql);
// ps = pstmt.executeQuery();
// while (ps.next()) {
// String str = ps.getString("name");
// System.out.println("名字是:" + str);
// }
con.setAutoCommit(false);
String st = "insert into dog (name,health,love,strain) values (?,?,?,?)";
pstmt = con.prepareStatement(st);
pstmt.setString(1, "哦哦");
pstmt.setInt(2, 50);
pstmt.setInt(3, 60);
pstmt.setString(4, "金毛");
pstmt.executeUpdate();
st = "delete from dog where id = ?";
pstmt = con.prepareStatement(st);
pstmt.setInt(1, 6);
pstmt.executeUpdate();
// con.rollback();
con.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// ps.close();
pstmt.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}