JDBC的扩展知识点总结

一、数据库的事务

1.1 事务概述

  • 事务:一组逻辑操作单元,使数据从一种状态变换到另一种状态
  • 事务处理(事务操作):保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),那么这些修改就永久地保存下来;要么数据库管理系统将放弃所作的所有修改,整个事务回滚(rollback)到最初状态
  • 为确保数据库中数据的一致性,数据的操纵应当是离散的成组的逻辑单元:当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态
  • 举个栗子,当小明给小红转账时,因为种种原因没有转账成功,小明的钱减少了,小红却没有收到钱,此时就需要事务回滚,否则小明就得哭死…

1.2 事务的属性

事务的ACID(acid)属性

  • 原子性(Atomicity)
  • 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
  • 一致性(Consistency)
  • 事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
  • 隔离性(Isolation)
  • 事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
  • 持久性(Durability)
  • 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响

1.3 JDBC事务处理

当一个连接对象被创建时,默认情况下是自动提交事务:每次执行一个 SQL 语句时,如果执行成功,就会向数据库自动提交,而不能回滚

为了让多个 SQL 语句作为一个事务执行:

1. 调用 Connection 对象的 setAutoCommit(false); 以取消自动提交事务

2.在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务

3.在出现异常时,调用 rollback(); 方法回滚事务

4.若此时 Connection 没有被关闭, 则需要恢复其自动提交状态

1.4 数据库事务使用的过程

使用数据库的事务,我们需要配合异常处理try

public void testJDBCTransaction() {
Connection conn = null;
try {
// 1.获取数据库连接
conn = JDBCUtils.getConnection();
// 2.开启事务
conn.setAutoCommit(false);
// 3.进行数据库操作

// 4.若没有异常,则提交事务
conn.commit();
} catch (Exception e) {
e.printStackTrace();
// 5.若有异常,则回滚事务
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}} finally {
JDBCUtils.close(null, null, conn); }  }

1.5 使用数据库事务的好处

使用COMMIT 和 ROLLBACK语句,我们可以:

  • 确保数据完整性。
  • 数据改变被提交之前预览。
  • 将逻辑上相关的操作分组

提交或回滚前的数据状态

  • 改变前的数据状态是可以恢复的
  • 执行 DML 操作的用户可以通过 SELECT 语句查询提交或回滚之前的修正
  • 其他用户不能看到当前用户所做的改变,直到当前用户结束事务。
  • DML语句所涉及到的行被锁定, 其他用户不能操作

提交后的数据状态

  • 数据的改变已经被保存到数据库中。
  • 改变前的数据已经丢失。
  • 所有用户可以看到结果。
  • 锁被释放, 其他用户可以操作涉及到的数据

说了这么多,还是使用代码来举例说明更加清晰(数据库连接的JDBCUtils类上一章写过了):

package com.company.jdbcDemo;

import com.company.jdbcDemo.JDBCUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/*
    AA给CC转账1000
    AA 2000
    CC 2000

        try{
           开启事务
           AA -= 1000
           System.out.println(1/0);
           CC += 1000
           提交(一旦提交数据不能再回滚(撤销))
        }catch(Exception e){
        事务回滚(撤销)
        }

    CREATE TABLE account(
    NAME VARCHAR(20),
    balance INT
    )

 */
public class AccountDemo {

    public static void main(String[] args) throws SQLException {
        //1.获取数据库连接对象
        Connection connection = JDBCUtils.getConnection();
        PreparedStatement ps = null;
        try {
            //2.开启事物--禁止自动提交
            connection.setAutoCommit(false);
            //-------------------------------------------------------------------
            //3.做具体的操作---执行sql语句
            //预编译
            String sql = "update account set balance=? where name=?";
            ps = connection.prepareStatement(sql);

            //给占位符赋值
            ps.setInt(1, 1000);
            ps.setString(2, "aa");
            //执行sql
            ps.executeUpdate();

            System.out.println(1 / 0);

            //给占位符赋值
            ps.setInt(1, 3000);
            ps.setString(2, "cc");
            //执行sql
            ps.executeUpdate();
            //-------------------------------------------------------------------
            //4.事务提交
            connection.commit();
        }catch (Exception e){
            e.printStackTrace();
            //5.事务回滚
            connection.rollback();
        }finally {
            //6.允许自动提交
            connection.setAutoCommit(true);
            //7.关闭资源----最后关闭资源
            JDBCUtils.close(ps,connection);

        }
    }
}

