首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >JDBC详解

JDBC详解

作者头像
訾博ZiBo
发布2025-01-06 14:21:48
发布2025-01-06 14:21:48
2810
举报

一、JDBC基本概念

1、概念

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

2、JDBC本质

官方(SUN公司)定义的一套操作数据库的规则,即接口。各个数据库厂商实现了这套接口,提供了数据库驱动jar包,我们呢可以使用这套(JDBC)接口进行编程,真正执行的代码是jar包中的实现类;

二、JDBC快速入门

1、步骤

第一步:导入驱动jar包;(将所用jar包复制到libs目录,然后右键选择Add As Library)

第二步:注册驱动;

第三步:获取数据库连接对象;

第四步:定义sql;

第五步:获取执行sql语句的对象——Statement;

第六步:执行sql;

第七步:处理结果;

第八步:释放资源;

2、代码示例

代码语言:javascript
复制
package mysql;


import com.mysql.jdbc.Driver;

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

public class Main {
    public static void main(String[] args) throws Exception {
        //第一步:导入驱动jar包;
        //第二步:注册驱动;其实,在mysql5之后,可以省略这句话,但不建议省略
        Class.forName("com.mysql.cj.jdbc.Driver");
        //第三步:获取数据库连接对象;
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/zibo?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC","root","root");
        //第四步:定义sql;
        String sql = "update stu set name = '二哥哥' where name = '二哥'";
        //第五步:获取执行sql语句的对象——Statement;
        Statement statement = connection.createStatement();
        //第六步:执行sql;
        long l = statement.executeLargeUpdate(sql);
        //第七步:处理结果;
        System.out.println(l);//1 执行成功了
        //第八步:释放资源;
        statement.close();
        connection.close();
    }
}

三、JDBC各个对象详解

1、DriverManager驱动管理对象

作用:

①注册驱动;

static void registerDriver(Driver driver)向DriverManager 注册给定驱动程序。

在我们的程序中使用的

代码语言:javascript
复制
        //第二步:注册驱动;其实,在mysql5之后,可以省略这句话,但不建议省略
        Class.forName("com.mysql.cj.jdbc.Driver");

实际上其内部静态代码块自动执行了registerDriver方法;

②获取数据库连接;

方法:

static Connection getConnection(String url, String user, String password)试图建立到给定数据库 URL 的连接。

参数说明:

url:指定连接数据库的路径;

语法:jdbc:mysql://ip地址(域名):端口号/数据库名称,后面要加上“?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC”,即为:

代码语言:javascript
复制
jdbc:mysql://ip地址(域名):端口号/数据库名称?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

可以简写,将ip地址(域名):端口号省略,因为默认是localhost:3306;

user:用户名;

password:密码;

2、Connection数据库连接对象

作用:

①获取执行sql的对象;

Statement createStatement()创建一个 Statement 对象来将 SQL 语句发送到数据库。

PreparedStatement prepareStatement(String sql)创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库。

②管理事务

开启事务:void setAutoCommit(boolean autoCommit)设置为false为开始事务;

提交事务:void commit();

回滚事务:void rollback()

3、Statement数据库语句执行对象

作用:

①执行sql

boolean execute(String sql):可以执行任意sql(了解即可);

int executeUpdate(String sql):执行DML(增删改)语句-常用、DDL(create、alter、drop)语句-不常用,返回值是影响的行数,可以通过行数判断是否执行成功,即大于0则成功;

ResultSet executeQuery(String sql):执行DQL(查询)语句,返回结果集对象;

示例代码:

代码语言:javascript
复制
package mysql;


import com.mysql.jdbc.Driver;

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

