JDBC基础知识复习

1、JDBC连接数据库

分3步:导入、注册、创建连接对象

1.1、导入JDBC驱动

导入对应数据库的驱动包(Jar文件),或者使用mvn导入对应数据库的依赖。

1.2、注册JDBC驱动程序

2个方法注册驱动,以Mysql为例子

  1. Class.forName("com.mysql.jdbc.Driver"),抛一个ClassNotFoundException的异常
  2. DriverManager.registerDriver(new com.mysql.jdbc.Driver())

1.3、创建连接对象

一般使用DriverManager.getConnection(String url, String user, String pass)方法获取

还有另外两种:

  1. getConnection(String url)方法
  2. getConnection(String url, Properties prop)方法

1.4、关闭JDBC连接

代码:Connection对象的close()方法

1.5、每种数据库对应的驱动名和URL

如下表:

JDBC驱动程序的名称URL
Mysqlcom.mysql.jdbc.Driverjdbc:mysql://hostname:port/ databaseName
Oracleoracle.jdbc.driver.OracleDriverjdbc:oracle:thin:@hostname:port Number:databaseName

2、JDBC接口

通过使用 JDBC Statement, CallableStatement 和 PreparedStatement 接口定义的方法和属性,使可以使用 SQL 或 PL/SQL 命令和从数据库接收数据。

接口应用场景
Statement当在运行时使用静态 SQL 语句时(Statement接口不能接收参数)
PreparedStatement当计划多次使用 SQL 语句时(PreparedStatement 接口接收在运行时输入参数)

2.2、Statement

我们需要使用 Connection 对象的 createStatement() 方法进行创建

Statement的方法:

方法说明
boolean execute(String SQL)如果 ResultSet 对象可以被检索返回布尔值 true,否则返回 false。使用这个方法来执行 SQL DDL 语句,或当需要使用真正的动态 SQL
int executeUpdate(String SQL)用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQL DDL(数据定义语言)语句。返回值是一个整数,指示受影响的行数(即更新计数)
ResultSet executeQuery(String SQL)返回 ResultSet 对象。用于产生单个结果集的语句,例如 SELECT 语句

释放Statement对象的方法是close()

2.3、PreparedStatement

占位符的概念而已,序号从1开始(不是从0开始哦)

2.4、两者区别

Statement适合静态SQL,PreparedStatement适合动态SQL。

因为PreparedStatement可以防止SQL注入!

3、ResultSet集合

结果集通常是通过执行查询数据库的语句生成,表示数据库查询结果的数据表。ResultSet 对象具有指向其当前数据行的光标。

ResultSet接口的方法可分为3类:

  1. 导航方法:用于移动光标
  2. 获取方法:用于查看当前行的光标所指向的列中的数据
  3. 更新方法:用于更新当前行的列中的数据

3.1、导航

迭代集合

3.2、获取

使用get方法

3.3、更新

使用update方法

4、事务

与数据库理论的事务概念一样,必须具有原子性、一致性、隔离性、持久性

需要先关闭提交的代码:使用Connection的setAutoCommit(false)方法

4.1、事务提交

使用Connection对象的commit()方法

4.2、事务回滚

使用Conncetion对象的rollback()方法

5、实现自己的数据库连接池

使用之前项目的图像算法中的均值hash的数据表
在这里插入图片描述

5.1、自己实现的连接池

package util;

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

/**
 * 数据库连接池
 * 循环链表实现
 * @author zzw
 */
public class DBPool {
	
	/**
	 * 池大小
	 */
	private static final int size = 20;
	
	/**
	 * 数据库驱动名
	 */
	private static final String driverName = "com.mysql.jdbc.Driver";
	
	/**
	 * 数据库名
	 */
	private static final String url = "jdbc:mysql://localhost:3306/imghashdb";
	
	/**
	 * 数据库用户名
	 */
	private static final String user = "root";
	
	/**
	 * 数据库密码
	 */
	private static final String password = "3306";
	
	/**
	 * 连接池
	 */
	private static final LinkedList<Connection> pool = new LinkedList<>();
	
	// 工具类不配实例化
	private DBPool() {}
	
	/**
	 * 创建size个连接对象放入连接池
	 */
	private static void createConnection() {
		for(int i=0;i<size;i++) {
			try {
				pool.add(DriverManager.getConnection(url, user, password));
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	// 静态代码块用于加载数据库驱动
	static {
		try {
			Class.forName(driverName);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取一个数据库连接
	 * @return Connection
	 */
	public static synchronized Connection getConn() {
		if(pool.isEmpty()) {
			createConnection();
		}
		return pool.removeFirst();
	}
	
	/**
	 * 归还一个数据库连接
	 * @param conn 数据库连接
	 */
	public static synchronized void callback(Connection conn) {
		// 如果当前连接池大小超过规定连接池大小,则不再归还
		if(pool.size() > size) {
			try {
				conn.close();
				System.out.println("此连接不必归还");
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}else {
			pool.add(conn);
		}
	}
}

5.2、测试

测试代码如下:

package app;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import util.DBPool;

public class App {
	public static void main(String[] args) throws SQLException {
		// 1. 增
		Connection conn = DBPool.getConn();
		conn.setAutoCommit(false);
		PreparedStatement prepareStatement = conn.prepareStatement("insert ahash values(?, ?, ?)");
		prepareStatement.setInt(1, 1);
		prepareStatement.setString(2, "00101101");
		prepareStatement.setString(3, "hello.jpg");
		int insert = prepareStatement.executeUpdate();
		System.out.println(insert);
		conn.commit();
		DBPool.callback(conn);
		
		// 2. 改
		//# 类似..略
		
		// 3. 查
		conn = DBPool.getConn();
		prepareStatement = conn.prepareStatement("select * from ahash");
		ResultSet resultSet = prepareStatement.executeQuery();
		resultSet.first();
		while(resultSet.next()) {
			System.out.println("id: "+resultSet.getInt(1)+", hash: "+resultSet.getString(2).substring(0, 8)+"..., path: "+resultSet.getString(3));
		}
		DBPool.callback(conn);
		// 4. 删
		//# 类似..略
		
	}
}

5.3、测试结果

在这里插入图片描述
控制台输出:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值