二、数据库连接池

概述

前面我们的示例代码中,一直在调用我写的那个JDBCUtils类来完成数据库的连接,如果我们在别的工程中,就需要复制一下我的那个类,并且我写的那个也不是很严谨,我前面实现的数据库连接方式存在以下问题:

  • 普通的JDBC数据库连接使用 DriverManager 来获取,每次向数据库建立连接的时候都要将 Connection 加载到内存中,再验证用户名和密码
  • 数据库的连接资源并没有得到很好的重复利用.若同时有几百人甚至几千人在线,频繁的进行数据库连接操作将占用很多的系统资源,严重的甚至会造成服务器的崩溃
  • 对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将导致重启数据库
  • 这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃

使用数据库连接池

  • 数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去
  • 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个
  • 数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中

2.1 数据库连接池技术的优点

  • 资源重用
  • 由于数据库连接得以重用,避免了频繁创建,释放连接引起的大量性能开销。在减少系统消耗的基础上,另一方面也增加了系统运行环境的平稳性。
  • 更快的系统反应速度
  • 数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于连接池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而减少了系统的响应时间
  • 新的资源分配手段
  • 对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接池的配置,实现某一应用最大可用数据库连接数的限制,避免某一应用独占所有的数据库资源
  • 统一的连接管理,避免数据库连接泄露
  • 在较为完善的数据库连接池实现中,可根据预先的占用超时设定,强制回收被占用连接,从而避免了常规数据库连接操作中可能出现的资源泄露

三、DRUID(德鲁伊)

  • 了解了数据库连接池以及优势,接下来我为大家带来一个目前常用的一个数据库连接池框架—>德鲁伊
  • DRUID是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0、DBCP、PROXOOL等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生的DB连接池,据说是目前最好的连接池

3.1 德鲁伊的使用

阿里德鲁伊连接池技术首先分为两步:

1.加入jar包

例如:druid-1.1.10.jar

2.代码步骤

第一步:建立一个数据库连接池

第二步:设置连接池的参数

第三步:获取连接

使用德鲁伊连接数据库的方式一

//1、创建数据源(数据库连接池)对象
DruidDataSource ds =new DruidDataSource();
//2、设置参数
//(1)设置基本参数
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/test");
ds.setUsername("root");
ds.setPassword("mysql123");
//3、获取连接
Connection conn = ds.getConnection();
//如果这里没有关闭,就相当于没有还
conn.close();

使用德鲁伊连接数据库的方式二

// 创建配置文件druid.properties
url=jdbc:mysql://localhost:3306/0319db ?rewriteBatchedStatements=true
username=root
password=123456
driverClassName=com.mysql.jdbc.Driver

代码如下:
Properties pro = new Properties();
pro.load(TestDruid2.class.getClassLoader().getResourceAsStream("druid.properties"));
DataSource ds=
		DruidDataSourceFactory.createDataSource(pro);
Connection conn = ds.getConnection();

这里注意了,德鲁伊配置文件中的key,必须跟我下面一样,否则连接不成功哦

// druid.properties内容
url=jdbc:mysql://localhost:3306/demo
username=root
password=123321
driverClassName=com.mysql.jdbc.Driver

四、DBUtils工具类

  • 既然数据库连接有了数据库连接池这么方便地操作,那么对数据的增删改查有没有相关的方法呢?当然有,它就是DBUtils
  • 将常用的操作数据库的JDBC的类和方法集合在一起,就是DBUtils.
  • 这个比较简单,我就介绍一下常用的API操作,具体的知识点,可以查看Java的API文档

我就直接上操作了,这里还是使用我前面实现的那个JDBCUtils类哈,偷个懒…

package com.company.jdbc2;

import com.company.jdbc.JDBCUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.junit.Test;

import java.sql.SQLException;
import java.util.List;

/*
    通过使用DBUtils工具类实现增,删,改,查的操作
 */
public class DBUtilsDemo {

    @Test
    public void test() throws SQLException {
        //1.创建操作对象
        QueryRunner queryRunner = new QueryRunner();
        //2.增,删,改是一个方法
        /*
            update(Connection conn, String sql, Object param)
            conn : 连接对象
            sql : sql语句
            param : 给占位符赋值的内容
         */
        String sql = "insert into student(sid,sname,sage) values(?,?,?)";
        //返回值 :有几条数据受到影响
        int i = queryRunner.update(JDBCUtils.getConnection(),
                sql, 10, "kongkong", 18);
        System.out.println("有" + i + "条数据受到影响");
    }

