【JavaEE学习笔记】JDBC_03_批处理,获取自增长键值,DBCP,C3P0,DBUtils

本文详细介绍了JDBC的高级特性,包括批处理、获取自增长键值、连接池技术(DBCP和C3P0)、以及DBUtils工具的使用方法。通过实际案例展示了如何高效地进行批量数据操作、管理数据库连接资源等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JDBC_03

A.批处理

1.概述

当我们需要向数据库存储大量数据时,就需要使用批处理

2.主要方法

PreparedStatment addBatch():调用批处理

PreparedStatment execuyeBatch():执行批处理

PreparedStatment clearBatch():清空批处理

3.代码实现

需求:存放100个数据信息

a.在数据库中创建一个表,具有主键增长

CREATE TABLE USER(
	id INT PRIMARY KEY AUTO_INCREMENT,
	username VARCHAR(50)
);

b.导入驱动jar包和jdbc连接数据库工具类、配置文件

package org.xxxx.jdbc.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle;

/**
 * 
 * 这是一个jdbc连接数据库的工具类
 * 
 * @author wpf
 * 
 */
public class JDBCUtil {

	private static String url;
	private static String user;
	private static String password;
	private static String classname;

	// 读取配置信息
	static {
		try {
			// 获取对象
			ResourceBundle rb = ResourceBundle.getBundle("config");
			url = rb.getString("url");
			user = rb.getString("user");
			password = rb.getString("password");
			classname = rb.getString("classname");

			// 加载驱动
			Class.forName(classname);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	// 不能创建对象
	private JDBCUtil() {

	}

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

	// 释放资源
	public static void close(ResultSet resultSet, Statement statement, Connection conn) throws SQLException {
		if (resultSet != null) {
			resultSet.close();
		}
		if (statement != null) {
			statement.close();
		}
		if (conn != null) {
			conn.close();
		}
	}

	public static void close(Statement statement, Connection conn) throws SQLException {
		if (statement != null) {
			statement.close();
		}
		if (conn != null) {
			conn.close();
		}
	}

}
配置文件

url=jdbc:mysql://localhost:3306/mydb_01
user=root
password=root
classname=com.mysql.jdbc.Driver

c.写一个User类作为javaBean存放对象

package org.xxxx.jdbc.bean;

import java.io.Serializable;

public class User implements Serializable {

	private static final long serialVersionUID = 1L;

	private int id;
	private String username;

	public User() {
		super();
	}

	public User(int id, String username) {
		super();
		this.id = id;
		this.username = username;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + "]";
	}

}

d.测试类

package org.xxxx.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;

import org.xxxx.jdbc.bean.User;
import org.xxxx.jdbc.util.JDBCUtil;

public class JDBCDemo {
	public static void main(String[] args) throws SQLException {
		 // 建立集合存放对象
		ArrayList<User> list = new ArrayList<>();
		
		// 存放数据
		for (int i = 0; i < 100; i++) {
			// 为了便于观察 编号为1000+i,username为"姓名+i"
			User user = new User(i + 1000, "张三" + i);
			list.add(user);
		}
		
		//连接数据库
		Connection conn = JDBCUtil.getConnection();
		
		// 定义sql语句
		String sql = "insert into user values(?, ?)";
		
		// 获取预编译对象
		PreparedStatement statement = conn.prepareStatement(sql);
		
		// 用批处理执行
		// 遍历集合
		for (User u : list) {
			statement.setInt(1, u.getId());
			statement.setString(2, u.getUsername());
			
			// 调用批处理,将数据加入缓存
			statement.addBatch();
		}
		
		// 执行批处理
		statement.executeBatch();
		
		// 清空批处理
		statement.clearBatch();
		
		// 释放资源
		JDBCUtil.close(statement, conn);
	}
}

B.获取自增长键值

1.概述

如果我有两张表,添加了外键约束user 表是主表,订单表是从表

这两张表通过外键关联起来,如果说我在user表里面添加了一个用户,用户的id 是主键

那我想在订单表里面,描述这个用户的订单,那我就得拿到这个用户的id

2.主要方法

public prepareStatment(sql, PreparedStatment.RETURN_GENERATED_KEYS):

该构造方法主要返回主键

prepareStatment setNull(1,Types.INTEGER):

插入整数空值,适用于自增长主键

ResultSet getGeneratedKeys():

获取自增长键,返回结果集

3.需求

插入一个用户信息,并返回用户主键(id)

package org.xxxx.jdbc;

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

import org.xxxx.jdbc.util.JDBCUtil;

import com.mysql.jdbc.PreparedStatement;

public class JDBCAutoKeyValue {
	public static void main(String[] args) throws SQLException {
		// 获取链接对象
		Connection conn = JDBCUtil.getConnection();

		// 定义sql语句
		String sql = "insert into user values(?, ?)";

		// 获取预编译对象
		java.sql.PreparedStatement statement = conn.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);

		// 给占位符赋值
		statement.setNull(1, Types.INTEGER);
		statement.setString(2, "李四");

		// 执行
		int i = statement.executeUpdate();

		// 获取自增长键的值
		ResultSet resultSet = statement.getGeneratedKeys();

		// 遍历
		while (resultSet.next()) {
			int keys = resultSet.getInt(1);
			System.out.println(keys);
		}

		// 释放资源
		JDBCUtil.close(resultSet, statement, conn);
	}
}

C.DBCP

1.连接池

存放多个连接对象的容器,我们每获取一次链接对象

底层会很耗费资源,连接池可以提高项目的性能

2.DBCP

阿帕奇基金组织出产的高效的管理链接对象

3.主要方法

BasicDataSourceFactory.createDataSource(Properties prop);

创建连接池,读取配置信息必须用Properties

4.代码实现

a.导入DBCP的两个jar包和数据库驱动jar包(一共三个),下图是DBCPjar包


b.导入配置文件dbcp.properties

#连接基本设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb_01
username=root
password=root


#<!--扩展配置 了解-->
#初始化连接
initialSize=10

#最大连接数量
maxActive=50

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

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

#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000

#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;] 
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=gbk

#指定由连接池所创建的连接的自动提交(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

c.测试类

package org.xxxx.dbcp;

import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Types;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;

public class DBCPDemo {
	public static void main(String[] args) throws Exception {
		// 读取配置信息
		Properties prop = new Properties();
		prop.load(new FileInputStream("src//dbcp.properties"));
		
		// 创建连接池
		DataSource ds = BasicDataSourceFactory.createDataSource(prop);
		
		// 链接数据库
		Connection conn = ds.getConnection();
		
		// 定义sql语句
		String sql = "insert into user values(?, ?)";
		
		// 获取预编译对象
		PreparedStatement statement = conn.prepareStatement(sql);
		
		// 赋值
		statement.setNull(1, Types.INTEGER);
		statement.setString(2, "王五");
		
		// 执行语句
		statement.executeUpdate();
		
		// 释放资源
		statement.close();
		conn.close();
	}
}

D.C3P0

1.在hibernate和spring框架中常用,有自动回收空闲连接功能

2.主要方法

建立连接池

public ComboPooledDataSource();

public ComboPooledDataSource(String str);选择配置信息

3.代码实现

a.导入jar包和mysql驱动


b.导入配置信息c3p0.properties或者c3p0-config.xml(先介绍properties)

要求

1)配置文件和后缀名固定:c3p0.properties

