目录
- 1 jdbc概念
- 2 jdbc原理
- 3 jdbc加载驱动代码
- 3.1 看源码
- 3.2 为什么不需要我们自己注册
- 4 类对象介绍
- 4.1 DriverManager
- 4.2 Connection
- 4.3 statement
- 4.4 ResultSet
- 5 JDBC 工具类
- 6 解决sql注入问题
- 7 JDBC 管理事务
- 8 jdbc 获取数据库连接对象connection
- 9 使用statement接口实现crud
- 10 数据库连接池
- 10.1 概念
- 10.2 DataSource
- 11 自定义jdbc框架
- 11.1 需求
- 11.2 数据库源信息
1 jdbc概念
2 jdbc原理
也就是,jdbc是基准,其他公司,比如mysql,oracle这些公司,基于这个jdbc基本,封装jdbc基准里面的api,变为自己的,也就是变为自己的东西,这个就是驱动类;
我们连接mysql,需要mysql的驱动类driver;连接oracle,需要oracle的驱动类,这些驱动类就是各个数据库厂家提供的;
3 jdbc加载驱动代码
我们创建一个maven,导入mysql的依赖
代码语言:javascript复制 <!--mysql驱动包-->
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
</dependencies>
以上这个是mysql的驱动包,这个就是mysql数据库公司封装了jdbc之后,自己的东西,以后我们使用这个驱动包,就可以在代码里面连接mysql数据库,并且操作数据库了;
以上在maven项目的pom文件里面写了这个,就相当于引入了mysql的驱动
mysql的驱动名称是com.mysql.jdbc.Driver
这个是mysql公司定的,我们使用就可以,我们在项目里面看看,能不能拿到这个对应的驱动
以上说明,只要添加了驱动,我们就可以在代码里面获取到驱动;
3.1 看源码
首先我们导入mysql的jar包,这个jar包就是mysql公司,封装了jdbc接口实现的一个项目,一个jar包就是一个项目,因为这个项目实现了java的jdk给提供的jdbc的接口,所以,我们就可以使用这个项目进行操作数据库,首先,每一个项目都有一个项目的入口,mysql的这个jar包也有,现在就是叫做驱动类,只要我们自己的项目,加载了这个驱动类,那么就有了mysql这个jar包的入口了;
1 我们看mysql的jar包的源码
找到驱动类
看这个类里面的代码
就相当于,我们一创建这个驱动类的对象,或者加载这个类,那么当前的jar包就和我们的jdk关联了;
3.2 为什么不需要我们自己注册
因为人家的jar包,已经有一个配置文件,这个里面配置了驱动类,直接读取这个配置文件,直接就可以进行注册,不需要我们自己注册
4 类对象介绍
4.1 DriverManager
这个类是jdk里面的,
4.2 Connection
这个类的对象,就是获取到了对应数据库的对象,之后根据这个对象,就可以操作数据库
4.3 statement
4.4 ResultSet
5 JDBC 工具类
这个工具类的作用就是,以后有人拿到这个代码,按照这个工具类里面的方法就可以操作数据库了
写一个配置文件
配置文件里面的内容是
代码语言:javascript复制url=jdbc:mysql://localhost:3306/eshop
user=root
password=123456
driver=com.mysql.jdbc.Driver
代码语言:javascript复制public class JDBCUtils {
// 1 私有构造方法
private JDBCUtils(){};
// 2 声明所需要的配置变量
private static String url ;
private static String user ;
private static String password ;
private static String driver;
// 3 提供静态代码块,读取配置文件里面的信息为变量赋值,注册驱动
static {
Properties pro = new Properties();
//这里是通过类加载器获取jdbc.propertise的绝对路径
//首先获取类的加载器,然后通过类的加载器获取src路径下资源的绝对路径
//这里的意思是不管模块如何移植,只要在模块当中,就能通过相对路径找到
//绝对路径
ClassLoader loader = JDBCUtils.class.getClassLoader();
//通过类加载器获取scr路径下的资源的绝对路径
URL res = loader.getResource("JDBC.properties");
//获取绝对路径
String path = res.getPath();
try {
pro.load(new FileReader(path));
} catch (IOException e) {
e.printStackTrace();
}
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 获取连接对象
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
// 关闭statement对象 和 Connection对象
public static void close(Statement stmt, Connection conn){
if (stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// 关闭statement对象 和 Connection对象 和 ResultSet对象
public static void close(ResultSet rs, Statement stmt, Connection conn){
if (rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
6 解决sql注入问题
就是使用预编译
7 JDBC 管理事务
如果多个方法都有事务,一个方法调用另一个方法,那么要保证多个方法使用的数据库的连接对象是同一个;
8 jdbc 获取数据库连接对象connection
我们在项目里面已经加载了驱动,之后根据驱动,就可以连接到mysql数据库了;这个驱动里面有很多的接口或者类,我们在代码里面只要操作这些,就可以操作数据库了;
我们首先要使用驱动获取到数据库连接,就是相当于获取到一个数据库对象,以后就可以拿这个对象进行操作数据库了;
代码语言:javascript复制package com.jing;/**
* @author jing
* @date 2022/3/29 -- 19:13
*/
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* @author jing
* @date 2022年03月29日 19:13
*/
public class jdbctest02 {
// 我要连接哪个数据库
private static String dbUrl="jdbc:mysql://localhost:3306/eshop";
// 数据库的用户名
private static String username = "root";
// 数据库的密码
private static String password = "123456";
// 使用哪个驱动进行连接数据库
private static String jdbcName = "com.mysql.jdbc.Driver";
public static void main(String[] args) {
try {
// 当前项目加载驱动
Class.forName(jdbcName);
System.out.println("加载成功");
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("加载失败");
}
Connection connection =null;
try {
// DriverManager 是驱动包里面的类,使用这个类里面的各种各样的方法进行操作数据库
connection = DriverManager.getConnection(dbUrl, username, password);
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
我们获取到connection对象,以后就在项目里面,就可以使用这个去操作数据库;
9 使用statement接口实现crud
我们以上已经获取到了数据库连接对象connection,使用这个获取statement接口对象,使用里面的方法就可以执行sql语句了,这个sql语句和我们在Navicat里面执行一样;
就是使用statement去操作sql语句;
代码语言:javascript复制public class jdbctest02 {
// 我要连接哪个数据库
private static String dbUrl="jdbc:mysql://localhost:3306/eshop";
// 数据库的用户名
private static String username = "root";
// 数据库的密码
private static String password = "123456";
// 使用哪个驱动进行连接数据库
private static String jdbcName = "com.mysql.jdbc.Driver";
public static void main(String[] args) {
try {
// 当前项目加载驱动
Class.forName(jdbcName);
System.out.println("加载成功");
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("加载失败");
}
Connection connection =null;
Statement statement =null;
try {
// DriverManager 是驱动包里面的类,使用这个类里面的各种各样的方法进行操作数据库
connection = DriverManager.getConnection(dbUrl, username, password);
statement = connection.createStatement();
String sql = "select * from product";
boolean execute = statement.execute(sql);
System.out.println(execute);
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
statement.close();
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
10 数据库连接池
10.1 概念
10.2 DataSource
这个是一个接口,java的jdk提供的,所以我们想要创建一个数据库连接池,就得自己写一个类,实现这个接口;
或者直接自己写一个类
代码语言:javascript复制package com.jing.utils;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.Properties;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
*
*
*
*/
public class DataSourcePool {
/**
* 最大连接数
*/
private static final int COUNT = 10;
/**
* 存放数据库
*/
private static final LinkedList<Connection> connections = new LinkedList<Connection>();
/**
* 创建锁
*/
private static final ReentrantLock lock = new ReentrantLock();
private static final Condition notEmpty = lock.newCondition();
private static final Condition notFull = lock.newCondition();
/**
* 数据库连接
*/
private static String URL;
/**
* 用户名
*/
private static String USER_NAME;
/**
* 密码
*/
private static String PASS_WORD;
/**
* 驱动类型
*/
private static String DRIVER_CLASS_NAME;
/**
* 存放属性信息
*/
private static Properties properties = new Properties();
/**
* 初始化信息
*/
static {
InputStream is = DataSourcePool.class.getResourceAsStream("JDBC.properties");
try {
properties.load(is);
URL = (String) properties.get("url");
USER_NAME = (String) properties.get("userName");
PASS_WORD = (String) properties.get("passWord");
DRIVER_CLASS_NAME = (String) properties.get("driver");
//加载驱动
Class.forName(DRIVER_CLASS_NAME);
Connection connection = null;
for (int i = 0; i < 10; i ) {
connection = DriverManager.getConnection(URL, USER_NAME, PASS_WORD);
connections.add(connection);
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 获取Connection
*/
public static Connection getConnection() {
final ReentrantLock reentrantLock = lock;
reentrantLock.lock();
try {
//如果没有连接了,则等待着新放入的连接
if (connections.isEmpty()) {
notEmpty.await();
}
Connection connection = connections.removeFirst();
notFull.signalAll();
return connection;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
reentrantLock.unlock();
}
return null;
}
/**
* 释放连接
*
* @param connection
*/
public static void release(Connection connection) {
final ReentrantLock reentrantLock = lock;
reentrantLock.lock();
try {
if (connections.size() == COUNT) {
notFull.await();
}
if (connection == null || connection.isClosed()) {
connections.add(DriverManager.getConnection(URL, USER_NAME, PASS_WORD));
notEmpty.signalAll();
return;
}
//恢复默认值
if (connection.getAutoCommit() == false) {
connection.setAutoCommit(true);
}
connections.add(connection);
notEmpty.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
reentrantLock.unlock();
}
}
}
11 自定义jdbc框架
之后我们使用的mybatis,就是封装了jdbc,把之前我们使用jdbc的语句封装了一下,因为我们就是要一个sql语句块,那些获取连接对象,关闭连接对象,都是公共的,我们不想操作,所以我们也要进行封装,可以这样说,这个自定义的jdbc的框架,就是mybatis框架的简化版;