java-JDBC详解

JDBC

  • Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。我们通常说的JDBC是面向关系型数据库的。
  • 为了简化 开发人员的(对数据的统一)操作,提供了一个java操作数据库规范,对于开发人员来说,我们只需要掌握JDBC接口的操作即可;

创建第一个JDBC–基础版

1.准备数据库
在这里插入图片描述
在这里插入图片描述
2.导入驱动
在这里插入图片描述
3. 创建java

  1. 导入数据库驱动mysql-connector-java-8.0.21.jar
    注意:导入jar包后,需要add as library
  2. 加载驱动Class.forName
  3. 用户信息和url,username,password
  4. 连接成功,得到数据库对象Connection
  5. 获取执行sql对象 statement 用来执行sql
  6. 执行sql
  7. 获取结果集resultSet
  8. 释放连接
package com.jdbc;


import java.sql.*;

public class JdbcDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException, SQLException {
        //1.加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2. 用户信息和url
        /**
         * test 数据库名
         * useUnicode=true 支持中文
         * characterEncoding=utf-8 使用utf-8
         *useSSL=true 是否通过证书或者令牌进行安全验证
         * serverTimezone=Asia/Shanghai 设置时区
         */
        String url = "jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true";
        String user="root";
        String password="cqmcx";
        //3.获取连接 connection 相当于一个数据库对象
        Connection connection = DriverManager.getConnection(url, user, password);
        //4.获取执行sql对象 statement 用来执行sql
        Statement statement = connection.createStatement();
        //5.执行sql 可以现在数据库中写好sql
        String sql="select * from demo where name='cx'";
        //6.获取结果集
        /**
         * statement.executeQuery 执行查询
         * statement.executeUpdate 执行 增删改
         * statement.execute 怎删改查 都可以
         */
        ResultSet resultSet = statement.executeQuery(sql);
        //6.遍历结果
        while (resultSet.next()){
            //列名要与数据库中字段名一样
            System.out.println("id="+resultSet.getInt("id"));
            System.out.println("name="+resultSet.getString("name"));
        }

		 //7.释放连接
        resultSet.close();
        statement.close();
        connection.close();
    }
}

在这里插入图片描述

JDBC中对象详解

DriverManager

//2. 加载驱动
 DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
        //1.加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

1和2 两种方式都可以,推荐使用下面一种,因为Driver这个类:

// 静态代码块只在类加载的时候执行,且只执行一次
 static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }

不明白反射的可以去 反射机制

URL

  • mysql :3306
    协议://主机地址:端口号/数据库名?参数1&参数2&参数…
  • oralce:1521
    jdbc:oracle:thin:@主机地址:1521:sid

connection

//回滚事务
        connection.rollback();
        //提交事务
        connection.commit();
        //开启关闭事务的自动提交
        connection.setAutoCommit();
 //4.执行sql 可以现在数据库中写好sql
        String sql="update demo set name='cxcx' where id=1";
        try {
            //        关闭事务自动提交
            connection.setAutoCommit(false);
            int i = statement.executeUpdate(sql);//更新操作
            //提交事务
            connection.commit();
            int i2=10/0;//发生异常
            //开启事务自动提交
            connection.setAutoCommit(true);

        } catch (SQLException e) {
            connection.rollback();//发生异常回滚事务
            e.printStackTrace();
        } finally {
            statement.close();
            connection.close();
        }

在这里插入图片描述
事务已经提交了,提交了就不能回滚了

 //4.执行sql 可以现在数据库中写好sql
        String sql="update demo set name='cx' where id=1";
        try {
            //        关闭事务自动提交
            connection.setAutoCommit(false);
            int i = statement.executeUpdate(sql);//更新操作
            int i2=10/0;//发生异常
            //开启事务自动提交
            connection.setAutoCommit(true);
            //提交事务
            connection.commit();

        } catch (SQLException e) {
            connection.rollback();//发生异常回滚事务
            e.printStackTrace();
        } finally {
            statement.close();
            connection.close();
        }