    @Test
    public void test2() throws SQLException {
        QueryRunner queryRunner = new QueryRunner();
        /*
        query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)
        conn : 连接对象
        sql : sql语句

         */
        String sql = "select sid a,sname,sage from student where sid=?";
        //注意:类中的属性名一定要和字段名相同。如果不相同则需要在sql语句中使用别名
//        Student student = queryRunner.query(JDBCUtils.getConnection(), sql,
//                new BeanHandler<Student>(Student.class), 10);

        sql = "select sid a,sname,sage from student";
        List<Student> list = queryRunner.query(JDBCUtils.getConnection(), sql,
                new BeanListHandler<Student>(Student.class));

       for (Student s : list) {
           System.out.println(s);
       }
    }

}

使用批处理

当我们需要对进行大批量的数据操作时,可以采用批处理技术,很简单,在url中添加批处理的参数

jdbc:mysql://localhost:3306/Demo?rewriteBatchedStatements=true

示例代码,(咳咳,依旧是我那个JDBCUtils实现连接的工具类…)

package com.company.jdbc3;

import com.company.jdbc.JDBCUtils;
import org.junit.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/*
    批处理:
 */
public class BatchDemo {

    /*
        使用批处理:
            1.mysql驱动包的版本必须为5.1.3x  才支持批处理
            2.在url连接中添加如下参数
                    jdbc:mysql://localhost:3306/Demo?rewriteBatchedStatements=true
            3.使用一些API:
                //添加到批处理中
                ps.addBatch();
                //执行批处理
                ps.executeBatch();
                //清空批处理
                ps.clearBatch();
     */
    @Test
    public void test2() throws SQLException {
        //1.获取数据库连接
        Connection connection = JDBCUtils.getConnection();
        //2.预编译
        PreparedStatement ps = connection.prepareStatement(
                "insert into student(sid,sname,sage) values(?,?,?)");
        //3.给占位符赋值
        for (int i = 1; i <= 100000 ; i++) {
            ps.setInt(1,i);
            ps.setString(2,"aaa"+i);
            ps.setInt(3,i);
            //添加到批处理中
            ps.addBatch();

            if (i % 1000 == 0){
                //执行sql
                ps.executeBatch();//执行批处理
                //清空批处理
                ps.clearBatch();
            }

        }
        //4.关资源
        JDBCUtils.close(ps,connection);
    }

    @Test
    public void test() throws SQLException {
        //1.获取数据库连接
        Connection connection = JDBCUtils.getConnection();
        //2.预编译
        PreparedStatement ps = connection.prepareStatement(
                "insert into student(sid,sname,sage) values(?,?,?)");
        //3.给占位符赋值
        for (int i = 1; i <= 100000 ; i++) {
            ps.setInt(1,i);
            ps.setString(2,"aaa"+i);
            ps.setInt(3,i);
            //执行sql
            ps.executeUpdate();
        }
        //4.关资源
        JDBCUtils.close(ps,connection);
    }
}

