ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JavaWEB-03-JDBC

2022-06-15 08:31:30  阅读:118  来源: 互联网

标签:03 JDBC JavaWEB sql jdbc mysql close 连接 String


内容

  • JDBC
  • JDBC
  • JDBC API
  • JDBC

1. JDBC入门

1.1 概述

  • 概念

    JDBC:Java DataBase ConnectivityJava数据库连接

    JDBC就是使用Java语言操作关系型数据库的一套API

    Sun公司和数据库厂商共同制定的一套连接并操作数据库的统一规范(接口),由数据库厂商负责实现(驱动Jar包);我们使用的时候只需要导入数据库厂商已经实现好的jar包即可。

  • 好处

    因为各个数据库厂商都实现了同一套JDBC接口规范。

    1. 我们可以使用同一套Java代码操作不同的关系型数据库
    2. 访问数据库的Java代码不改变的前提下,替换不同的驱动Jar包可以轻松更换数据库
  • 我们要怎么做

    整体思路:基于JDBC定义的规则编码,不用考虑不同数据库之间的差异

    1. 导数对应据库驱动包。
    2. 基于JDBC定义的规则轻松编程。

1.2 quick start

  • 实现步骤

    1. 导入Jar
    2. 注册驱动
    3. 获取连接
    4. 获取执行者对象
    5. 执行SQL语句,并且接收结果
    6. 处理结果
    7. 释放资源
  • 演示代码

    package com.cy.jdbc;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.Statement;
    
    /**
     * JDBC快速入门
     */
    public class JDBCDemo {
    
        public static void main(String[] args) throws Exception {
            //1. 注册驱动  建议写上去
            Class.forName("com.mysql.jdbc.Driver");
            //2. 获取连接
            //url  jdbc:mysql:///maven   == jdbc:mysql://127.0.0.1:3306/maven
            //jdbc:mysql://ip:数据库端口号/数据库名称?添加自定义参数
            String url = "jdbc:mysql://127.0.0.1:3306/maven";
            String username = "root";
            String password = "root";
            //Connection 数据库的连接对象
            Connection conn = DriverManager.getConnection(url, username, password);
            //3. 定义sql
            String sql = "update account set money = ? where id = ?";
            //4. 获取执行sql的对象 Statement
            //Statement stmt = conn.createStatement();
            PreparedStatement pps = conn.prepareStatement(sql);
    
            pps.setDouble(1,3000);
            pps.setInt(2,1);
    
            //5. 执行sql
            //int count = stmt.executeUpdate(sql);//受影响的行数  执行增删改
            int count = pps.executeUpdate();
    
            //6. 处理结果  受影响的行数
            System.out.println(count);
            //7. 释放资源
            pps.close();
            conn.close();
        }
    }
    

2. jdbc常用API

2.1 DriverManager

功能1:注册驱动

  • 不需要手动调用DriverManagerAPI注册,而是保证com.mysql.jdbc.Driver被加载进内存即可。

查看com.mysql.jdbc.Driver类的源码

package com.mysql.jdbc;

import java.sql.DriverManager;
import java.sql.SQLException;

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    public Driver() throws SQLException {
    }

    static {
        try {
            // 在静态代码块中完成了注册驱动的代码
            // 我们只要保证Driver被加载进内存,下面的注册驱动的步骤就会自动完成。
            /*
            	Class.forName("com.mysql.jdbc.Driver");
            	Driver.class //Driver的字节码对象
            	new Driver(); // 多一个driver对象
            */
            /*
            	在MySQL5以上的版本,注册驱动不需要我们自己做了。
            	在mysql-connector-java-5.1.47.jar中META-INF下面services下面的
            	java.sql.Driver文件中,填写了com.mysql.jdbc.Driver全类名
            	该类的便会自动被加载进内存
            */
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }
}

功能2:获取连接对象

static Connection getConnection(url, username, password)

