JDBC学习笔记

JDBC技术

JDBC概述

  • JDBC:Java Database Connectivity ,是sun公司为了简化和统一java连接数据库定义的一套规范

JDBC和数据库驱动的关系

  • 接口(JDBC)和实现(驱动jar)的关系

JDBC开发基本步骤

  1. 注册驱动
  2. 获得连接
  3. 获取执行sql语句的对象
  4. 执行sql语句
  5. 处理结果
  6. 释放资源
Class.forName("驱动的路径");
DriverManager.getConnection("数据库路径","数据库用户名","数据库密码");
statement : 执行SQL语句的对象
Connection:连接数据库的对象
ResultSet:结果集对象,作用:保存查询后的结果集
Close:释放资源
package top.simba1949.jdbc;

import com.mysql.jdbc.Driver;
import org.junit.Test;

import java.sql.*;

public class JDBCTest {

    @Test
    public void tt01() throws SQLException {
        ResultSet resultSet = null;
        Statement statement = null;
        Connection connection = null;
        try {
            //1.注册驱动 DriverManger
            DriverManager.registerDriver(new Driver());
            //2.建立连接Connection
            String url = "jdbc:mysql://localhost:3306/test";
            String user = "root";
            String password = "19491001";
            connection = DriverManager.getConnection(url, user, password);
            //3.获取执行sql语句的对象Statement
            statement = connection.createStatement();
            //4.执行sql语句
            String sql = "select * from USER ";
            resultSet = statement.executeQuery(sql);
            //5.处理结果
            while (resultSet.next()){
                System.out.println(resultSet.getString("uid"));
                System.out.println(resultSet.getString(2));
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //6.释放资源
            //关闭结果集
            resultSet.close();
            //关闭执行sql语句的对象statement
            statement.close();
            //关闭连接
            connection.close();
        }
    }

}

JDBC API详解

这里写图片描述

1.java.sql.DriverManager

作用:主要是用于加载驱动,并且创建和数据库的连接

1.1 RegisterDriver(Driver driver) ;注册驱动

  • 翻阅源码发现,通过API的方式注册驱动,Driver会new两次,所有推荐这种写法:

    Class.forName("com.mysql.jdbc.Driver");
    

1.2 getConnection(String url, String user, String password) ;与数据库建立连接

这里写图片描述

常见的几种数据库连接字符串的写法:

MySql写法:		jdbc:mysql://localhost:3306/sid
Oracle写法:	    jdbc:oracle:thin:@localhost:1521:sid
SqlServer写法:	jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=sid
2.java.sql.Connection接口
  • 接口的实现在数据库驱动中。所有与数据库交互都是基于连接对象的。

2.1 createStatement() ;创建执行sql语句对象

2.2 prepareStatement(String sql) ;创建预编译执行sql语句的对象

3.java.sql.Statement接口
  • 接口的实现在数据库驱动中
  • 操作sql语句,并返回相应结果对象

3.1 Statement; 执行sql语句对象

  • ResultSet executeQuery(String sql) 根据查询语句返回结果集。只能执行select语句。
  • int executeUpdate(String sql) 根据执行的DML(insert update delete)语句,返回受影响的行数。
  • boolean execute(String sql) 此方法可以执行任意sql语句。返回boolean值,表示是否返回的是ResultSet结果集。仅当执行select语句,且有返回结果时返回true, 其它语句都返回false
4.java.sql.ResultSet接口

4.1封装结果集,查询结果表的对象

  • 提供一个游标,默认游标指向结果集第一行之前。
  • 调用一次next(),游标向下移动一行。
  • 提供一些getXXX方法。XXX代表的是数据类型

4.2ResultSet接口常用API

  • boolean next() ;将光标从当前位置向下移动一行
  • XXX getXXX(int columnIndex) : 根据列的序号获取XXX类型的值,列的序号从1开始
  • XXX getXXX(String columnName) : 根据列名去获取XXX类型的值
  • void close()关闭ResultSet 对象

SQL注入问题解决:preparedStatement

什么是SQL注入:

SQL 注入是用户利用某些系统没有对输入数据进行充分的检查,从而进行恶意破坏的行为。

1.preparedStatement概述

预编译对象, 是Statement对象的子类。

特点:

  • 性能要高
  • 会把sql语句先编译,格式固定好,
  • sql语句中的参数会发生变化,过滤掉用户输入的关键字(or)。
2.用法
2.1通过connection对象创建
  • prepareStatement(String sql) ;创建prepareStatement对象
  • sql表示预编译的sql语句,如果sql语句有参数通过?来占位
2.2通过setxxx方法来指定参数
  • setxxx(int i,Obj obj); i 指的就是问号的索引(指第几个问号,从1开始),xxx是类型(eg:int,String,Long)

eg:

String sql = "select *from user where username =? and password =?";
//创建prepareStatement
statement = connection.prepareStatement(sql);
//设置参数
statement.setString(1, username);
statement.setString(2, password);

resultSet = statement.executeQuery();

连接池技术

自定义连接池

package top.simba1949.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;

public class DataSourceTest {
    //1.创建容器,用于存放连接Connection
    private static LinkedList<Connection> pool = new LinkedList<>();
    private static String url = "jdbc:mysql://localhost:3306/test";
    private static String user = "root";
    private static String password = "19491001";
    //1.1初始化连接池中的连接
    static {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            for (int i = 0;i < 3;i++){
                //1.2获取连接,放入池子
                Connection connection = DriverManager.getConnection(url, user, password);
                pool.add(connection);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 2.获取连接,从连接池中获取连接
     * @return
     */
    public static Connection getConnection(){
        //LinkedList:移除并返回此列表的第一个元素。
        return pool.removeFirst();
    }
    
    public static void release(Connection connection){
        //将从连接池获取的连接归还连接池
        if (null != connection){
            pool.add(connection);
        }
    }
}

自定义规范连接池(装饰者设计模式)

装饰者设计模式

固定结构:接口A,已知实现类C,需要装饰者创建代理类B

  • 创建类B,并实现接口A
  • 提供类B的构造方法,参数类型为A,用于接受A的其他实现类
  • 给类B添加类型为A的成员变量,用于存放A接口的实现类
  • 增强需要的方法
  • 实现不需要增强的方法,方法体重新调用成员变量存放的其他实现类对应的方法
package top.simba1949.jdbc;

import java.sql.*;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;

public class ConnectionTest implements Connection{
    private Connection connection;
    private List<Connection> pool;

    public ConnectionTest(Connection connection) {
        this.connection = connection;
    }

    public ConnectionTest(Connection connection, List<Connection> pool) {
        this.connection = connection;
        this.pool = pool;
    }

    //需要增强的方法
    @Override
    public void close() throws SQLException {
        this.pool.add(this);
    }
    //不需要增强的方法调用原来的方法返回
    @Override
    public Statement createStatement() throws SQLException {
        return this.connection.createStatement();
    }
  ......
  
}

C3P0连接池

需要导入C3P0的jar和数据库驱动的jar

C3P0下载地址

C3P0官方文档

C3P0的Maven地址

C3P0连接池配置项

DBCP连接池

需要导入commons-dbcp-xx.jar和commons-pool-xx.jar

DBCP下载地址

DBCP官方文档

DBCP的Maven地址

DBCP连接池配置项(官方)

DRUID连接池

DRUID官网

DRUID官方下载地址

DRUID的Maven地址

DBUtils

JavaBean组件

JavaBean就是一个类,在开发中常用封装数据。具有一下特性:

  • 需要实现接口:java.io.Serializable
  • 提供私有字段
  • 提供getter/setter方法
  • 提供无参构造
DBUtils概述

DBUtils是java编程中的数据库操作实用工具。封装了对JDBC的操作,简化了JDBC操作,少写代码

DBUtils三大核心功能
  • QueryRunner中提供对sql语句操作的API
  • ResultSetHandler接口,用于定义select操作后,怎样封装结果集
  • DbUtils类,定义了关闭资源与事务处理的方法
DBUtils核心类
  • QueryRunner(DataSource ds),提供数据源(连接池),DBUtils底层自动维护连接Connection
  • update(String sql,Object…params),执行更新数据
  • query(String sql,ResultSetHandler rsh,Object…params),执行查询
ResultSetHandler结果集处理类
ArrayHandler将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值
ArrayListHandler将结果集中的每一条记录封装到一个Object[]数组中,将这些数组再封装到List集合中
BeanHandler将结果集中的第一条记录封装到一个指定的javaBean中
BeanListHander将结果集中的每一条记录封装到一个指定的javaBean中,将这些javaBean再封装到List集合中
ColumnListHandler将结果集中指定的列的字段值,封装到一个List集合中
KeyedHandler将结果集中的每一条记录封装到一个Map< String,Object >中,再将这个Map集合作为Map1的value,Map1集合的key是指定的字段的值
MapHandler将结果集中的第一条记录封装到Map< String,Object > 集合中,key就是字段名称,value就是字段值
MapListHandler将结果集中的每一条记录封装到Map< String,Object > 集合中,key就是字段名称,value就是字段值,再将这些Map封装到List集合中
ScalarHandler它是用于单数据,例如:select count(*) from tname;
DBUtils工具类
  • closeQuietly(Connection conn):关闭连接,如果有异常try后不抛
  • commitAndCloseQuietly(Connection conn):提交并关闭连接
  • rollbackAndCloseQuietly(Connection conn):回滚并关闭连接
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Simba1949

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

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

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

打赏作者

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

抵扣说明:

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

余额充值