Jdbc进阶

Posted 菜菜小谭

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Jdbc进阶相关的知识,希望对你有一定的参考价值。

***************************数据库的隔离级别****************************

mysql 数据库 这4种隔离级别都支持 默认的隔离级别 可重复读

oracle 只支持 读已提交、序列化 默认的隔离级别是 读已提交

 

一.读未提交

会出现脏读


客户端A 修改了数据 没提交 ,其他客户端也可以读到,读未提交....


脏读: 经理(客户端A)发工资 本来要发5000,不小心多打1个0,发了50000,但是没提交,

客户端B(杨帆)一查,可以查到,挺高兴,刚准备去消费,消费的路上,经理马上反应过来了,立马回滚


从新插入一条5000的记录,杨帆再一查5000,数据不一致, 这种不一致的现象叫做脏读...


读的是临时的不准确的数据!!!

 

***************************批量更新****************************


每次调用 executeUpdate() 执行一条SQL语句 都要通过网络 把sql语句发送到数据库服务器 再返回

效率比较低


可以把多条语句 加入到 Batch里, executeBatch() 就把这些sql语句 都发送服务器端一起执行了,效率高


返回值是int[]


JDK8.0新增的功能

long count = stmt.executeLargeUpdate();//如果一条sql语句影响行数比较多 超过int类型的表数范围 使用这个方法

同样批量更新时 如果每条sql语句 影响的行数 都超过int类型表数范围 使用

long[] longArr = stmt.executeLargeBatch();


演示代码:


public void testBatchUpdate() {

Statement stmt = null;
try {

String sql1 = "insert into account values(1,‘杨帆1‘,1000)";
String sql2 = "insert into account values(2,‘杨帆2‘,2000)";

String sql3 = "insert into account values(3,‘杨帆3‘,3000)";
String sql4 = "insert into account values(4,‘杨帆4‘,4000)";

stmt = conn.createStatement();
boolean autoCommit = conn.getAutoCommit();

conn.setAutoCommit(false);
// 收集多条SQL语句 等待一起发送
stmt.addBatch(sql1);
stmt.addBatch(sql2);
stmt.addBatch(sql3);
stmt.addBatch(sql4);

int[] countArr = stmt.executeBatch();

for (int i = 0; i < countArr.length; i++) {
System.out.println("第" + i + "条SQL语句受影响的行数为:" + countArr[i]);
}

conn.commit();

conn.setAutoCommit(autoCommit);
System.out.println("批量更新成功");
} catch (SQLException e) {
try {
conn.rollback();

System.out.println("批量更新失败");
} catch (SQLException e1) {

e1.printStackTrace();
}
System.out.println("建立通道失败");
e.printStackTrace();
} catch (Exception e) {
try {
conn.rollback();

System.out.println("批量更新失败");
} catch (SQLException e1) {

e1.printStackTrace();
}
System.out.println("建立通道失败");
e.printStackTrace();
} finally {
// 五.关闭
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
System.out.println("关闭pstmt通道失败");
e.printStackTrace();
}
}

if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
System.out.println("关闭数据库连接失败");
e.printStackTrace();
}
}
}


***************************数据库连接池****************************


一.为什么使用数据库连接池


每次执行增删改查操作的时候 都要从新创建连接、关闭连接,比较耗时,效率低.为了提高效率,有了数据库连接池的概念


二.什么是数据库连接池


在应用程序(或web服务器)启动的时候, 事先创建好n个数据库连接对象,并把这些对象放到一个容器中,以备使用.这个容器

叫做数据库连接池. 用户用的时候 不需要创建连接,直接从连接池中取出一个Connection对象来用就可以了,用完以后也不需要

关闭,直接把Connection对象 还到数据库连接池中..大大的减少了频繁创建、关闭连接所浪费的时间.


javax.sql.DataSource 数据源 它是一个接口 不同产生有对该接口的不同实现,常见的第三方数据源

1.DBCP

2.C3P0

三.如何使用

DBCP

导入两个jar包

commons-dbcp.jar
commons-pool.jar

commons-dbcp.jar 依赖于 commons-pool.jar

 

 

package com.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.commons.dbcp.BasicDataSource;

/**
* 公司:蓝桥软件学院
* 作者:zhangzy
* 时间:2017年9月1日 下午5:31:26
* 功能:数据库连接池 DBCP实现
*/
public class ConnOracleDataSource {

private static BasicDataSource dataSource = new BasicDataSource();


private static String driverClassName = "oracle.jdbc.OracleDriver";
private static String url = "jdbc:oracle:thin:@localhost:1521:orcl";
private static String username = "scott";
private static String password = "tiger";


static{

dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);

//1.设置Conn对象的初始个数
dataSource.setInitialSize(5);
//2.设置最大的活动连接数
dataSource.setMaxActive(20);
//3.设置最少空闲数
dataSource.setMinIdle(2);
}

public static Connection getConnection(){
Connection conn = null;

try {
conn = dataSource.getConnection();
} catch (SQLException e) {
System.out.println("创建连接失败");
e.printStackTrace();
}


return conn;
}

public static void closeConnection(ResultSet rs,Statement stmt,Connection conn){

if(rs!=null){
try {
rs.close();
} catch (SQLException e) {

e.printStackTrace();
}
}

if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
System.out.println("关闭通道失败");
e.printStackTrace();
}
}

if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
System.out.println("关闭数据库连接失败");
e.printStackTrace();
}
}

}

public static void main(String[] args) {
System.out.println(ConnOracleDataSource.getConnection());
}
}

 

测试效率:


public static void main(String[] args) {
long startTime = System.currentTimeMillis();

for (int i = 1; i <= 100; i++) {

CategoryDaoImpl dao = new CategoryDaoImpl();

Category category = new Category();

category.setCname("手机");
category.setCdesc("通讯工具");

dao.addCategory(category);
}

long endTime = System.currentTimeMillis();

System.out.println("总共使用了" + (endTime - startTime) + "毫秒");

}

 




















































































































































以上是关于Jdbc进阶的主要内容,如果未能解决你的问题,请参考以下文章

JDBC六部曲-2(进阶)

Jdbc进阶

手撕JDBC笔记,进阶框架必备

Jdbc进阶

JDBC进阶 元数据

手撕JDBC笔记(含源码),进阶框架必备