//3.获取连接
// 相当于之前使用mysql工具连接数据库
// 完整格式:jdbc:mysql://ip:数据库端口号/数据库名称?添加自定义参数
// jdbc:mysql://就是协议 相当于 http://
// url连本机  jdbc:mysql://localhost:3306/db2 简化写法jdbc:mysql:///db2 
// 可选自定义参数:useSSL=false 不是用SSL加密并取消提示

Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1","root","root");

2.2 Connection

就像打电话,一个Connection对象,就是一通电话。

所以连接又称会话,Session

功能1:获取执行者对象

该对象会执行SQL语句

  • 获取普通执行者对象:Statement createStatement();

  • 获取预编译执行者对象:PreparedStatement prepareStatement(String sql);

功能2:控制事务

Connection中定义了三个方法,用来控制事务。对应MySQL中的三种操作。

  • 开启:setAutoCommit(boolean autoCommit); 参数为false,则开启事务。

  • 提交:commit();

  • 回滚:rollback();

功能3:释放资源

  • close();

演示代码

package com.cy.jdbc;

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

/**
 * JDBC API 详解:Connection
 */
public class JDBCDemo3_Connection {

    public static void main(String[] args) throws Exception {
        //1. 注册驱动  建议写上去
        Class.forName("com.mysql.jdbc.Driver");
        //2. 获取连接,配置连接四要素
        //jdbc:mysql://ip:数据库端口号/数据库名称?添加自定义参数
        String url = "jdbc:mysql://127.0.0.1:3306/web22_day03_jdbc";
        String username = "root";
        String password = "root";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3. 定义sql
        String sql1 = "update account set money = money - 500 where id = 1";
        String sql2 = "update account set money = money + 500 where id = 2";
        //4. 获取执行sql的对象 Statement
        Statement stmt = conn.createStatement();
        try {
            // 开启事务
            conn.setAutoCommit(false);
            //5. 执行sql
            int count1 = stmt.executeUpdate(sql1);//受影响的行数
            //6. 处理结果
            System.out.println(count1);
            int i = 3/0;
            //5. 执行sql
            int count2 = stmt.executeUpdate(sql2);//受影响的行数
            //6. 处理结果
            System.out.println(count2);

            // 提交事务
            conn.commit();
        } catch (Exception throwables) {
            // 回滚事务,手动开启事务之后,该操作可以省略。
            // 没有没有提交,他也不会自动提交,就相当于回滚了。
            // conn.rollback();
            throwables.printStackTrace();
        }

        //7. 释放资源
        stmt.close();
        conn.close();
    }
}

2.3 Statement

