欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JDBC-02

程序员文章站 2022-12-08 23:35:09
JDBC 前言 在JDBC-01当中,我们简单地学习了有关JDBC的一些基本操作,现在我们再一次进行深入的学习。 正文 事务 首先,我们来学习的是JDBC中事务的运用,那么让我们再次了解一下事务的概念。 事务的概念 事务指的是逻辑上的一组操作,组成这组操作各个逻辑单元要么全部成功,要么全部失败。 关 ......

jdbc

前言

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

 

正文

事务

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

事务的概念

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

关于事务的api

getautocommit()

JDBC-02

 

commit()

JDBC-02

 

rollback()

 

JDBC-02

 

异常案例:

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);
        }



    }
}

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

 

连接池

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

好处(作用):

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

 

连接池原理:

JDBC-02

 

自定义连接池:

  我们可以利用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操作:(实例源于黑马,博主在这偷个懒)

添加:

JDBC-02

 

修改:

JDBC-02

 

删除:

JDBC-02

 

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

JDBC-02

 

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

JDBC-02

 

resultsethandler的实现类:

arrayhandler 和 arraylisthandler:

JDBC-02

 

JDBC-02

 

beanhandler 和 beanlisthandler (重要!!):

JDBC-02

JDBC-02

JDBC-02

 

maphandler 和 maplisthandler:

JDBC-02

JDBC-02

JDBC-02

 

columnlisthandler 和 scalarhandler 还有 keyedhandler:

columnlisthandler:

JDBC-02

 

scalarhandler:查询表中有多少列

JDBC-02

 

keyedhandler:

JDBC-02

 

JDBC-02

JDBC-02

 

 

小结

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

                                   加油!

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

推荐阅读