在这里插入图片描述
因为是先发生了错误,此时数据还没有被提交,所以事务进行了回滚

Statement

Statement 会导致sql注入问题,一般使用PrepareStatement来执行sql对象

 /**
         * statement.executeQuery 执行查询
         * statement.executeUpdate 执行 增删改,返回的是受影响的行数
         * statement.execute 增删改查 都可以
         */

SQL注入问题

 //2.获取连接 connection 相当于一个数据库对象
        Connection connection = DriverManager.getConnection(url, user, password);
        //3.获取执行sql对象 statement 用来执行sql
        Statement statement = connection.createStatement();

        //实际情况中,是我们传入一个变量
        String name="'cdacdc' or 1=1";

        //4.执行sql 可以现在数据库中写好sql
        String sql="select * from demo where name="+name;


        //5.获取结果集
        ResultSet resultSet = statement.executeQuery(sql);
        //6.遍历结果
        while (resultSet.next()){
            //列名要与数据库中字段名一样
            System.out.println("id="+resultSet.getInt("id"));
            System.out.println("name="+resultSet.getString("name"));
        }

PreparedStatement (防止SQL注入)

//2.获取连接 connection 相当于一个数据库对象
        Connection connection = DriverManager.getConnection(url, user, password);

        //实际情况中,是我们传入一个变量
        String name="'cdacdc' or 1=1";

        //3.使用? 占位符代替参数
        String sql="select * from demo where name=?";

        //4.进行预编译
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        //手动给参数赋值
        preparedStatement.setString(1,name);



        //5.获取结果集
        ResultSet resultSet = preparedStatement.executeQuery(sql);

报错:

eption in thread "main" java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1
	

ResultSet

查询的结果集:封装了所有的查询结果

 resultSet.beforeFirst();//移动到最前面
        resultSet.afterLast();//移动到最后面
        resultSet.next();//移动到下一个数据
        resultSet.previous();//移动到前一行
        resultSet.absolute(row);//移动到指定行

        //如果知道列的类型就使用对应的类型获取
        resultSet.getString("列名");

创建第一个JDBC–工具类版

  • 上述代码我们看到了,有一些东西是在很多地方都是不变的,例如反射加载类模板,建立连接,释放连接等…,所以我们可以创建一个工具类,这个类提供一个获取连接的方法和释放连接的方法即可!

JDBCUtil.java

package com.jdbc.utils;

import java.sql.*;

