Javaweb之JDBC

1.jdbc的概念

Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。通俗易懂说:jdbc就是java操作数据库api的封装

在这里插入图片描述
不同数据库采用相同的接口规范,但不是有Java实现,而是由数据库厂商实现的,所以使用JDBC连接数据库要加载驱动

2.JDBC快速入门

使用JDBC的步骤:
1.导入mysql驱动jar包;
2.注册驱动 javase 反射机制Class.forName()
3.获取数据库连接
4.获取执行者对象
5.执行sql语句并获取返回结果
6.对结果进行处理
7.释放jdbc资源

package com.zhxd.jdbc.test;
import com.mysql.jdbc.Driver;

import java.sql.*;

public class TestJDBC1 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1、导入驱动
        //2.注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //3.创建数据库连接
        Connection connection = DriverManager.getConnection(
                "jdbc:mysql://127.0.0.1:3306/myemployees", "root", "root");
        //4.获取执行者对象
        Statement statement = connection.createStatement();
        //5.执行sql语句并返回结果
        ResultSet resultSet = statement.executeQuery("select * from employees");
        //6.处理返回的结果
        while(resultSet.next()) {
            System.out.println(resultSet.getString("last_name"));
        }
        //7.释放资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}

3.认识JDBC的API

3.1 DriverManager注册驱动

注册驱动的方式:
1.DriverManager.registerDriver(new Driver());
2.通过反射机制:Class.forName(“com.mysql.jdbc.Driver”)

com.mysql.jdbc.Driver类中存在静态代码块

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

    static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }
}

3.2DriverManager.getConnection()获取数据库连接对象

Connection connection = DriverManager.getConnection(“数据库连接地址”,
“用户名称”, “用户密码”);
参数:指定连接的路径 语法:jdbc://mysql://ip地址:端口号码/数据库名称
user:用户名称
pwd:用户的密码

3.3 Statement 执行Sql语句对象

1.boolean execute(String sql):可以执行任意的sql语句
2.int executeUpdate(string sql):可执行DML和DDL语句
3.Resultset executeQuery(String sql):执行DQL语句

3.4Resultset 获取查询结果集

1.判断结果集是否有数据: boolean next();
有数据返回true 并将索引向下移动一行
没有数据返回false
2.获取结果集中的数据:xxx.getxx(列名称) 注意与 数据库数据类型需要对应,比如resultSet.getInt()/resultSet.getString()

4.JBDC案例

需求:
需求1:查询所有学生信息
需求2:根据id查询学生信息
需求3:新增学生信息 ----insert into
需求4:根据主键id修改学生信息
需求5:根据主键id删除学生信息 企业实际开发中 不会真正物理删除数据 而是隐藏update的形式。—javaweb开发。

分层架构
com.zhxd.entity—实体类----创建实体类与数据库表结构字段一一对应的
com.zhxd.dao----数据库访问层----db打交道
com.zhxd.serivce—业务逻辑层
如果在db数据类型是为varchar 对应 string
如果在db数据类型是为int对应 Integer

PS:为什么要有Service和Dao层
Dao负责封装数据库的增删改查方法,数据表和实体类字段一一对应,这样不方便后期数据的修改,对数据进行修改都交给Service层
在这里插入图片描述

4.1实体类层

package com.zhxd.jdbc.entity;
/*
 * author zhxd
 * ClassName StudentEntity
 * date 2022/12/3 10:20
 */

/*
* 定义学生实体类
* */
public class StudentEntity {
    private Long id;
    private String name;
    private Integer age;
    private String address;

    public StudentEntity(Long id, String name, Integer age, String address) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    public String getAddress() {
        return address;
    }

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

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