执行者对象,执行SQL语句并返回SQL语句执行的结果/结果集。

  • 执行DML/DDL语句:修改(增删改)

    int executeUpdate(String sql);

    返回值int:返回影响的行数。

    参数sqlinsertupdatedelete语句。

    一般不会在Java代码中执行DDL语句,Java中主要完成对数据库中表记录的操作。

  • 执行DQL语句:查询

    ResultSet executeQuery(String sql);

    返回值ResultSet:封装查询的结果集。

    参数sqlselect语句。

  • 释放资源

    立即将执行者对象释放:void close();

  • 演示代码:演示增删改

    /**
     * statement执行dql,并获取结果集
     * JDBC API 详解:Statement
     */
    public class JDBCDemo4_Statement {
    
        /**
         * 执行DML语句
         * @throws Exception
         */
        @Test
        public void testDML() throws  Exception {
           //1. 注册驱动
           //Class.forName("com.mysql.jdbc.Driver");
           //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
           String url = "jdbc:mysql:///maven?useSSL=false";
           String username = "root";
           String password = "root";
           Connection conn = DriverManager.getConnection(url, username, password);
           //3. 定义sql
           String sql = "update account set money = 4000 where id = 1";
           //4. 获取执行sql的对象 Statement
           Statement stmt = conn.createStatement();
           //5. 执行sql
           int count = stmt.executeUpdate(sql);//执行完DML语句,受影响的行数
    
           //6. 处理结果
            if(count > 0){
                System.out.println("修改成功~");
            }else{
                System.out.println("修改失败~");
            }
           //7. 释放资源
           stmt.close();
           conn.close();
    
       }
    
    
        /**
         * 执行DDL语句
         * @throws Exception
         */
        @Test
        public void testDDL() throws  Exception {
            //1. 注册驱动
            //Class.forName("com.mysql.jdbc.Driver");
            //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
            String url = "jdbc:mysql:///db1?useSSL=false";
            String username = "root";
            String password = "1234";
            Connection conn = DriverManager.getConnection(url, username, password);
            //3. 定义sql
            String sql = "drop database db2";
            //4. 获取执行sql的对象 Statement
            Statement stmt = conn.createStatement();
            //5. 执行sql
            int count = stmt.executeUpdate(sql);//执行完DDL语句,可能是0
            //6. 处理结果
            //System.out.println(count);
           /* if(count > 0){
                System.out.println("修改成功~");
            }else{
    
                System.out.println("修改失败~");
            }*/
            System.out.println(count);
    
            //7. 释放资源
            stmt.close();
            conn.close();
    
        }
    }
    
  • 演示代码:查询及结果集处理

    public class JDBCDemo5_ResultSet {
    
        /**
         * 执行DQL
         *
         * @throws Exception
         */
        @Test
        public void testResultSet() throws Exception {
            //1. 注册驱动
            //Class.forName("com.mysql.jdbc.Driver");
            //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
            String url = "jdbc:mysql:///maven?useSSL=false";
            String username = "root";
            String password = "root";
            Connection conn = DriverManager.getConnection(url, username, password);
    
            //3. 定义sql
            String sql = "select * from account";
    
            //4. 获取statement对象
            Statement stmt = conn.createStatement();
    
            //5. 执行sql  executeQuery
            ResultSet rs = stmt.executeQuery(sql);
    
    
            // 6.1 光标向下移动一行,并且判断当前行是否有数据
            while (rs.next()) { //移动到下一行
                //6.2 获取数据  getXxx()
                
                int id = rs.getInt("id");
                String name = rs.getString("name");
                double money = rs.getDouble("money");
    
                System.out.println("id = " + id);
                System.out.println("name = " + name);
                System.out.println("money = " + money);
            }
    
            //7. 释放资源
            rs.close();
            stmt.close();
            conn.close();
        }
    }
    

2.4 查询并封装POJO对象案例

2.4.1 需求

查询account账户表数据,封装为Account对象中,并且存储到ArrayList集合中

2.4.2 核心步骤

  1. 使用上述操作完成查询,查询出结果集。
  2. 定义实体类Account
  3. 查询数据,封装到Account对象中
  4. Account对象存入ArrayList集合中

2.4.3 演示代码

package com.cy.pojo;

public class Account {

    private int id;
    private String name;
    private double money;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}
/**
 * 实现需求:查询account账户表数据,封装为Account对象中,并且存储到ArrayList集合中
 */
public class JDBCDemo5_ResultSet {
  
    /**
     * 查询account账户表数据,封装为Account对象中,并且存储到ArrayList集合中
     * 1. 定义实体类Account
     * 2. 查询数据,封装到Account对象中
     * 3. 将Account对象存入ArrayList集合中
     *
     *
     * @throws Exception
     */
    @Test
    public void testResultSet2() throws  Exception {
        //1. 注册驱动
        //Class.forName("com.mysql.jdbc.Driver");
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql:///maven?useSSL=false";
        String username = "root";
        String password = "root";
        Connection conn = DriverManager.getConnection(url, username, password);

        //3. 定义sql
        String sql = "select * from account";

        //4. 获取statement对象   不能用(Statement)
        //Statement stmt = conn.createStatement();
        PreparedStatement pps = conn.prepareStatement(sql);
        //5. 执行sql
        //ResultSet rs = stmt.executeQuery(sql);
        ResultSet rs = pps.executeQuery();
        // 创建集合
        List<Account> list = new ArrayList<>();

        // 6.1 光标向下移动一行,并且判断当前行是否有数据
        while (rs.next()){
            Account account = new Account();
            int id = rs.getInt("id");
            String name = rs.getString("name");
            double money = rs.getDouble("money1");
            account.setId(id);
            account.setName(name);
            account.setMoney(money);
            // 存入集合
            list.add(account);
        }
        System.out.println(list);

        //7. 释放资源
        rs.close();
        pps.close();
        conn.close();
    }
}

