当前位置: 移动技术网 > IT编程>开发语言>Java > JDBC-02

JDBC-02

2020年04月06日  | 移动技术网IT编程  | 我要评论

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网