    public void setAge(Integer age) {
        this.age = age;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "StudentEntity{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}

4.2 Dao层

package com.zhxd.jdbc.dao;
/*
 * author zhxd
 * ClassName StudentDao
 * date 2022/12/3 10:27
 */

import com.zhxd.jdbc.entity.StudentEntity;

import java.sql.*;
import java.util.*;

public class StudentDao {
    /**
     * 学生对象数据库访问层
     * */

    /**
     * 查询所有学生的信息
     *
     * @return
     */

    public ArrayList<StudentEntity> allStudent() {
        ArrayList<StudentEntity> students = new ArrayList<StudentEntity>();
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;

        try {
            //        1.导入mysql驱动jar包;
//        2.注册驱动 javase 反射机制Class.forName()
            Class.forName("com.mysql.jdbc.Driver");
//        3.获取数据库连接
            connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/zhxd", "root", "root");
//            4.获取执行者对象
            statement = connection.createStatement();
//            5.执行sql语句并获取返回结果
            resultSet = statement.executeQuery("select * from zhxd_student");
//            6.对结果进行处理
            while (resultSet.next()) {
                Long id = resultSet.getLong("id");
                String name = resultSet.getString("name");
                Integer age = resultSet.getInt("age");
                String address = resultSet.getString("address");
                StudentEntity student = new StudentEntity(id, name, age, address);
                students.add(student);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
//            7. 释放jdbc资源
            try {
                if (resultSet != null) resultSet.close();
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                return students;
            }
        }
    }

    /**
     * 根据id查询学生信息
     *
     * @return
     */
    public StudentEntity getStudentById(Long stuId) {
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        StudentEntity student = null;
        try {
//        1.导入mysql驱动jar包;
//        2.注册驱动 javase 反射机制Class.forName()
            Class.forName("com.mysql.jdbc.Driver");
//        3.获取数据库连接
            connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/zhxd", "root", "root");
//            4.获取执行者对象
            statement = connection.createStatement();
//            5.执行sql语句并获取返回结果
            resultSet = statement.executeQuery("select * from zhxd_student");
//            6.对结果进行处理
            if (resultSet.next()) {
                Long id = resultSet.getLong("id");
                String name = resultSet.getString("name");
                Integer age = resultSet.getInt("age");
                String address = resultSet.getString("address");
                student = new StudentEntity(id, name, age, address);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
//            7. 释放jdbc资源
            try {
                if (resultSet != null) resultSet.close();
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                return student;
            }
        }
    }

    /**
     * 修改学生信息
     *
     * @return
     */
    public int updatetStudent(StudentEntity student) {
        Connection connection = null;
        Statement statement = null;
        int result = 0;
        try {
//        1.导入mysql驱动jar包;
//        2.注册驱动 javase 反射机制Class.forName()
            Class.forName("com.mysql.jdbc.Driver");
//        3.获取数据库连接
            connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/zhxd?characterEncoding=gbk", "root", "root");
//            4.获取执行者对象
            statement = connection.createStatement();
//            5.执行sql语句并获取返回结果
            String updateStr = "update zhxd_student set name = " + "'" + student.getName() + "'" + ",age = " + student.getAge() +
                    ",address = " + "'" + student.getAddress() + "'" + " where id = " + student.getId();
            System.out.println(updateStr);
            result = statement.executeUpdate(updateStr);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
//            7. 释放jdbc资源
            try {
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                return result;
            }
        }
    }

    /**
     * 删除学生信息
     *
     * @return
     */
    public int deleteStudent(Long id) {
        Connection connection = null;
        Statement statement = null;
        int result = 0;
        try {
//        1.导入mysql驱动jar包;
//        2.注册驱动 javase 反射机制Class.forName()
            Class.forName("com.mysql.jdbc.Driver");
//        3.获取数据库连接
            connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/zhxd", "root", "root");
//            4.获取执行者对象
            statement = connection.createStatement();
//            5.执行sql语句并获取返回结果
            String deleteStr = "delete from zhxd_student where id = " + id;
            result = statement.executeUpdate(deleteStr);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
//            7. 释放jdbc资源
            try {
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                return result;
            }
        }
    }

    /**
     * 插入学生信息
     *
     * @return
     */
    public int insertStudent(StudentEntity student) {
        Connection connection = null;
        Statement statement = null;
        int result = 0;
        try {
//        1.导入mysql驱动jar包;
//        2.注册驱动 javase 反射机制Class.forName()
            Class.forName("com.mysql.jdbc.Driver");
//        3.获取数据库连接
            connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/zhxd?characterEncoding=gbk", "root", "root");
//            4.获取执行者对象
            statement = connection.createStatement();
//            5.执行sql语句并获取返回结果
            String insertStr = "insert into zhxd_student values(null," + "'" +student.getName() +"'" + "," + student.getAge() + "," +
                    "'"+ student.getAddress() + "'" + ")";
            result = statement.executeUpdate(insertStr);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
//            7. 释放jdbc资源
            try {
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                return result;
            }
        }
    }
}

4.3Service层

package com.zhxd.jdbc.service;
/*
 * author zhxd
 * ClassName StudentService
 * date 2022/12/3 10:45
 */

import com.zhxd.jdbc.dao.StudentDao;
import com.zhxd.jdbc.entity.StudentEntity;

import java.util.ArrayList;

public class StudentService {
    private StudentDao studentDao = new StudentDao();

    /**
     * 查询所有学生信息
     *
     * @return
     * */
    public ArrayList<StudentEntity> allStudent() {
        return studentDao.allStudent();
    }

    /**
     * 根据id查询学生信息
     *
     * @return
     * */
    public StudentEntity getStudentById(Long id) {
        return studentDao.getStudentById(id);
    }

    /**
     * 插入学生信息
     *
     * @return
     * */
    public int insertStudent(StudentEntity student) {
        return studentDao.insertStudent(student);
    }

    /**
     * 删除学生信息
     *
     * @return
     * */
    public int deleteStudent(Long id) {
        return studentDao.deleteStudent(id);
    }
    /**
     * 修改学生信息
     *
     * @return
     * */
    public int updatetStudent(StudentEntity student) {
        return studentDao.updatetStudent(student);
    }
}

5、jdbc工具类封装

目的:抽取公共代码,简化代码的书写,减少代码冗余
步骤:

  1. 编写配置文件:在src目录下创建config.properties文件
  2. 编写jdbc工具 获取连接 释放连接

编写配置文件

driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/zhxd?characterEncoding=gbk
user=root
password=root

编写JDBC工具类

package com.zhxd.utils;
/*
 * author zhxd
 * ClassName JDBCUtil
 */

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JDBCUtil {
    /*
    * 1.需要将构造方法私有化 ---工具类 不需要实例化对象 通过类名.方法名访问
    * */

    private JDBCUtil() {
    }

    /*
    * 2.定义工具类 需要 声明 变量
    * */
    private static String driverClass;
    private static String url;
    private static String user;
    private static String password;

    /*
    * 3.使用静态代码块来给我们声明jdbc变量赋值(读取config.properties)
    * */
    static {
        //1.读取config.properties IO 相对路径
        try{
            InputStream resourceAsStream =
                    JDBCUtil.class.getClassLoader().getResourceAsStream("config.properties");
            Properties properties = new Properties();
            properties.load(resourceAsStream);
            //2.赋值给声明的变量
            driverClass = properties.getProperty("driverClass");
            url = properties.getProperty("url");
            user = properties.getProperty("user");
            password = properties.getProperty("password");
            //3.注册驱动类
            Class.forName(driverClass);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
    * 4.封装连接方法
    * */

    public static Connection getConnection() {
        Connection connection = null;
        try{
            connection = DriverManager.getConnection(url, user, password);
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            return connection;
        }
    }

    /*
    * 5.释放连接的方法
    * */
    //重载,区分DQL和DML语句
    //DQL
    public static void closeConnection(ResultSet resultSet, Statement statement, Connection connection) {
        try {
            if (resultSet != null) resultSet.close();
            if (statement != null) statement.close();
            if (connection != null) connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    //DML
    public static void closeConnection(Connection connection, Statement statement) {
        closeConnection(null, statement,connection);
    }
}

改造Dao层的代码(以查询为例):

 /**
 * 查询所有学生的信息
 *
 * @return
 */

public ArrayList<StudentEntity> allStudent() {
    ArrayList<StudentEntity> students = new ArrayList<StudentEntity>();
    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;

    try {
        //修改前
        /*
        *Class.forName("com.mysql.jdbc.Driver");
        *connection = DriverManager.getConnection(
        *       "jdbc:mysql://127.0.0.1:3306/zhxd?characterEncoding=gbk", "root", "root");
        */
        
        //修改后
        connection = JDBCUtil.getConnection();
        statement = connection.createStatement();
        resultSet = statement.executeQuery("select * from zhxd_student");
        while (resultSet.next()) {
            Long id = resultSet.getLong("id");
            String name = resultSet.getString("name");
            Integer age = resultSet.getInt("age");
            String address = resultSet.getString("address");
            StudentEntity student = new StudentEntity(id, name, age, address);
            students.add(student);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        //修改前
        /*
        *try {
        *    if (resultSet != null) resultSet.close();
        *    if (statement != null) statement.close();
        *    if (connection != null) connection.close();
        *} catch (SQLException e) {
        *    e.printStackTrace();
        *}
        */
        
        //修改后
        JDBCUtil.closeConnection(resultSet, statement, connection);
        return students;
    }
}

6、SQL注入攻击及预防

什么是SQL攻击?
就是利用SQL语句的漏洞实现对系统的攻击,底层原理就是通过传递参数('or 1 = '1)导致SQL语句成立可以查询到数据

登录SQL语句:select * from user where phone=’ ’ and pwd = ’ ’
但是攻击者传递pwd参数为’or 1 = ’ 1,这时SQL语句为
select * from user where phone=‘’ and pwd = ‘’ or 1 = ‘1’;
使用SQL语句拼接的情况下,很容易被攻击者sql注入

6.1如何解决SQL注入?

使用PreparedStatement(预编译执行者对象),在sql语句执行前,将sql语句提前编译,明确sql语句格式后再传递参数,就不会出现拼接sql语句的情况。
sql语句使用?占位,占位符赋值方式为setXXX(参数1,参数2)
XXX:数据类型,参数1:?的位置从编号1开始,参数2:?的实际参数

PreparedStatement statement = null;
String loginSql = "select * from users where phone=? and pwd=?;";
statement = connection.prepareStatement(loginSql );
statement.setString(1, userEntity.getPhone());
statement.setString(2, userEntity.getPwd());

7.JDBC事务

  • 事务:同时执行多个业务,这些业务要么全部执行成功,要么全部执行失败
  • 提交事务:事务里面做的写操作,可以查询到写完之后的数据
  • 回滚事务:事务里面做的写操作,直接回滚,查询不到

如果开启了事务,但是没有回滚或者提交,我们是查询不到未提交的数据

  • 直接使用SET来改变MySQL的自动提交模式,SET AUTOCOMMIT = 0/1,0:禁止自动提交,1:开启自动提交
  • 用BEGIN ROLLBACK COMMIT来实现管理事务,BEGIN开启一个事务,ROLLBACK事务回滚,COMMIT事务确认

JDBC手动事务,使用Connection对象实现

  • 开启事务:setAutoCommit(boolean aotuCommit),false代表禁止自动提交,即开启事务
  • 提交事务:commit(),当执行完sql提交事务
  • 回滚事务:rollback(),通常会在异常处理catch中回滚

在mysql InnoDB存储引擎中 多个线程如果同时修改同一行数据 最终只会有一个线程修改成功。
InnoDB存储引擎—行锁

  • 查看有哪些行锁:select * from information_schema.innodb_trx
  • kill 行锁编号:手动释放行锁

手动事务示例:

package com.zhxd.test;
/*
 * author zhxd
 * ClassName Demo01
 */

import com.zhxd.utils.JDBCUtil;

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

public class Demo01 {
    public static void main(String[] args) {
        Connection connection = null;
        Statement statement1 = null;
        Statement statement2 = null;
        try {
            //1.获取Connection连接
            connection = JDBCUtil.getConnection();
            //2.开启事务
            connection.setAutoCommit(false);
            //3.获取SQL执行对象
            statement1 = connection.createStatement();
            statement2 = connection.createStatement();
            //4.定义SQL语句
            String sql1 = "update zhxd_student set name = 'lisi' where id = 1";
            String sql2 = "update zhxd_student set name = 'zhangsan' where id = 2";
            //5.执行SQL语句
            statement1.executeUpdate(sql1);
            statement2.executeUpdate(sql2);
            //6.手动抛出异常
            int a = 2 / 0;
            //7.提交事务
            connection.commit();
        } catch (Exception e) {
            try {
                connection.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            JDBCUtil.closeConnection(connection, statement1);
            JDBCUtil.closeConnection(null, statement2);
        }
    }
}

8.数据库连接池

  • 我们在JDBC编程中,每次创建和断开Connection对象都会消耗一定的时间和IO资源,如果需要频繁的与数据库打交道,该过程效率非常低。因为在Java程序与数据库之间建立连接时,数据库端要验证用户名和密码,并且要为这个连接分配资源,Java程序则要把代表连接的java.sql.Connection对象等加载到内存中,所以建立数据库连接的开销很大。
  • 为了避免频繁的创建数据库连接,与时我们可以通过数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用现有的数据库连接,而不是重新建立.
  • 数据库连接池大致实现原理:数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,当应用程序访问数据库时并不是直接创建Connection,而是向连接池“申请”一个Connection。如果连接池中有空闲的Connection,则将其返回,否则创建新的Connection。使用完毕后,连接池会将该Connection回收,并交付其他的线程复用使用,以减少创建和断开数据库连接的次数,提高数据库的访问效率。
    在这里插入图片描述

8.1 c3p0数据库连接池的使用

1.导入依赖的jar包
c3p0-0.9.5.2
mchange-commons-java-0.2.12.jar
mysql-connector-java-8.0.13.jar
2.c3p0相关类与方法

  • 创建连接池:new ComboPoolDataSource(["配置文件数据库名称"]) (参数可选)
  • 设置用户名称:pool.setUser("用户名")
  • 设置用户密码:pool.setPassword("密码")
  • 设置数据库连接的url:pool.setUrl("jdbc:mysql://127.0.0.1:3306/数据库名称")
  • 加载驱动:pool.setDriverClass("com.mysql.jdbc.Driver");
  • 获取连接对象:pool.getConnection()
package com.zhxd.jdbcpool;
/*
 * author zhxd
 * ClassName Test01
 */

import com.mchange.v2.c3p0.ComboPooledDataSource;

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

public class Test01 {
    public static void main(String[] args) {
        ResultSet resultSet = null;
        Connection connection = null;
        //创建c3p0数据库连接池
        ComboPooledDataSource pool = new ComboPooledDataSource();
        try {
            pool.setUser("root");//用户名
            pool.setPassword("root");//密码
            pool.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/zhxd?characterEncoding=gbk");//mysql数据库连接url
            pool.setDriverClass("com.mysql.jdbc.Driver");
            //获取连接对象
            connection = pool.getConnection();
            //编写sql语句
            String sql = "select * from zhxd_student where id=?";
            //获取预编译执行对象
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setLong(1, 1);
            //获取结果集
            resultSet = preparedStatement.executeQuery();
            while(resultSet.next()) {
                Long id = resultSet.getLong("id");
                String name = resultSet.getString("name");
                int age = resultSet.getInt("age");
                String address = resultSet.getString("address");
                System.out.println("id:" + id + " " + "name:" + name + " " + "age:" + age + " " + "address:" + address);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            //释放连接和结果
            try {
                if(resultSet!=null) resultSet.close();
                if(connection !=null) connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

连接池的连接对象.close()并不是关闭连接,而是释放连接对象归还连接池

使用配置文件对代码进行优化:

  • 在src目录下创建c3p0.properties或者c3p0-config.xml文件
  • 特别的文件要求,程序会自动寻找配置文件

c3p0-config.xml:

<c3p0-config>
    <!-- 使用默认的配置读取连接池对象 -->
    <default-config>
        <!--  连接参数 -->
        <!--需要修改自己数据库路径、用户账号、密码-->
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/zhxd?characterEncoding=gbk</property>
        <property name="user">root</property>
        <property name="password">root</property>
    </default-config>

    <named-config name="zhxd-otherc3p0">
        <!--  连接参数 -->
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/zhxd?characterEncoding=gbk</property>
        <property name="user">root</property>
        <property name="password">root</property>
    </named-config>
</c3p0-config>

修改Test测试程序
在这里插入图片描述

8.1.1 c3p0 核心配置文件说明

<!--初始化申请的连接数量-->
<property name="initiaPoolSize">5</property>
<!--最大别的连接数量-->
<property name="maxPoolSize">10</property>
<!--设置超时时间(单位毫秒)-->
<property name="checkoutTimeout">3000</property>

8.2 druid数据库连接池

  • Druid(德鲁伊):数据库连接池实现技术,由阿里巴巴提供,与c3p0数据库连接池底层实现原理一样
  • Druid使用:
  1. 导入druid的jar包依赖
  2. 定义配置文件:是properties形式的,可以叫任意名称,可以放在任意目录下,程序不会自动查找,因此要手动加载配置文件

druid.properties

#数据库驱动
driverClass=com.mysql.jdbc.Driver
#数据库连接的url
url=jdbc:mysql://127.0.0.1:3306/zhxd?characterEncoding=gbk
#用户登录名称和密码
username=root
password=root
#初始化连接池数量
initiaSize=5
#最大连接数量
maxActive=10
#最大等待时间
maxWait=3000
  1. 加载配置文件:Class对象.getClassLoader().getResourceAsStream(druid.properties)
  2. 数据库连接池对象:通过DruidDataSourceFactory.createDataSource(Properties properties)获取
  3. 获取连接:DruidDataSourceFactory对象.getConnection()

整合Druid数据库连接池:
DataSourceUtils.java(参考优化jdbc连接的方法)

package com.zhxd.utils;
/*
 * author zhxd
 * ClassName DataSourceUtils
 */

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class DataSourceUtils {
    //定义连接池对象
    private static DataSource dataSource = null;

    private DataSourceUtils() {}

    /*
    * 静态代码块加载配置文件
    * */

    static {
        try {
            Properties properties = new Properties();
            InputStream resourceAsStream = DataSourceUtils.class.getClassLoader().getResourceAsStream("druid.properties");
            properties.load(resourceAsStream);
            //获取数据库连接池
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 封装连接方法
    public static Connection getConnection() {
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            return connection;
        }
    }

    //封装释放连接方法
    /*
    * 分为执行DML和DQL语句 重载
    * */
    public static void closeConnection(Connection connection, Statement statement, ResultSet resultSet) {
        try {
            if(resultSet != null) resultSet.close();
            if(statement != null) statement.close();
            if(connection != null) connection.close();
        }catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void closeConnection(Connection connection, Statement statement) {
        closeConnection(connection, statement, null);
    }
}

测试druid数据库连接池:

package com.zhxd.jdbcpool;
/*
 * author zhxd
 * ClassName Test02
 */

import com.zhxd.utils.DataSourceUtils;

import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;

public class Test02 {
    public static void main(String[] args) {
        ResultSet resultSet = null;
        Connection connection = null;
        Statement statement = null;
        try {
            //获取连接对象
            connection = DataSourceUtils.getConnection();
            //编写sql语句
            String sql = "select * from zhxd_student where id=1";
            //获取预编译执行对象
            statement = connection.createStatement();
            //获取结果集
            resultSet = statement.executeQuery(sql);
            while(resultSet.next()) {
                Long id = resultSet.getLong("id");
                String name = resultSet.getString("name");
                int age = resultSet.getInt("age");
                String address = resultSet.getString("address");
                System.out.println("id:" + id + " " + "name:" + name + " " + "age:" + age + " " + "address:" + address);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            //释放连接和结果
            DataSourceUtils.closeConnection(connection, statement, resultSet);
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值