AI智能
改变未来

# JDBC,数据库连接池 C3P0和Druid


JDBC

1.概念

​ Java DataBase Connectivity Java 数据库连接,Java语言操作数据库

​ JDBC 本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库jar包。我们可以使用这套接口(JDBC)去编程,真正执行的代码是驱动包Jar包中的实现类。

2.快速入门

  • 1,导入驱动jar包
  • 2,注册驱动
  • 3,获取数据库连接对象 Connection
  • 4,定义sql
  • 5,获取执行sql语句的对象Statement
  • 6,执行sql,接收返回结果
  • 7,处理结果
  • 8,释放资源

**executeQuery:**用于产生单个结果集(ResultSet)的语句,例如:被执行最多的SELECT 语句。
**executeUpdate :**用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQL DDL(数据定义语言)语句,例如 CREATE TABLE 和 DROP TABLE。
**execute:**可用于执行任何SQL语句,返回一个boolean值,表明执行该SQL语句是否返回了ResultSet。
如果执行后第一个结果是ResultSet,则返回true,否则返回false。

3.详解各个对象

1.DriverManger:驱动管理对象

功能:

#注册驱动:告诉程序员该使用哪一个数据库的驱动jar

​ static void registerDriver(Driver driver) :注册与给定的驱动程序 DriverManger。

写代码使用发现:在com.mysql.cj.jdbc.Driver类中存在静态代码块

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

注意:mysql5之后的驱动jar包可以省略注册驱动的步骤

#获取数据库连接:

方法:static Connection getConnection(String url , String user , String Passsword)

参数::

url:指定的连接路径。

​ 指定语法:jdbc:mysql://ip地址(域名):端口号/数据库名称。

例子:jdbc:mysql://localhost:3306/db

user:用户名

​ password:密码

2.Connection:数据库连接对象

功能:

#获取执行sql的对象

*Statement createStatement()

*PreparedStatement prepareStatement(String sql)

#管理事务

*开启事务 setAutoCommit(boolean autoComment ): 调用该方法设置参数值为false,即为开启事务

*提交事务:commit()

*回滚事务:rollback()

3.Statement:执行sql对象

功能:

#执行sql

*boolen execute(String sql): 可以执行任意sql。

*int executeUpdate:执行DML(instert,update,delete)语句,DDL(CREATE,ALTER,DROP)语句.

​ 返回值是:影响的行数。可以通过影响的行数,判断dml语法是否执行成功!(如果返回值大于0则代表成功,反之不成功!)

*ResultSet executeQuery(String sql) :执行dql语句(select)语句 返回一个结果集。

4.ResultSet:结果集对象(封装结果集对象)

功能

#netx(); 游标向下移动 判断当前行是否是最后一行末尾(是否有数据),如果是则返回false,如果不是则返回true。

#getXXX(); xxx代表数据类型,如 int getInt(), String getString(),

参数:getString(1) 1代表列的编号,从1开始

​ getString(“列名”)代表列的名称

注意:

使用步骤:1游标向下移动一行.2判断是否有数据.3.获取数据.

5.PreparedStatement:执行sql兑现

#SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题。

解决sql注入问题:使用PreparedStatement对象来解决。

表示预编译的sql:参数使用?作为占位符号,在执行sql时赋值。

步骤:

  • 1,导入驱动jar包
  • 2,注册驱动
  • 3,获取数据库连接对象 Connection
  • 4,定义sql
  • *注意:sql的阐述使用?作为占位符。 如:select * from user where username = ? and password= ?
  • 5,获取执行sql语句的对象 PreparedStatement Connection.prepareStatement(String sql)
  • 6,给占位符?赋值
  • 方法: setXxx(参数1,参数2,)
  • 参数1:?的位置。
  • 参数2:?的值。
  • 7,执行sql,接收返回结果,不需要传递sql语句了
  • 9,处理结果
  • 10,释放资源

*注意:后期都会使用PreparedStatement来完成增删改查的所有操作

1:可以防止sql注入。

2:效率更高。

&抽取JDBC工具类&

*目的:简化书写

*分析:

1,注册驱动也抽取。

2.抽取一个方法获取连接对象。

​ *不想传递参数(麻烦),还得保证工具类的通用性

​ 解决方案:配置文件。

​ jdbc.properties

​ url =

user =

​ password =

读取资源文件

//读取资源文件,获取值//Properties//1,创建Properties类Properties pro = new Properties();//2.加载文件//获取src路径下的路径文件的方式 ClassLoader 类加载器pro.load(new FileReader(\"E:\\\\IdeaProjects\\\\javaweb\\\\jdbc\\\\src\\\\main\\\\resources\\\\jdbc.properties\"));//3获取属性赋值

3.抽取一个方法释放资源。

4.JDBC事务

1,事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。

2,操作:

*,开启事务

​ &在执行sql之前开启事务

*,提交事务

​ &当所有sql都执行完提交事务

*,回滚事务

​ &在catch中回滚事务

3,使用Connection对象来管理事务

*开启事务 setAutoCommit(boolean autoComment ): 调用该方法设置参数值为false,即为开启事务

*提交事务:commit()

*回滚事务:rollback()

例子:

public class JDBCDemo3 {public static void main(String[] args) {Connection conn = null;PreparedStatement pstmt1 = null;PreparedStatement pstmt2 = null;try {//1,获取连接conn = JdbcUtils.getConnection();//开启事务conn.setAutoCommit(false);//定义sql//1,B-500String sql1 = \"update account set money = money - ? where id = ?\";//2,A+500String sql2 = \"update account set money = money + ? where id = ?\";//3获取sql执行对象pstmt1 = conn.prepareStatement(sql1);pstmt2 = conn.prepareStatement(sql2);//执行sqlpstmt1.setFloat(1, 500);pstmt1.setInt(2, 2);pstmt2.setFloat(1, 500);pstmt2.setInt(2, 1);pstmt1.executeUpdate();int i = 1/0;pstmt2.executeUpdate();//提交事务conn.commit();} catch (Exception e) {//事务的回滚try {if (conn != null) {conn.rollback();}} catch (SQLException ex) {ex.printStackTrace();}e.printStackTrace();} finally {JdbcUtils.close(pstmt1, conn);JdbcUtils.close(pstmt2, null);}}}

5,数据库连接池

**概念:**其实就是一个容器(集合)存放数据库连接的容器。

*当系统初始化好后,容器被创建,容器会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完后,会将对象归还给容器。

好处:

​ 1,节约资源。

​ 2,用户访问高效。

实现

1,标准接口:DataSource javax.sql包下

​ 方法:

  • 获取连接:getConnection()
  • 归还连接:如果连接对象Connection是从连接池获取的,那么调用Connection.close()方法,则不会再关闭连接了,而是归还连接。

2,一般我们不去实现它,由数据库厂商来实现。

*  C3P0:数据库连接池技术。*  Druid:数据库连接池实现技术(由阿里巴巴提供)。

#C3P0:

  • 步骤:

    1,导入jar包,cap0-0.9.5.2.jar mchange-commons-java-0.2.12.jar

    2,定义配置文件,

    ​ 名称:cap0.properties 或者 c3p0-config.xml。

    <c3p0-config><!--使用默认的配置读取数据库连接池对象 --><default-config><!--  连接参数 --><property name=\"driverClass\">com.mysql.cj.jdbc.Driver</property><property name=\"jdbcUrl\">jdbc:mysql://localhost:3306/jdbc</property><property name=\"user\">root</property><property name=\"password\">123456</property><!-- 连接池参数 --><!--初始化申请的连接数量--><property name=\"initialPoolSize\">5</property><!--最大的连接数量--><property name=\"maxPoolSize\">10</property><!--超时时间--><property name=\"checkoutTimeout\">3000</property></default-config></c3p0-config>

    ​ 路径:直接将文件放在src目录下即可。

    3,创建核心对象,数据库连接池对象 comboPooledDataSource.

    4,获取连接:getConnection.

    例子:

    public class C3P0Demo1 {public static void main(String[] args) throws SQLException {//1,创建数据池连接对象DataSource ds = new ComboPooledDataSource();//2获取连接对象Connection conn = ds.getConnection();//3.打印System.out.println(conn);}}

#Druid:

步骤:

1,导入jar包

2,定义配置文件

​ *特点:

​ 1是properties形式的.

​ 2是可以叫任意名称,可以放在任意目录下

配置文件示例;

driverClassName=com.mysql.cj.jdbc.Driverurl=jdbc:mysql://localhost:3306/jdbcusername=rootpassword=123456#初始化连接数量initialSize=5#最大连接数量maxActive=10#最大等待时间maxWait=3000

3,加载配置文件 Properties pro = new Properties();

4,获取数据库连接池对象:

​ 通过工厂类来获取 DruidDateSourceFactory

5,获取连接:getconnection

​ 例子:

public class DruidDemo {public static void main(String[] args) throws Exception {//1,导入jar包//2,定义配置文件//3,加载配置文件Properties pro = new Properties();//加载配置文件InputStream is =         DruidDemo.class.getClassLoader().getResourceAsStream(\"druid.properties\");pro.load(is);//4,获取连接池对象DataSource ds = DruidDataSourceFactory.createDataSource(pro);//5,获取连接Connection connection = ds.getConnection();System.out.println(connection);}}

定义工具类

1定义一个JdbcUtils

2提供静态代码块加载配置文件

3提供方法

​ #获取连接方法:通过数据库连接池来获取连接

​ #释放资源

​ #提供连接数据库连接池的方法

连接池工具类

/*** Druid连接池工具类*/public class JdbcUtils {private static DataSource ds;static {Properties pro = new Properties();try {pro.load(JdbcUtils.class.getClassLoader().getResourceAsStream(\"druid.properties\"));//获取DateSourceds = DruidDataSourceFactory.createDataSource(pro);} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}/*** 获取连接的方法*/public static Connection getConnection() throws SQLException {return ds.getConnection();}/*** 释放资源*/public static void close(Statement stmt, Connection conn) {if (stmt != null) {try {stmt.close();} catch (SQLException e) {e.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}/*** 释放资源重载*/public static void close(ResultSet rs, Statement stmt, Connection conn) {if (rs != null) {try {rs.close();} catch (SQLException e) {e.printStackTrace();}}if (stmt != null) {try {stmt.close();} catch (SQLException e) {e.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}/*** 获取连接池方法*/public static DataSource getDataSource(){return ds;}}

测试连接池工具类

/*** 测试新工具类*/public class DruidDemo2 {public static void main(String[] args) {/*** 完成添加操作*///1获取连接PreparedStatement pstmt = null;Connection conn = null;try {conn = JdbcUtils.getConnection();//定义sqlString sql = \"insert into account values(null, ?, ?)\";//获取pstmr对象pstmt = conn.prepareStatement(sql);//给?赋值pstmt.setString(1, \"D\");pstmt.setFloat(2, 5000);//执行sqlint i = pstmt.executeUpdate();System.out.println(i);} catch (SQLException e) {e.printStackTrace();} finally {//释放资源JdbcUtils.close(pstmt,conn);}}}
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » # JDBC,数据库连接池 C3P0和Druid