JDBC详解

目录

一、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代码:


一、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、代码示例

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 注册给定驱动程序。 

在我们的程序中使用的

        //第二步:注册驱动;其实,在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”,即为:

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(查询)语句,返回结果集对象;

示例代码:

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:代表列的名称;

使用步骤:

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

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

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

代码示例:

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的参数使用?作为占位符,例如:

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、示例

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配置文件:

<?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代码:

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

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代码:

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

JdbcTemplate template = new JdbcTemplate(ds);

第三步:

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

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

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

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

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

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

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

 

3、代码演示:

druid.properties见上面;

java代码:

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("====================");
        }
    }
}

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值