2.5 PreparedStatement

2.5.1概述

预编译的执行者对象,执行SQL语句并返回SQL语句执行的结果集。

相对于Statement来说,PreparedStatement有额外两个作用:

  1. 通过转义字符避免SQL注入问题。
  2. 开启预编译后,通过预编译可以提高SQL语句的执行效率。

2.5.2 使用及API

  • 获取该对象

    // 这里的SQL语句,不需要指定参数,而是通过?作为占位符,后面再通过setString方法把参数设置进来
    PreparedStatement  connection.prepareStatement(sql)
    
  • 设置参数

    // index 从1 开始
    pst.setString(int index, String paramter)
    
  • 执行DML语句:修改(增删改)

    int executeUpdate();

    返回值int:返回影响的行数。

    执行DQL语句:查询

    ResultSet executeQuery();

    返回值ResultSet:封装查询的结果集。

  • 释放资源

    立即将执行者对象释放:void close();

  • 演示代码

    /**
      *
      * @throws Exception
      */
    @Test
    public void testPreparedStatement() throws  Exception {
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql:///db1?useSSL=false";
        String username = "root";
        String password = "1234";
        Connection conn = DriverManager.getConnection(url, username, password);
    
        // 接收用户输入 用户名和密码
        String name = "zhangsan";
        String pwd = "' or '1' = '1";
    
        // 定义sql   预编译sql   ? 占位符
        String sql = "select * from tb_user where username = ? and password = ?";
    
        // 获取pstmt对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
    
        // 设置?的值
        pstmt.setString(1,name);
        pstmt.setString(2,pwd);
    
        // 执行sql
        ResultSet rs = pstmt.executeQuery();
    
        // 判断登录是否成功
        if(rs.next()){
            System.out.println("登录成功~");
        }else{
            System.out.println("登录失败~");
        }
    
        //7. 释放资源
        rs.close();
        pstmt.close();
        conn.close();
    }
    

2.5.3 原理

可以通过日志看到其运行原理及效果。

  • 准备工作1:开启预编译

    想要看小预编译执行者对象的执行效果,需要先在url中开启预编译,添加如下自定义参数即可

    useServerPrepStmts=true
    

    添加该参数后,完整的URL链接如下:

    jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true
    
  • 准备工作2:打开日志,查看预编译等相关效果

    my.ini文件末尾,添加如下内容,并重启MySQL服务。

    log-output=FILE
    general-log=1
    general_log_file="D:\mysql.log"
    slow-query-log=1
    slow_query_log_file="D:\mysql_slow.log"
    long_query_time=2
    
  • 重启MySQL

    方式1:可以打开服务窗口,手动重启MySQL服务。

    方式2:在以管理员身份打开的命令行中,键入以下命令

    net stop mysql  # 关闭mysql服务
    net start mysql  # 开启mysql服务
    
  • 结论

    通过修改查询相关代码,并查看日志,可以得出如下结论:

    1. URL中开启预编译后,相同模板的SQL语句在创建预编译执行者对象的时候,就已经发送到SQL,并完成了语法检查和编译。
    2. 预编译执行者对象,在往SQL模板中设置参数的时候,会对参数中的特殊符号添加转义字符\,避免SQL注入
    3. 使用相同模板的多条不同参数的SQL语句,只会在第一次创建预编译执行者对象的时候编译一次,从而提高执行效率。
  • 演示代码

    /**
     * PreparedStatement原理
     * @throws Exception
     */
    @Test
    public void testPreparedStatement2() throws  Exception {
    
    
    
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        // useServerPrepStmts=true 参数开启预编译功能
        String url = "jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true";
        String username = "root";
        String password = "root";
        Connection conn = DriverManager.getConnection(url, username, password);
    
        // 接收用户输入 用户名和密码
        String name = "zhangsan";
        String pwd = "' or '1' = '1";
    
        // 定义sql
        String sql = "select * from tb_user where username = ? and password = ?";
    
        // 获取pstmt对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
    
    
        Thread.sleep(10000);
        // 设置?的值
        pstmt.setString(1,name);
        pstmt.setString(2,pwd);
        ResultSet rs = null;
                // 执行sql
        rs = pstmt.executeQuery();
    
    
        // 设置?的值
        pstmt.setString(1,"aaa");
        pstmt.setString(2,"bbb");
    
        // 执行sql
        rs = pstmt.executeQuery();
    
    
        // 判断登录是否成功
        if(rs.next()){
            System.out.println("登录成功~");
        }else{
            System.out.println("登录失败~");
        }
    
        //7. 释放资源
        rs.close();
        pstmt.close();
        conn.close();
    }
    