public class Main {
    public static void main(String[] args) throws Exception {
        //第一步:导入驱动jar包;
        //第二步:注册驱动;其实,在mysql5之后,可以省略这句话,但不建议省略
        Class.forName("com.mysql.cj.jdbc.Driver");
        //第三步:获取数据库连接对象;
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/zibo?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC","root","root");
        //第四步:定义sql;
        //添加一条数据
        String sql_add = "insert into stu(name,ranking,dep_id) values('訾博1',191,1)";
        //修改一条数据
        String sql_change = "update stu set name = '二哥' where name = '二哥哥'";
        //删除一条数据
        String sql_delete = "delete from stu where name = '二姐'";
        //第五步:获取执行sql语句的对象——Statement;
        Statement statement = connection.createStatement();
        //第六步:执行sql;
        long l1 = statement.executeLargeUpdate(sql_add);
        long l2 = statement.executeLargeUpdate(sql_change);
        long l3 = statement.executeLargeUpdate(sql_delete);
        //第七步:处理结果;
        if(l1>0){
            System.out.println("添加成功!");
        }else {
            System.out.println("添加失败!");
        }
        if(l2>0){
            System.out.println("修改成功!");
        }else {
            System.out.println("修改失败!");
        }
        if(l3>0){
            System.out.println("删除成功!");
        }else {
            System.out.println("删除失败!");
        }
        //第八步:释放资源;
        statement.close();
        connection.close();
    }
}

4、ResultSet结果集对象

方法:

boolean next():将光标从当前位置向下移一个位置(并不是一次移动一行,而是一列(当前行的一列))。

getXxx():获取数据,Xxx代表数据类型;

getXxx()参数:

int:代表列的编号;

String:代表列的名称;

使用步骤:

第一步:游标向下移动一行;

第二步:判断是否有数据;

第三步:如果有,则获取数据,否则结束;

代码示例:

代码语言:javascript
复制
package mysql;


import com.mysql.jdbc.Driver;

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

public class Main {
    public static void main(String[] args) throws Exception {
        //第一步:导入驱动jar包;
        //第二步:注册驱动;其实,在mysql5之后,可以省略这句话,但不建议省略
        Class.forName("com.mysql.cj.jdbc.Driver");
        //第三步:获取数据库连接对象;
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/zibo?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC","root","root");
        //第四步:定义sql;
        String sql = "select * from stu";
        //第五步:获取执行sql语句的对象——Statement;
        Statement statement = connection.createStatement();
        //第六步:执行sql;
        ResultSet set = statement.executeQuery(sql);
        //第七步:处理结果;
        while (true){
            boolean yes = set.next();
            if(!yes){
                break;
            }else {
                System.out.println("id:"+set.getInt("id"));
                System.out.println("姓名:"+set.getString("name"));
                System.out.println("排名:"+set.getInt("ranking"));
                System.out.println("信息id:"+set.getInt("dep_id"));
                System.out.println("------------------------------");
            }
        }
        //第八步:释放资源;
        statement.close();
        connection.close();
    }
}

5、PreparedStatement执行sql的对象

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

当随便输入用户名,输入这个密码:a' or 'a' = 'a;

最终拼接成的sql语句是:select * from stu where username = 'fsagfsdgsjsd' and password = 'a' or 'a' = 'a'

发现由于or,这个sql语句的结果永远为True,那么数据库则会登录成功!多么危险!

解决SQL注入问题:使用PreparedStatement对象解决

预编译的SQL:参数使用?作为占位符;

步骤:

第一步:导入驱动jar包;(将所用jar包复制到libs目录,然后右键选择Add As Library)

第二步:注册驱动;

第三步:获取数据库连接对象;

第四步:定义sql;

SQL的参数使用?作为占位符,例如:

代码语言:javascript
复制
select * from user where username = ? and password = ?;

第五步:获取执行sql语句的对象——PreparedStatement,connection.prepareStatement(String sql)将sql语句传入;

第六步:给占位符?赋值;

方法:setXxx(参数1,参数2),参数1是第i个?代表的数据的索引,参数2是第i个?代表的数据的值,以此类推;

第七步:执行sql,这里就不需要传递sql语句了,前面已经传了,并处理结果;

第八步:释放资源;

四、JDBC事务管理

1、使用Connection管理事务

开启事务:void setAutoCommit(boolean autoCommit)设置为false为开始事务;

提交事务:void commit();