到此这篇关于JDBC的扩展知识点总结的文章就介绍到这了,更多相关JDBC知识点内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JDBC连接Sql Server 2005总结

    1.准备工作: 准备相关的软件(Eclipse除外,开源软件可以从官网下载) <1>.Microsoft SQL server 2005 Express Edition 下载地址:http://download.microsoft.com/download/0/9/0/09020fab-d2c3-4a8c-b9e0-db53a7a30ae8/SQLEXPR_CHS.EXE <2>.SQL Server Management Studio 下载地址:http://www.micros

  • JDBC连接mysql乱码异常问题处理总结

    前段时间学习JDBC,要连接mysql获取数据.按照老师的样例数据,要存一些名字之类的信息,用的都是英文名,我当时就不太想用英文,就把我室友的名字存了进去,嘿嘿,结果,出问题了. 连接数据库语句: static final String DB_URL = "jdbc:mysql://localhost/filemanagement"; 查询语句: private static final String theUserQuery = "SELECT name, password

  • 使用JDBC连接Mysql数据库会出现的问题总结

    首先理清几个概念: JDBC:java数据库连接,是Orical公司的指定的一套规范接口 java数据库驱动:JDBC的实现类,由相应的数据库厂商提供,可以通过驱动去操作不同的数据库 在java-数据库这里,jdbc-api中的所有包都是java.sql或者javax.sql JDBC的操作步骤: (1)建立数据库和表 (2)创建项目 (3)导入驱动jar包 (4)注册驱动 Class.forName("com.mysql.jdbc.Driver"); (5)获取连接 Connecti

  • javaweb学习总结——使用JDBC处理MySQL大数据

    BLOB (binary large object),二进制大对象,是一个可以存储二进制文件的容器.在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型,BLOB是一个大文件,典型的BLOB是一张图片或一个声音文件,由于它们的尺寸,必须使用特殊的方式来处理(例如:上传.下载或者存放到一个数据库). 一.基本概念 在实际开发中,有时是需要用程序把大文本或二进制数据直接保存到数据库中进行储存的. 对MySQL而言只有blob,而没有clob,mysql存储大文本采用的是Text,Text和

  • Java 数据库连接(JDBC)的相关总结

    Java 数据库连接(Java DataBase Connectivity,缩写JDBC)是官方(sun公司)定义的一套操作所有关系型数据库的规则(即接口). 各个数据库厂商去实现这套接口,提供数据库驱动jar包.我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类. 一.JDBC API 概述 JDBC API主要位于JDK中的java.sql包中(之后扩展的内容位于javax.sql包中),主要包括(下面的接口,需驱动程序提供者来具体实现): DriverManage

  • JDBC用法小结

    本文实例总结了JDBC的用法.分享给大家供大家参考.具体分析如下: DriverManger:驱动管理器类 要操作数据库,必须先与数据库创建连接,得到连接对象 public static Connection getConnection(String url, String username,String password){} Connection:连接接口: 通过DriverManger类的getConnection方法,将获得连接对象,执行sql语句必须借助语句对象(Statement)

  • 浅析JAVA常用JDBC连接数据库的方法总结

    一.JDBC连接DB2 复制代码 代码如下: Class.forName("Com.ibm.db2.jdbc.net.DB2Driver");   String url="jdbc:db2://dburl:port/DBname"   cn = DriverManager.getConnection( url, sUsr, sPwd );  Class.forName("Com.ibm.db2.jdbc.net.DB2Driver"); Stri

  • JDBC数据库的使用操作总结

    JDBC是一组能够执行SQL语句的API 由于传统的数据库操作方式需要程序员掌握各个不同的数据库的API,极其不便 因此java定义了JDBC这一标准的接口和类,为程序员操作数据库提供了统一的方式 JDBC的操作方式比较单一,由五个流程组成: 1.通过数据库厂商提供的JDBC类库向DriverManager注册数据库驱动 2.使用DriverManager提供的getConnection()方法连接到数据库 3.通过数据库的连接对象的createStatement方法建立SQL语句对象 4.执行

  • Java中JDBC事务与JTA分布式事务总结与区别

    Java事务的类型有三种:JDBC事务.JTA(Java Transaction API)事务.容器事务.常见的容器事务如Spring事务,容器事务主要是J2EE应用服务器提供的,容器事务大多是基于JTA完成,这是一个基于JNDI的,相当复杂的API实现.所以本文暂不讨论容器事务.本文主要介绍J2EE开发中两个比较基本的事务:JDBC事务和JTA事务. JDBC事务 JDBC的一切行为包括事务是基于一个Connection的,在JDBC中是通过Connection对象进行事务管理.在JDBC中,

  • java开发中基于JDBC连接数据库实例总结

    本文实例讲述了java开发中基于JDBC连接数据库的方法.分享给大家供大家参考,具体如下: 创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),这通过java.lang.Class类的静态方法forName(String  className)实现. 例如: try{ //加载MySql的驱动类 Class.forName("com.mysql.jdbc.Driver") ; }c

  • JDBC常用接口总结

    本文主要向大家介绍JDBC常用的接口都有哪些,下面来看看具体内容. 1.Driver接口 对于每一个数据库驱动程序都必须实现Driver接口,在编写程序时,当需要连接数据库的时候就需要装载由数据库厂商提供的数据库驱动程序,装载的方式如下: Class.forname("jdbc.driver_class_name"); 同时要注意的就是在使用Class.forname时首先需要引入java.sql包.下面这段代码就是装载SQL Server数据库驱动程序的一段代码: import ja

  • Java JDBC连接数据库常见操作总结

    本文实例总结了Java JDBC连接数据库常见操作.分享给大家供大家参考,具体如下: db.properties配置文件(MySql数据库) # db.properties jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF-8 jdbc.username=root jdbc.password=123456 # param

随机推荐