3. SQL注入及解决方案

3.1. 产生的原因

使用任意用户名并配合下面的密码,登录

' or '1' = '1

普通执行者对象拼接后的SQL 语句,变成了:

select * from tb_user where username = 'xxxx' and password = '' or '1' = '1'

普通的statement只是把用户输入的用户名和密码进行了简单的拼接,拼接到了SQL语句中。

这样,用户名或密码中特殊的单子或符号就被识别成了SQL语句中的关键字或者是特殊符号。

思路:仅把' or 1=1 -- 当做普通的字符串来处理,使用转义符号\,然后面的符号表示其本来的意思(现原形)。

PreparedStatement就是使用这个思路解决的。

PreparedStatement中的方法public void setString(int parameterIndex, String x) throws SQLException

// 提前准备好长度变量,不用每次调用length()方法,效率高
int stringLength = x.length();

for(int i = 0; i < stringLength; ++i) {
    // 获取参数的每一个字符
    char c = x.charAt(i);
    
    // 判断是否是特殊符号,如果是就在前面拼一个 \  转义,让这个特殊符号表示自己原来的意思。
    switch(c) {
        case '\u0000':
            buf.append('\\');
            buf.append('0');
            break;
        case '\n':
            buf.append('\\');
            buf.append('n');
            break;
        case '\r':
            buf.append('\\');
            buf.append('r');
            break;
        case '\u001a':
            buf.append('\\');
            buf.append('Z');
            break;
        case '"':
            if (this.usingAnsiMode) {
                buf.append('\\');
            }

            buf.append('"');
            break;
        case '\'':
            buf.append('\\');
            buf.append('\'');
            break;
        case '\\':
            buf.append('\\');
            buf.append('\\');
            break;
        case '¥':
        case '₩':
            if (this.charsetEncoder != null) {
                CharBuffer cbuf = CharBuffer.allocate(1);
                ByteBuffer bbuf = ByteBuffer.allocate(1);
                cbuf.put(c);
                cbuf.position(0);
                this.charsetEncoder.encode(cbuf, bbuf, true);
                if (bbuf.get(0) == 92) {
                    buf.append('\\');
                }
            }

            buf.append(c);
            break;
        default:
            buf.append(c);
    }
}

4. 连接池

4.1 概念

初始化并维护多个连接对象,当其他地方需要数据库连接时,从连接池获取;用完之后,归还到连接池。

以此实现连接的复用,提高效率。

数据源:DataSource,内部维护了一个连接池,还提供了操作连接池的一些功能。

一般情况下,会把数据源和连接池混为一谈,把数据源喊做连接池。

常见的数据源有:C3P0、Druid。我们学习Druid

4.2 池化思想(重要)

以空间换时间的做法。

游戏背包、新闻客户端。

  1. 提供更好的使用体验
  2. 对资源的消耗会更少。不会频繁的创建和销毁对象。
1596678583095

img

4.3 Druid使用

4.3.1 导包

// 导包并添加到添加了模块类库
druid-1.1.12.jar

4.3.2 配置文件

properties配置文件(名字任意),但是配置文件中key的值固定。常见参数如下:

# 连接四要素
# 数据库驱动全类名
driverClassName=com.mysql.jdbc.Driver
# URL
url=jdbc:mysql:///maven?useSSL=false&useServerPrepStmts=true
#用户名
username=root
#密码
password=root