回滚事务:void rollback()

2、示例

代码语言:javascript
复制
package mysql;


import com.mysql.jdbc.Driver;

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

public class Main {
    public static void main(String[] args) throws Exception {
        //第一步:导入驱动jar包;
        //第二步:注册驱动;其实,在mysql5之后,可以省略这句话,但不建议省略
        Class.forName("com.mysql.cj.jdbc.Driver");
        //第三步:获取数据库连接对象;
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/zibo?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC","root","root");
        try {
            //第四步:定义sql;
            String name = "name";
            String sql = "update stu set name = '四哥',ranking = 100 where name = '大神'";
            //第五步:获取执行sql语句的对象——Statement;
            Statement statement = connection.createStatement();
            //执行sql之前开启事务
            connection.setAutoCommit(false);
            //第六步:执行sql;
            int i = statement.executeUpdate(sql);
            //第七步:处理结果;
            System.out.println(i);
            //提交事务
            connection.commit();
            //第八步:释放资源;
            statement.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
            //一旦出现任何异常都进行回滚操作
            if (connection!=null){
                connection.rollback();
            }
        }
    }
}

五、数据库连接池

1、概述

本质上与线程池一样,这里不再做过多叙述;

2、实现

标准接口:

DataSource;

获取连接:

getConnection();

归还连接:

如果连接是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接,而是归还连接;

备注:

我们呢一般不去实现这个接口,由数据库厂商实现;

一些实现:

C3P0:数据库连接池技术;

Druid:数据库连接池实现技术,由阿里巴巴提供;

3、C3P0

①使用步骤:

第一步:

导入jar包(c3p0-0.9.2.1.jar和mchange-commons-java-0.2.3.4.jar);

第二步:

定义配置文件(自动加载):

名称是c3p0.properties或者c3p0-config.xml;

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

第三步:

创建核心对象,数据库连接池对象,ComboPooledDataSource

第四步:

获取连接,getConnection

②简单使用示例:

xml配置文件:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <!-- 默认配置,如果没有指定则使用这个配置 -->
    <default-config>
        <property name="user">root</property>
        <property name="password">root</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/zibo?useUnicode=true;useJDBCCompliantTimezoneShift=true;useLegacyDatetimeCode=false;serverTimezone=UTC</property>
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="checkoutTimeout">30000</property>
        <property name="idleConnectionTestPeriod">30</property>
        <property name="initialPoolSize">3</property>
        <property name="maxIdleTime">30</property>
        <property name="maxPoolSize">100</property>
        <property name="minPoolSize">2</property>
        <property name="maxStatements">200</property>
    </default-config>
    <!-- 命名的配置,可以通过方法调用实现 -->
    <named-config name="mysql">
        <property name="user">root</property>
        <property name="password">root</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/zibo?useUnicode=true;useJDBCCompliantTimezoneShift=true;useLegacyDatetimeCode=false;serverTimezone=UTC</property>
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <!-- 如果池中数据连接不够时一次增长多少个 -->
        <property name="acquireIncrement">5</property>
        <!-- 初始化数据库连接池时连接的数量 -->
        <property name="initialPoolSize">20</property>
        <!-- 数据库连接池中的最大的数据库连接数 -->
        <property name="maxPoolSize">25</property>
        <!-- 数据库连接池中的最小的数据库连接数 -->
        <property name="minPoolSize">5</property>
    </named-config>
</c3p0-config>

Java代码:

代码语言:javascript
复制
package mysql;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class TestMySql {
    public static void main(String[] args) throws SQLException {
        //获取DataSource,使用默认配置(一般情况使用默认配置即可,使用其他配置,只需要将名字作为参数传入)
        DataSource ds = new ComboPooledDataSource();
        //获取连接
        Connection connection = ds.getConnection();
        System.out.println(connection);
    }
}

4、druid

使用步骤:

第一步:

导包druid-1.1.9.jar;

第二步:

定义配置文件(手动加载):

说明:

是properties形式的,可以取任意名称、放在任意位置;

第三步:

获取数据库连接池——通过工厂类获取DruidDataSourceFactory

第四步:

获取连接;

代码示例:

druid.properties

代码语言:javascript
复制
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/zibo?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
username=root
password=root
# 初始化连接数量
initialSize=5
# 最大连接数
maxActive=10
# 最大等待时间
maxWait=3000

java代码:

代码语言:javascript
复制
package mysql;

import com.alibaba.druid.pool.DruidDataSourceFactory;

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

public class TestMySql {
    public static void main(String[] args) throws Exception {
        //第一步:导包druid-1.1.9.jar;
        //第二步:定义配置文件(手动加载):
        //第三步:获取数据库连接池——通过工厂类获取DruidDataSourceFactory
        //先加载配置文件
        Properties pro = new Properties();
        InputStream resourceAsStream = TestMySql.class.getClassLoader().getResourceAsStream("druid.properties");
        assert resourceAsStream != null;
        pro.load(resourceAsStream);
        DataSource dataSource = DruidDataSourceFactory.createDataSource(pro);
        //第四步:获取连接;
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
    }
}

六、JDBCTemplate

1、介绍

是Spring框架对JDBC的简单封装;

提供了JDBCTemplate简化了JDBC的开发;

好处:

不需要我们管理连接了。

不需要我们设置参数了。

查询时候可以直接返回对应的实体类。

2、使用步骤

第一步:

导入Jar包;

第二步:

创建JDBCTemplate对象,依赖于数据源DataSource

代码语言:javascript
复制
JdbcTemplate template = new JdbcTemplate(ds);
第三步:

调用JdbcTemplate的方法来完成CRUD的操作

execute:没有返回值,可以执行所有的SQL语句,一般用于执行DDL语句。

update():执行DML语句,增、删、改语句;

queryForMap():查询结果将结果集封装为map集合;

queryForList():查询结果将结果集封装为list集合;

query():查询结果,将结果封装为JavaBean对象;

queryForObject():查询结果,将结果封装为对象;

3、代码演示:

druid.properties见上面;
java代码:
代码语言:javascript
复制
package mysql;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Properties;

public class Test2 {
    public static void main(String[] args) throws Exception {
        //1、导包
        //2、创建JDBCTemplate对象,依赖于数据源DataSource
        //从配置文件加载数据源
        Properties pro = new Properties();
        InputStream resourceAsStream = TestMySql.class.getClassLoader().getResourceAsStream("druid.properties");
        assert resourceAsStream != null;
        pro.load(resourceAsStream);
        DataSource dataSource = DruidDataSourceFactory.createDataSource(pro);
        //创建JDBCTemplate对象
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        String sql = "select * from stu";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
        for (Map<String, Object> map : list) {
            for (String s : map.keySet()) {
                System.out.println(map.get(s));
            }
            System.out.println("====================");
        }
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、JDBC基本概念
    • 1、概念
    • 2、JDBC本质
  • 二、JDBC快速入门
    • 1、步骤
    • 2、代码示例
  • 三、JDBC各个对象详解
    • 1、DriverManager驱动管理对象
      • 作用:
    • 2、Connection数据库连接对象
      • 作用:
    • 3、Statement数据库语句执行对象
      • 作用:
    • 4、ResultSet结果集对象
      • 方法:
    • 5、PreparedStatement执行sql的对象
      • ①SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串拼接,会造成安全性问题;
  • 四、JDBC事务管理
    • 1、使用Connection管理事务
    • 2、示例
  • 五、数据库连接池
    • 1、概述
    • 2、实现
      • 标准接口:
      • 获取连接:
      • 归还连接:
      • 备注:
      • 一些实现:
    • 3、C3P0
      • ①使用步骤:
      • ②简单使用示例:
    • 4、druid
      • 使用步骤:
      • 代码示例:
  • 六、JDBCTemplate
    • 1、介绍
    • 2、使用步骤
      • 第一步:
      • 第二步:
      • 第三步:
    • 3、代码演示:
      • druid.properties见上面;
      • java代码:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档