public class JDBCUtil {
    static String url = "jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true";
    static String user="root";
    static String password="cqmcx";
    static {
        //1.加载驱动
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /*获取连接*/
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, user, password);
    }

    public static void colseConnection(Connection connection,Statement statement,ResultSet resultSet){
        if(resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

JdbcDemo.java

package com.jdbc;


import com.jdbc.utils.JDBCUtil;

import java.sql.*;

public class JdbcDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException, SQLException {
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
        try {
            connection = JDBCUtil.getConnection();
            String sql="select * from demo where name= ? ";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,"cxcx");
           resultSet = preparedStatement.executeQuery();
            while (resultSet.next()){
                //列名要与数据库中字段名一样
                System.out.println("id="+resultSet.getInt("id"));
                System.out.println("name="+resultSet.getString("name"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.colseConnection(connection,preparedStatement,resultSet);
        }
    }
}

注意:
sql.Date 数据库  java.sql.Date()
util.Date java  new java.sql.Date(new Date().getTime())

创建第一个JDBC–工具类版properties优化

在这里插入图片描述
在根目录下创建一个jdbc.properties文件

driver=com.mysql.cj.jdbc.Driver
url =jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true
user=root
password=cqmcx
package com.jdbc.utils;

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

public class JDBCUtil {
    static String driver = null;
    static String url = null;
    static String user=null;
    static String password=null;

    static {
        //1.加载驱动
        try {
            /*
            * 加载根目录下的资源文件
            * */
            InputStream resourceAsStream = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
            Properties properties = new Properties();
            properties.load(resourceAsStream);

            driver=properties.getProperty("driver");
            url=properties.getProperty("url");
            user=properties.getProperty("user");
            password=properties.getProperty("password");

            //加载驱动
            Class.forName(driver);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*获取连接*/
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, user, password);
    }

    public static void colseConnection(Connection connection,Statement statement,ResultSet resultSet){
        if(resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

数据库连接池

  • 由于java连接数据库,要经历连接-释放-连接-释放,这样十分耗费资源,所以我们有没有可能提前准备一些资源,等程序需要使用的时候就可以直接使用,用完之后放在此处等待其他程序使用,** 池化技术**就此诞生了!

DBCP

DBCP (Database Connection Pool)是一个依赖 Jakarta commons-pool 对象池机制的数据库连接池,Tomcat 的数据源使用的就是 DBCP。

在这里插入图片描述
在这里插入图片描述

  • jdbc_config.properties
#连接设置
#driverClassName 是dbcp设置好的名字
driverClassName=com.mysql.cj.jdbc.Driver
url =jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true
username=root
password=cqmcx

#<!-- 初始化连接 -->
initialSize=10

#最大连接数量
maxActive=50

#<!-- 最大空闲连接 -->
maxIdle=20

#<!-- 最小空闲连接 -->
minIdle=5

#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000
#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:【属性名=property;】
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=UTF8

#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true

#driver default 指定由连接池所创建的连接的只读(read-only)状态。
#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
defaultReadOnly=

#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED
  • JDBCUtil.java
package com.jdbc.utils;


import org.apache.commons.dbcp.BasicDataSourceFactory;

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

public class JDBCUtil {
    private static DataSource dataSource=null;
    static {
        //1.加载驱动
        try {
            /*
            * 加载根目录下的资源文件
            * */
            InputStream resourceAsStream = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc_config.properties");
            Properties properties = new Properties();
            properties.load(resourceAsStream);

            //创建数据源--工厂模式
            dataSource = BasicDataSourceFactory.createDataSource(properties);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*获取连接*/
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    public static void colseConnection(Connection connection,Statement statement,ResultSet resultSet){
        if(resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

C3P0

  • C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。使用它的开源项目有Hibernate、Spring等。

在这里插入图片描述
在这里插入图片描述

  • c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>

<c3p0-config>
    <!--
    c3p0的缺省(默认)配置
    如果在代码中"ComboPooledDataSource ds=new ComboPooledDataSource();"这样写就表示使用的是c3p0的缺省(默认)
    -->
    <default-config>
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&amp;characterEncoding=utf-8&amp;useSSL=true&amp;useUnicode=true</property>
        <property name="user">root</property>
        <property name="password">cqmcx</property>

        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </default-config>

    <!--
    c3p0的命名配置
    如果在代码中"ComboPooledDataSource ds=new ComboPooledDataSource("MySQL");"这样写就表示使用的是mysql的缺省(默认)
    -->
    <named-config name="MySQL">
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=true</property>
        <property name="user">root</property>
        <property name="password">cqmcx</property>

        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </named-config>

</c3p0-config>
  • JDBCUtil.java
package com.jdbc.utils;


import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;


import javax.activation.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JDBCUtil {
    private static ComboPooledDataSource dataSource=null;
    //2.private static ComboPooledDataSource dataSource=null;
    static {
   
        try {
            //2.代码版配置
//            dataSource= new ComboPooledDataSource();
//            dataSource.setDriverClass();
//            dataSource.setUser();
//            dataSource.setPassword();
//            dataSource.setJdbcUrl();


            //1.配置文件写法
            dataSource= new ComboPooledDataSource();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*获取连接*/
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    public static void colseConnection(Connection connection,Statement statement,ResultSet resultSet){
        if(resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

IDEA 连接数据库

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
按提示下载
在这里插入图片描述
在这里插入图片描述
成功连接!
在这里插入图片描述

=============================================================================
JDBC 推荐狂神说

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈行恩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值