2)必须放在src目录下

使用者就不需要再读取配置信息,驱动中会自动读取

c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///mydb_01
c3p0.user=root
c3p0.password=root

c.测试类

package org.xxxx.c3p0;

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

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0Demo {
	public static void main(String[] args) throws SQLException {
		// 建立连接池
		ComboPooledDataSource ds = new ComboPooledDataSource();

		// 链接数据库
		Connection conn = ds.getConnection();

		// 定义sql语句
		String sql = "insert into user values(?, ?)";

		// 获取预编译对象
		PreparedStatement statement = conn.prepareStatement(sql);
		
		// 赋值
		statement.setNull(1, Types.INTEGER);
		statement.setString(2, "王五");
		
		// 执行语句
		statement.executeUpdate();
		
		// 释放资源
		statement.close();
		conn.close();
		ds.close();
	}
}

控制台的提示信息不用管

4.c3p0-config.xml配置文件

<c3p0-config>
	<!-- 默认配置,如果没有指定则使用这个配置 -->
	<default-config>
		<!-- 基本配置 -->
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/mydb_01</property>
		<property name="user">root</property>
		<property name="password">root</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>
	</default-config> 
	
	
	<!-- 命名的配置 -->
	<named-config name="myname">
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/xxxx</property>
		<property name="user">root</property>
		<property name="password">1234</property>
		
		
		<!-- 如果池中数据连接不够时一次增长多少个 -->
		<property name="acquireIncrement">5</property>
		<property name="initialPoolSize">20</property>
		<property name="minPoolSize">10</property>
		<property name="maxPoolSize">40</property>
		<property name="maxStatements">20</property>
		<property name="maxStatementsPerConnection">5</property>
	</named-config>
</c3p0-config> 
这个配置文件和properties只能存在一个

用法和properties一样

不同地方:命名配置

设置named_config,若要读取该配置信息,则使用有参构造

ComboPooledDataSource ds = new ComboPooledDataSource("myname");

E.DBUtils

1.概述

阿帕奇基金组织出品,封装操作对象的增删改查

2.主要方法

配合C3P0使用

public QueryRunner(ComboPooledDataSource ds);

将连接池对象传进去

List<> query(sql, new BeanListHandler<>(User.class));

查处所有数据,并封装为对象,装到集合里

3.需求

查询user中的所有数据

a.在C3P0的基础上,导入jar包和驱动


b.建立javaBean存储对象

package org.xxxx.c3p0.bean;

import java.io.Serializable;

public class User implements Serializable {

	private static final long serialVersionUID = 1L;

	private int id;
	private String username;

	public User() {
		super();
	}

	public User(int id, String username) {
		super();
		this.id = id;
		this.username = username;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + "]";
	}

}

c.代码实现

import org.xxxx.c3p0.bean.User;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class DBUtils {
	public static void main(String[] args) throws SQLException {
		// 创建连接池
		ComboPooledDataSource ds = new ComboPooledDataSource();
		
		// 创建增删改查对象
		QueryRunner runner = new QueryRunner(ds);
		
		// 定义sql语句
		
		String sql = "select * from user";
		
		// 执行语句,并封装对象到集合
		List<User> list = runner.query(sql, new BeanListHandler<>(User.class));
		
		// 遍历
		for (User u : list) {
			System.out.println(u.getId() + "---" + u.getUsername());
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值