JDBC-02

JDBC

前言

  在JDBC-01当中,我们简单地学习了有关JDBC的一些基本操作,现在我们再一次进行深入的学习。

正文

事务

  首先,我们来学习的是JDBC中事务的运用,那么让我们再次了解一下事务的概念。

事务的概念

  事务指的是逻辑上的一组操作,组成这组操作各个逻辑单元要么全部成功,要么全部失败。

关于事务的API

getAutoCommit()

commit()

rollback()

异常案例:

package com.charles.jdbc.high;

import org.junit.Test;

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

/**
 * 有关事务的案例
 * 转账案例
 * @author Charles
 */
public class Demo01 {
    @Test
    public void demo(){
        Connection conn = null;
        PreparedStatement pste = null;
        try {
            // 加载驱动 + 获取连接
            conn = org.charl.Demo.getConnection();
            // 编写SQL
            String sql = "update account set money = money + ? where name = ?";
            // 预编译
            pste = conn.prepareStatement(sql);
            // 转账过程
            pste.setInt(1,-1000);
            pste.setString(2,"aaa");
            pste.executeUpdate();
            pste.setInt(1,1000);
            pste.setString(2,"bbb");
            pste.executeUpdate();
            // 因为这个错误,导致异常的发生
            int i = 1 / 0;
        } catch (SQLException e){
            e.printStackTrace();
        } finally {
            // 资源释放
            org.charl.Demo.release(pste,conn);
        }

    }
}

修改后的案例

package com.charles.jdbc.high;

import org.junit.Test;

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

/**
 * 有关事务的案例
 * 转账案例
 * @author Charles
 */
public class Demo01 {
    @Test
    public void demo(){
        Connection conn = null;
        PreparedStatement pste = null;
        try {
            // 加载驱动 + 获取连接
            conn = org.charl.Demo.getConnection();
            // 开启事务
            conn.setAutoCommit(false);
            // 编写SQL
            String sql = "update account set money = money + ? where name = ?";
            // 预编译
            pste = conn.prepareStatement(sql);
            // 转账过程
            pste.setInt(1,-1000);
            pste.setString(2,"aaa");
            pste.executeUpdate();
            pste.setInt(1,1000);
            pste.setString(2,"bbb");
            pste.executeUpdate();
            // 因为这个错误,导致异常的发生
//            int i = 1 / 0;
            conn.commit();
        } catch (SQLException e){
            // 回滚事务
            try {
                conn.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            // 资源释放
            org.charl.Demo.release(pste,conn);
        }

    }
}

这样,数据就会进行回滚,保证了数据的安全性。

连接池

概念:连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要它们的线程使用。

好处(作用):

  • 减少连接创建时间
  • 简化的编程模式
  • 受控的资源使用
  • 提高连接的效率

连接池原理:

自定义连接池:

  我们可以利用DataSource接口来实现一个自定义连接池

具体步骤:

  1. 编写一个类实现DataSource接口
  2. 重写一个getConnection方法
  3. 初始化多个连接在内存中
  4. 编写归还连接的方法

具体实现:

/**
 * 自定义连接池
 * @author Charles
 */
public class MyDataSource implements DataSource {
    // 在初始化的时候提供一些连接
    private List<Connection> connectionList = new ArrayList<Connection>();
    public MyDataSource(){
        // 初始化连接
        for (int i = 1; i <= 4; i++){
            // 向集合中存入连接
            connectionList.add(org.charl.Demo.getConnection());
        }
    }
    // 获得连接的方法
    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        Connection conn = connectionList.remove(0);
        return conn;
    }

    // 归还连接的方法
    public void addBack(Connection conn){
        connectionList.add(conn);
    }

代码案例:

package jdbc.datasources;

import org.junit.Test;

import javax.management.relation.Relation;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 利用连接池的案例
 */
public class Demo01 {
    @Test
    public void demo(){
        Connection conn = null;
        PreparedStatement preparedStatement = null;
        ResultSet rs = null;
        MyDataSource md = null;

        try{
            // 利用自定义的连接池注册驱动 + 获得连接
            md = new MyDataSource();
            conn = md.getConnection();
            // 编写SQL语句
            String sql = "select * from account";
            preparedStatement = conn.prepareStatement(sql);
            rs = preparedStatement.executeQuery();
            // 遍历结果
            while (rs.next()){
                System.out.println(rs.getInt("id") + " " + rs.getString("name") + " "
                        + rs.getString("money"));
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            // 释放资源
            if (preparedStatement != null){
                try{
                    preparedStatement.close();
                } catch (SQLException e){
                    e.printStackTrace();
                }
                preparedStatement = null;
            }

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

            // 归还连接
            md.addBack(conn);

        }
    }
}

Druid开源连接池