# 其他参数
# 初始化连接数
initialSize=5
# 最大连接数
maxActive=10
# 超时时间
maxWait=3000

完整参数介绍:

属性 说明 建议值
url 数据库的jdbc连接地址。一般为连接oracle/mysql。示例如下:
mysql : jdbc:mysql://ip:port/dbname?option1&option2&…
oracle : jdbc:oracle:thin:@ip:port:oracle_sid
username 登录数据库的用户名
password 登录数据库的用户密码
initialSize 启动程序时,在连接池中初始化多少个连接 10-50已足够
maxActive 连接池中最多支持多少个活动会话
maxWait 程序向连接池中请求连接时,超过maxWait的值后,认为本次请求失败,即连接池 100
没有可用连接,单位毫秒,设置-1时表示无限等待
minEvictableIdleTimeMillis 池中某个连接的空闲时长达到 N 毫秒后, 连接池在下次检查空闲连接时,将 见说明部分
回收该连接,要小于防火墙超时设置
net.netfilter.nf_conntrack_tcp_timeout_established的设置
timeBetweenEvictionRunsMillis 检查空闲连接的频率,单位毫秒, 非正整数时表示不进行检查
keepAlive 程序没有close连接且空闲时长超过 minEvictableIdleTimeMillis,则会执 true
行validationQuery指定的SQL,以保证该程序连接不会池kill掉,其范围不超
过minIdle指定的连接个数。
minIdle 回收空闲连接时,将保证至少有minIdle个连接. 与initialSize相同
removeAbandoned 要求程序从池中get到连接后, N 秒后必须close,否则druid 会强制回收该 false,当发现程序有未
连接,不管该连接中是活动还是空闲, 以防止进程不会进行close而霸占连接。 正常close连接时设置为true
removeAbandonedTimeout 设置druid 强制回收连接的时限,当程序从池中get到连接开始算起,超过此 应大于业务运行最长时间
值后,druid将强制回收该连接,单位秒。
logAbandoned 当druid强制回收连接后,是否将stack trace 记录到日志中 true
testWhileIdle 当程序请求连接,池在分配连接时,是否先检查该连接是否有效。(高效) true
validationQuery 检查池中的连接是否仍可用的 SQL 语句,drui会连接到数据库执行该SQL, 如果
正常返回,则表示连接可用,否则表示连接不可用
testOnBorrow 程序 申请 连接时,进行连接有效性检查(低效,影响性能) false
testOnReturn 程序 返还 连接时,进行连接有效性检查(低效,影响性能) false
poolPreparedStatements 缓存通过以下两个方法发起的SQL: true
public PreparedStatement prepareStatement(String sql)
public PreparedStatement prepareStatement(String sql,
int resultSetType, int resultSetConcurrency)
maxPoolPrepareStatement
PerConnectionSize
每个连接最多缓存多少个SQL 20
filters 这里配置的是插件,常用的插件有: stat,wall,slf4j
监控统计: filter:stat
日志监控: filter:log4j 或者 slf4j
防御SQL注入: filter:wall
connectProperties 连接属性。比如设置一些连接池统计方面的配置。
druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
比如设置一些数据库连接属性:

4.3.3 代码

public class DruidDemo {

    public static void main(String[] args) throws Exception {
        //1.导入jar包
        //2.定义配置文件

        //3. 加载配置文件  map集合  key-value
        Properties prop = new Properties();
        prop.load(new FileInputStream("web_day03_jdbc-demo/src/druid.properties"));
        //4. 获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);

        //5. 获取数据库连接 Connection
        Connection connection = dataSource.getConnection();

        System.out.println(connection);

        // 这里可以调用connection的close方法
        // Druid充了connection的close方法,实现逻辑变成了回收连接,而非关闭连接
        connection.close();


        // 获取当前代码的运行路径,可以运行下面一行代码
        //System.out.println(System.getProperty("user.dir"));
    }
}

标签:03,JDBC,JavaWEB,sql,jdbc,mysql,close,连接,String
来源: https://www.cnblogs.com/chenyong1144/p/16377075.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有