JDBC基础

1.JDBC的概念
JDBC(Java DataBase Connectivity,Java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成,所以JDBC本质就是一些操作数据库的jar包。

2.JDBC的作用
JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序,JDBC是Java程序操作数据库必要的接口,并且是持久层框架如Mybatis的基础,只有理解和熟练使用JDBC才能对框架的理解更加深入,知其然更知其所以然。总而言之,要使用Java操作数据库就要使用JDBC。

3.Connection,Statement,ResultSet的基本使用
JDBC的使用过程大概为:首先用加载对应的数据库驱动类到JVM中,然后使用数据库用户名和密码创建数据库连接,产生连接对象Connection,通过Connection对象可以得到SQL执行对象Statement,最后书写SQL语句然后用Statement对象执行SQL,如果是查询语句的话,用ResultSet对象来接受返回值。

所有的常量都是使用properties文件或者xml文件进行配置的,当然也可以用手动set,传参啥的,但是不建议。

示例代码:

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

//使用基本的Statement进行数据库操作
public class JDBCDemo1 {

    public static void main(String[] args) {

        //定义一个properties对象来读取配置文件
        Properties prop = new Properties( );
        //定义一个数据库连接对象的引用
        Connection conn = null;
        //定义一个SQL执行对象的引用
        Statement stat = null;
        //定义一个结果集对象的引用
        ResultSet rs = null;

        String selectSql = "SELECT * FROM USER";
        String addSql = "insert into USER values( '3','手冢国光', '1993.1.2')";

        try {
            //加载配置文件
            prop.load(JDBCDemo1.class.getResourceAsStream("jdbc"));
            //将数据库驱动类对象加载到JVM中
            Class.forName(prop.getProperty("driverClassName"));
            //使用API获得对数据库的connection
            conn = DriverManager.getConnection(prop.getProperty("url"), prop.getProperty("username"), prop.getProperty("password"));
            //通过连接对象生成一个执行SQL的statement对象
            stat = conn.createStatement();

            //测试JDBC的查询功能,用结果集对象来存取从数据库中查到的数据
            rs = stat.executeQuery(selectSql);
            //结果集的遍历
            while(rs.next()) {
                //ResultSet有很多API可供使用
                //根据列的序号获取列的值(1是第一列)
                System.out.print(rs.getString(1) + " ");
                //通过列名获得列的值
                System.out.println(rs.getString("name"));
            }

            //测试JDBC的插入功能(删除,更新和插入是一样的,只是SQL不同)
            int count = stat.executeUpdate(addSql);
            System.out.println("success insert " + count + " line");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try{
                if(rs != null){
                    rs.close();
                }
                if(stat != null){
                    stat.close();
                }
                if(conn != null){
                    conn.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
        }
    }

}

使用了Properties文件

//数据库驱动类,使用的封装好的JDBC jar包
driverClassName = com.mysql.cj.jdbc.Driver
//使用jdbc方式连接MySQL数据库放在localhost端口号3306数据库名test,设置时间格式和编码格式
url = jdbc:mysql://localhost:3306/user?serverTimezone=UTC&characterEncoding=utf-8
//数据库的登录名
username = root
//数据库的登录密码
password = zhejiushimima

使用的最新的MySQL驱动,所以驱动类是com.mysql.cj.jdbc.Driver,不是com.mysql.jdbc.Driver,并且需要指定serverTimezone的值,可以选择不同的时区,这里就设置为serverTimezone=UTC

4.PrepareStatement的基本使用
Statement是最原始的SQL执行对象,存在很多问题,比如SQL注入,效率低等,所以开发中一律使用PrepareStatement。
PrepareStatement和Statement使用基本相同,只是产生PrepareStatement对象的时候,采用的是预编译,所以要提供缺失参数的SQL(用?占位符),然后在将参数set就行,最后示例代码中涉及到批处理的基本操作。
示例代码:

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

//使用PrepareStatement进行预编译和批处理,更加安全高效
public class JDBCDemo2 {

    public static void main(String[] args) {

        //定义一个properties对象来读取配置文件
        Properties prop = new Properties();
        //定义一个数据库连接对象的引用
        Connection conn = null;
        //定义一个SQL执行对象的引用
        PreparedStatement prep = null;
        //定义一个结果集对象的引用
        ResultSet rs = null;
        //String selectSql = "SELECT * FROM USER WHERE NAME = ?";
        String addSql = "insert into user values(?,?,?)";

        try {
            //加载配置文件
            prop.load(JDBCDemo2.class.getResourceAsStream("jdbc"));
            //将数据库驱动类对象加载到JVM中
            Class.forName(prop.getProperty("driverClassName"));
            //使用API获得对数据库的connection
            conn = DriverManager.getConnection(prop.getProperty("url"), prop.getProperty("username"), prop.getProperty("password"));

            //通过预编译SQL来生成一个prepareStatement对象
            prep = conn.prepareStatement(addSql);
            //向预编译的SQL中填入参数
            prep.setString(1, "10");
            prep.setString(2,"真田弦一郎");
            prep.setDate(3, new Date(new java.util.Date().getTime()));

            //批处理实例,但是只能用于更新的语句,不能用于查询的语句
            //prep.addBatch();
            //prep.executeBatch();

            //这里直接执行预编译好的sql就好了
            rs = prep.executeQuery();

            //结果集的遍历
            while (rs.next()) {
                //ResultSet有很多API可供使用
                //根据列的序号获取列的值(1是第一列)
                System.out.print(rs.getString(1) + " ");
                //通过列名获得列的值
                System.out.println(rs.getString("name"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

同样使用了前面的properties文件

预编译解决了很多问题,但是在高频率访问的情形下,服务器可能还是不堪重负,原因在于和数据库频繁的建立和断开连接,是很耗时的,这时候就需要数据库连接池来解决问题。
数据库连接池基本思想是当服务器启动之时,就直接建立与数据库的数个连接,然后当一个请求到达的时候,将一个可用连接分配给对应的请求,然后使用完毕在归还给连接池,并不进行实际的关闭,这样就解决了频繁建立和断开连接的问题。

5.DBCP数据库连接池基本使用
DBCP(DataBase Connection Pool)数据库连接池,是java数据库连接池的一种,由Apache开发,通过数据库连接池,可以让程序自动管理数据库连接的释放和断开。

数据库连接池这里的主要涉及到的是启动配置。

DBCP的配置采用的properties文件:

//数据库驱动类,使用的封装好的JDBC jar包
driverClassName = com.mysql.cj.jdbc.Driver
//使用jdbc方式连接MySQL数据库放在localhost端口号3306数据库名test,设置时间格式和编码格式
url = jdbc:mysql://localhost:3306/user?serverTimezone=UTC&characterEncoding=utf-8
//数据库的登录名
username = root
//数据库的登录密码
password = zhejiushimima
//连接池启动时创建的连接数(默认为0)
initalSize = 10
//连接池中可同时连接的最大连接数(默认为8)
maxActive = 5
//连接池中允许的最大空闲数(默认是8,负数表示不受限制)
maxIdle = 5
//连接池中允许的最小空闲连接数
minIdle = 3
//如果连接不够用的时候,等待的最长时间(默认是无限,建议调整为一个定值,防止饿死)
maxWait = 60000

示例代码:

public class JDBCDemo3 {

    public static void main(String[] args){
        Properties prop = new Properties();
        ResultSet rs = null;
        try {
            //加载配置文件
            prop.load(JDBCDemo3.class.getResourceAsStream("dbcp"));
            //根据配置文件来构造数据库连接池
            DataSource ds = BasicDataSourceFactory.createDataSource(prop);
            //从连接池中取连接
            Connection conn = ds.getConnection();
            
            //测试
            PreparedStatement prep = conn.prepareStatement("SELECT * from USER ");
            rs = prep.executeQuery();
            while(rs.next()){
                System.out.println(rs.getString(2));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

6.C3P0数据库连接池基本使用
C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等,比DBCP好一些,支持自动关闭连接。

使用类似,C3P0的配置有三种方法,一种是使用set方法手动配置,一种是使用properties文件,最后是使用xml文件,这里是使用xml文件配置,这些配置文件都可以去官网copy,意义也基本都很好理解。

xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <default-config>
        <property name="automaticTestTable">con_test</property>
        <property name="checkoutTimeout">30000</property>
        <property name="idleConnectionTestPeriod">30</property>
        <property name="initialPoolSize">10</property>
        <property name="maxIdleTime">30</property>
        <property name="maxPoolSize">100</property>
        <property name="minPoolSize">10</property>
        <property name="maxStatements">200</property>

        <!-- MySQL的配置 -->
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/user?serverTimezone=UTC&amp;characterEncoding=utf-8</property>
        <property name="user">root</property>
        <property name="password">zhejiushimiam</property>

        <user-overrides user="test-user">
            <property name="maxPoolSize">10</property>
            <property name="minPoolSize">1</property>
            <property name="maxStatements">0</property>
        </user-overrides>

    </default-config>

    <!-- This app is massive! -->
    <named-config name="intergalactoApp">
        <property name="acquireIncrement">50</property>
        <property name="initialPoolSize">100</property>
        <property name="minPoolSize">50</property>
        <property name="maxPoolSize">1000</property>

        <!-- intergalactoApp adopts a different approach to configuring statement caching -->
        <property name="maxStatements">0</property>
        <property name="maxStatementsPerConnection">5</property>

        <!-- he's important, but there's only one of him -->
        <user-overrides user="master-of-the-universe">
            <property name="acquireIncrement">1</property>
            <property name="initialPoolSize">1</property>
            <property name="minPoolSize">1</property>
            <property name="maxPoolSize">5</property>
            <property name="maxStatementsPerConnection">50</property>
        </user-overrides>
    </named-config>
</c3p0-config>

示例代码:

public class JDBCDemo4 {

    public static void main(String[] args){

        //手动指定xml配置文件的路径,如果不手动指定,默认是加载ClasPath下面的c3p0-config.xml文件,所以要放在src根目录下
        System.setProperty("com.mchange.v2.c3p0.cfg.xml", System.getProperty("user.dir")+"/servletWeb/src/c3p0-config.xml");
        try {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            Connection conn = ds.getConnection();
            
            //测试,有了配置文件,就很轻松了
            PreparedStatement prep = conn.prepareStatement("SELECT * FROM USER");
            ResultSet rs = prep.executeQuery( );
            while(rs.next()){
                System.out.println(rs.getString(2));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

7.数据库事务
除了以上的基本使用还有就是JDBC支持数据库的事务设置,可以设置事务手动提交,以便回滚,也可以设置数据库事务隔离级别等等。

所有的jar包都去官网下载二进制zip文件,然后解压之后就可以引入使用了。
数据库是MySQL数据库
数据库驱动jar包是mysql-connector-java-8.0.11.jar.
DBCP需要三个jar包:
commons-dbcp2-2.3.0.jar
commons-logging-1.2.jar
commons-pool2-2.5.0.jar
C3P0需要两个个jar包:
c3p0-0.9.5.2.jar
mchange-commons-java-0.2.11.jar

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值