  Druid 是阿里旗下的开源连接池产品,使用非常简单,可以与Spring 框架进行快速整合。

Maven导包

    <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.21</version>
    </dependency>

基本代码实现

package com.charles.datasource.demo1;

import com.alibaba.druid.pool.DruidDataSource;
import org.junit.Test;

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

public class DruidDemo1 {

    @Test
    public void demo01(){
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            // 使用连接池
            DruidDataSource druidDataSource = new DruidDataSource();
            druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
            druidDataSource.setUrl("jdbc:mysql:///web_test3");
            druidDataSource.setUsername("root");
            druidDataSource.setPassword("1234");

// 获得连接
            connection = druidDataSource.getConnection();
            // 编写SQL
            String sql = "select * from user";
            // 预编译sql
            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()){
                System.out.println(resultSet.getInt("id") + " " + resultSet.getString("username")
                        + " " + resultSet.getString("password"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}

当然也可以将这些数据库信息向外面引入,即创建一个db.properties

代码实现:

单元测试类

    @Test
    public void Demo02(){
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            // 使用连接池
            Properties properties = new Properties();
            properties.load(new FileInputStream("src/main/resources/db.properties"));
            DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);

            // 获得连接
            connection = dataSource.getConnection();
            // 编写SQL
            String sql = "select * from user";
            // 预编译sql
            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()){
                System.out.println(resultSet.getInt("id") + " " + resultSet.getString("username")
                        + " " + resultSet.getString("password"));
            }
        } catch (SQLException | FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

db.properties

# 连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///web_test3
username=root
password=1234

# 初始化连接
initialSize=10

# 最大连接数量
maxActive=50

# 最大空闲连接
maxIdle=20

# 最小空闲连接
minIdle=5

# 超时等待时间(以毫秒为单位)
maxWait=60000

C3P0连接池

  C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。

使用方法与Druid相类似

Maven导包

<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.2</version>
</dependency>

基本代码实现

package com.charles.datasource.demo1;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;

import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class C3p0 {

    @Test
    public void demo01() {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            // 使用连接池
            ComboPooledDataSource DataSource = new ComboPooledDataSource();
            DataSource.setDriverClass("com.mysql.jdbc.Driver");
            DataSource.setJdbcUrl("jdbc:mysql:///web_test3");
            DataSource.setUser("root");
            DataSource.setPassword("1234");

            // 获得连接
            connection = DataSource.getConnection();
            // 编写SQL
            String sql = "select * from user";
            // 预编译sql
            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                System.out.println(resultSet.getInt("id") + " " + resultSet.getString("username")
                        + " " + resultSet.getString("password"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        } finally {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

当然,C3P0连接池也可以通过外部配置文件引用

具体代码实现:

c3p0-config.xml配置文件

<?xml version="1.0" encoding="utf-8"?>
<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql:///web_test3</property>
        <property name="user">root</property>
        <property name="password">1234</property>

        <property name="initialPoolSize">5</property>
        <property name="maxPoolSize">20</property>
        <property name="minPoolSize">5</property>
    </default-config>

</c3p0-config>

单元测试类

    @Test
    public void Demo02(){
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            // 使用连接池
            ComboPooledDataSource DataSource = new ComboPooledDataSource();
            DataSource.setDriverClass("com.mysql.jdbc.Driver");
            DataSource.setJdbcUrl("jdbc:mysql:///web_test3");
            DataSource.setUser("root");
            DataSource.setPassword("1234");

            // 获得连接
            connection = DataSource.getConnection();
            // 编写SQL
            String sql = "select * from user";
            // 预编译sql
            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                System.out.println(resultSet.getInt("id") + " " + resultSet.getString("username")
                        + " " + resultSet.getString("password"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        } finally {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

这里注意,只要将配置文件放在默认路径下,它就会自动查找,不需要手动导入。

DBUtils

  Commons DbUtils一个对JDBC进行简单封装的工具类库,它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。

为什么要学习DBUTILES?

  两个字:方便   ----->  一个字:懒

DBUtils常用的API:

QuerryRunner 和 DBUtils,具体查API文档

DBUtils的CRUD操作:(实例源于黑马,博主在这偷个懒)

添加:

修改:

删除:

查询单条(前提创造实体类):

查询多条(前提创造实体类):

ResultSetHandler的实现类:

ArrayHandler 和 ArrayListHandler:

BeanHandler 和 BeanListHandler (重要!!):

MapHandler 和 MapListHandler:

ColumnListHandler 和 ScalarHandler 还有 KeyedHandler:

ColumnListHandler:

ScalarHandler:查询表中有多少列

KeyedHandler:

小结

  以上便是JDBC的内容了,多练,练到烦了就会了。当然为了更偷懒,我们后期将会学到Mybatis,这个框架比JDBC更方便。

                                   加油!

                             时间:2020-04-06 01:41:37

原文地址:https://www.cnblogs.com/Charles-H/p/Learning_JDBC02.html

时间: 2024-11-13 08:21:57

JDBC-02的相关文章

百度刚放假啊数据库风口浪尖萨拉疯了

http://www.ebay.com/cln/l_x5585/2015.02.11/176746639012 http://www.ebay.com/cln/jiacha_boryk/2015.02.11/176837188016 http://www.ebay.com/cln/gbnlin0/2015.02.11/176837189016 http://www.ebay.com/cln/j_j2841/2015.02.11/177066749015 http://www.ebay.com/c

百度房间爱师傅卡卡是快乐疯了;爱死

http://www.ebay.com/cln/shx9479/-/177007606013/2015.02.11 http://www.ebay.com/cln/genqi12/-/176846034010/2015.02.11 http://www.ebay.com/cln/seyyon2/-/176906811016/2015.02.11 http://www.ebay.com/cln/wcn5971/-/176846032010/2015.02.11 http://www.ebay.co

百度和房价是否健康教案上开发

http://www.ebay.com/cln/l.kuan2/-/167247714018/2015.02.10 http://www.ebay.com/cln/setlia-3616/-/167086016019/2015.02.10 http://www.ebay.com/cln/pen-y77/-/167086017019/2015.02.10 http://www.ebay.com/cln/yua-me2/-/167399441016/2015.02.10 http://www.eba

百度电话费健身房拉伸件礼服加拉斯减肥

http://www.ebay.com/cln/cnli_c90nphs5e/-/167379958016/2015.02.07 http://www.ebay.com/cln/gaw4612/-/167226239018/2015.02.07 http://www.ebay.com/cln/re_len4/-/167263594010/2015.02.07 http://www.ebay.com/cln/ta.ku83/-/167162702017/2015.02.07 http://www.

百度回复金卡是减肥拉进来收付款

http://www.ebay.com/cln/cnli_c90nphs5e/-/167379958016/2015.02.08 http://www.ebay.com/cln/gaw4612/-/167226239018/2015.02.08 http://www.ebay.com/cln/re_len4/-/167263594010/2015.02.08 http://www.ebay.com/cln/ta.ku83/-/167162702017/2015.02.08 http://www.

百度放假哈萨克就发了设计费拉萨

http://www.ebay.com/cln/ldicn.mz6dm/2015.02.11/177030163015 http://www.ebay.com/cln/tan_qi5/2015.02.11/176903144013 http://www.ebay.com/cln/l.lu104/2015.02.11/177030175015 http://www.ebay.com/cln/ya01191/2015.02.11/176722580014 http://www.ebay.com/cl

百度房间撒谎发卡上就发了空间啊

http://www.ebay.com/cln/h-h4129/2015.02.11/176819191016 http://www.ebay.com/cln/fendo88/2015.02.11/176613943017 http://www.ebay.com/cln/ygon288/2015.02.11/176727517018 http://www.ebay.com/cln/ta.ch17/2015.02.11/176613950017 http://www.ebay.com/cln/g-

百度房间沙发客服就考试考几分离开

http://www.ebay.com/cln/jinlon8/book/167309734010/2015.02.10 http://www.ebay.com/cln/bam5330/book/167115292019/2015.02.10 http://www.ebay.com/cln/yi_za70/book/167315676012/2015.02.10 http://www.ebay.com/cln/y.y3463/book/167285977014/2015.02.10 http:/

Web Service学习笔记之----JAX-RPC

众所周知,数据科学是这几年才火起来的概念,而应运而生的数据科学家(data scientist)明显缺乏清晰的录取标准和工作内容.此次课程以<星际争霸II>回放文件分析为例,集中在IBM Cloud相关数据分析服务的应用.面对星际游戏爱好者希望提升技能的要求,我们使用IBM Data Science Experience中的jJupyter Notebooks来实现数据的可视化以及对数据进行深度分析,并最终存储到IBM Cloudant中.这是个介绍+动手实践的教程,参会者不仅将和讲师一起在线

02.lomboz与JDBC处理DDL语句应用举例

一.lomboz开发工具 Lomboz是Eclipse的一个主要的开源插件(open-source plug-in),Lomboz插件能够使Java开发者更好的使用Eclipse去创建,调试和部署一个100%基于J2EE的Java应用服务器. Lomboz插件的使用,使得Eclipse将多种J2EE的元素.Web应用的开发和最流行的应用服务器车结合为一体.用它来替换myeclipse是没有任何问题的,这里我们只需用来开发JDBC数据库应用程序. 1.下载及安装  lomboz的官方网站,http