JDBC learning

JDBC learning


1 Overview

JDBC is an API for Java to connect to databases. It allows users to access any form of tabular data, especially data stored in relational databases.

1.1 Load the driver package:

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>6.0.6</version>
</dependency>

1.2 Execution process:

  • Connect to a data source, such as a database.
  • Pass query and update instructions for the database.
  • Process the database response and return the result.

2. Related Interfaces

2.1 DriverManager

effect:

  • Register driver: use reflection to obtain driver instances in actual development
  • Get the connection: use the getConnection() method to get the database connection
Connection getConnection(String url, String username, String password);
/** url写法:jdbc:mysql://localhost:3306/dbname
*   jdbc: 协议
*   mysql: 子协议
*   localhost: 主机名
*   3306: 默认端口号
*   dbname: 数据库名字
*   默认url简写: jdbc:mysql:///dbname 
*/
// username: 数据库连接账号
// password:数据库连接密码

2.2 Connection

effect:

  • Create an object for executing SQL statements:
// 1. 执行SQL语句,有SQL注入漏洞
Statement createStatement()
// 2. 预编译SQL语句,解决SQL注入漏洞
PreparedStatement prepareStatement(String sql)
// 3. 执行SQL中存储过程
CallableStatement prepareCall(String sql)
  • conduct transaction management
// 设置事务是否自动提交
setAutoCommit(boolean autoCommit)
// 事务提交
commit()
// 事务回滚
rollback()

2.3 Statement

effect

  • execute SQL
// 执行SQl,执行select语句后返回true,否则返回false
boolean execute(String sql)
// 执行SQL中的select语句,并将结果封装
ResultSet executeQuery(String sql)
// 执行SQL中的insert/update/delete语句,返回受影响行数
int executeUpdate(String sql)
  • Execute batch
    processing. It is best not to exceed 500 batches at a time.
// 添加到批处理
addBatch(String sql)
// 执行批处理
executeBatch()
// 清空批处理
clearBatch()

2.4 ResultSet

Result set: that is, the encapsulation of the query result of the query statement (select) statement

effect

  • Get the query results
// 使用 next() 验证是否有下一个数据,有则返回true
rs.next()
// 使用 getXXX() 获取数据
rs.getInt("id")
rs.getString()
// 获取通用数据使用 getObject()
rs.getObject()

3. Connect to the database

3.1 Load the driver:

// 通过反射获得驱动,driverClass代表驱动类名
Class.forName(driverClass)
// 加载MySql驱动
Class.forName("com.mysql.jdbc.Driver")
// 加载Oracle驱动
Class.forName("oracle.jdbc.driver.OracleDriver")

3.2 Get database connection:

// 获得本地默认数据库
DriverManager.getConnection(jdbc:mysql://localhost:3306/dbname, root, root);

4. Resource release

  • Since the Connection object is a very rare resource, it should be released immediately after it is used up. If it is not timely, the correct shutdown can easily lead to system downtime. The principle of using Connection is to create it as late as possible and release it as early as possible.
  • ResultSet and Statement need to be released in time after use
// 使用close()方法释放资源
if(rs!= null){
	try {
		rs.close();
	} catch (SQLException e) {
		e.printStackTrace();
	}
	    rs = null;
	}
// 	PreparedStatement/Connection 同理释放

5. Tool class extraction

Since registering drivers, acquiring connections, and releasing resources are all repetitive operations. These codes can be extracted into a utility class, which can improve code reuse. At the same time, some database parameter configuration information can also be written to a configuration file.

5.1 Configuration file

# 文件名:jdbc.properties
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql:///dbname
username=root
password=root

5.2 Tools

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

//JDBC的工具类
public class JDBCUtils {
	private static final String driverClass;
	private static final String url;
	private static final String username;
	private static final String password;
	
	static{
		// 加载属性文件并解析:
		Properties props = new Properties();
		// 使用类的加载器的方式进行获取:
		InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
		try {
			props.load(is);
		} catch (IOException e) {
			e.printStackTrace();
		}
		driverClass = props.getProperty("driverClass");
		url = props.getProperty("url");
		username = props.getProperty("username");
		password = props.getProperty("password");
	}

	/**
	 * 注册驱动的方法
	 * @throws ClassNotFoundException 
	 */
	public static void loadDriver() throws ClassNotFoundException{
		Class.forName(driverClass);
	}
	
	/**
	 * 获得连接的方法:
	 * @throws SQLException 
	 */
	public static Connection getConnection() throws Exception{
		loadDriver();
		Connection conn = DriverManager.getConnection(url, username, password);
		return conn;
	}
	
	/**
	 * 资源释放方法1
	 */
	public static void release(PreparedStatement pstmt,Connection conn){
		if(pstmt != null){
			try {
				pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			pstmt = null;
		}
		if(conn != null){
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			conn = null;
		}
	}
	/**
	 * 资源释放方法2
	 */
	public static void release(ResultSet rs,PreparedStatement pstmt,Connection conn){
		if(rs!= null){
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			rs = null;
		}
		if(pstmt != null){
			try {
				pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			pstmt = null;
		}
		if(conn != null){
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			conn = null;
		}
	}
}

6. Data manipulation

That is, CRUD operations, generally use PreparedStatement to avoid SQL injection vulnerabilities. The following operation uses the utility class to obtain a database connection.

6.1 Adding data

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
// 导入工具类
import com.test.jdbc.utils.JDBCUtils; 
public class JDBCTest {
    public void insert(){
        Connection conn = null;
		PreparedStatement pstmt = null;
		try{
			// 获得连接:
			conn = JDBCUtils.getConnection();
			// 编写SQL:
			String sql = "insert into user values (null,?,?,?)";
			// 预处理SQL:
			pstmt = conn.prepareStatement(sql);
			// 设置参数的值:
			pstmt.setString(1, "hahaha");
			pstmt.setString(2, "12345");
			pstmt.setString(3, "小明");
			// 执行SQL:
			int num = pstmt.executeUpdate();
			if(num > 0){
				System.out.println("保存成功!");
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			// 释放资源
			JDBCUtils.release(pstmt, conn);
		}
    }
}

6.2 Modify data

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
// 导入工具类
import com.test.jdbc.utils.JDBCUtils; 
public class JDBCTest {
     public void update(){
        Connection conn = null;
		PreparedStatement pstmt = null;
		try{
			// 获得连接:
			conn = JDBCUtils.getConnection();
			// 编写SQL:
			String sql = "update user set username = ?,password = ?,name = ? where uid = ?";
			// 预编译SQL:
			pstmt = conn.prepareStatement(sql);
			// 设置参数:
			pstmt.setString(1, "hahaha");
			pstmt.setString(2, "123456");
			pstmt.setString(3, "小六");
			pstmt.setInt(4, 6);
			// 执行SQL:
			int num = pstmt.executeUpdate();
			if(num > 0){
				System.out.println("修改成功!");
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JDBCUtils.release(pstmt, conn);
		}
     }
}

6.3 Deleting data

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
// 导入工具类
import com.test.jdbc.utils.JDBCUtils; 
public class JDBCTest {
     public void delete(){
        Connection conn = null;
		PreparedStatement pstmt = null;
		try{
			// 获得连接:
			conn = JDBCUtils.getConnection();
			// 编写SQL:
			String sql = "delete from user where uid = ?";
			// 预编译SQL:
			pstmt = conn.prepareStatement(sql);
			// 设置参数:
			pstmt.setInt(1, 6);
			// 执行SQL:
			int num = pstmt.executeUpdate();
			if(num > 0){
				System.out.println("删除成功!");
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JDBCUtils.release(pstmt, conn);
		}
     }
}

6.4 Query data

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
// 导入工具类
import com.test.jdbc.utils.JDBCUtils; 
public class JDBCTest {
    // 查询一条
     public static void selectOne(){
        Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try{
			// 获得连接:
			conn = JDBCUtils.getConnection();
			// 编写SQL:
			String sql = "select * from user where uid = ?";
			// 预编译SQL:
			pstmt = conn.prepareStatement(sql);
			// 设置参数:
			pstmt.setObject(1, 3);
			// 执行SQL:
			rs = pstmt.executeQuery();
			// 判断结果集:
			if(rs.next()){
				System.out.println(rs.getInt("uid")+"  "+rs.getString("username")+"  "+rs.getString("password")+"  "+rs.getString("name"));
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JDBCUtils.release(rs, pstmt, conn);
		}
     }
     
    // 查询全部
    public static void selectOne(){
        Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try{
			// 获得连接:
			conn = JDBCUtils.getConnection();
			// 编写SQL:
			String sql = "select * from user";
			// 预编译SQL:
			pstmt = conn.prepareStatement(sql);
			// 设置参数
			// 执行SQL:
			rs = pstmt.executeQuery();
			while(rs.next()){
				System.out.println(rs.getInt("uid")+"  "+rs.getString("username")+"  "+rs.getString("password")+"  "+rs.getString("name"));
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JDBCUtils.release(rs, pstmt, conn);
		}
    }
}

7. Database connection pool

7.1 Connection Pool

Connection pooling is a buffer pooling technique for creating and managing a connection ready to be used by any thread that needs them.

  • Disadvantages of the application directly obtaining the connection: The user needs to obtain a connection to the database for each request, and the database connection usually consumes relatively large resources and takes a long time to create. This is a huge waste of database resources, and it is very easy to cause memory overflow of the database server.
  • Use connection pool: The connection requested by the user is obtained directly from the connection pool, and then put back into the connection pool after use. A large number of user needs can be met by maintaining fewer connections.

7.2 C3P0 Connection Pool

import jar package

<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
<dependency>
    <groupId>c3p0</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.1.2</version>
</dependency>

Instructions

  • Add configuration file
# 文件名 c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>

  <default-config>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
	<property name="jdbcUrl">jdbc:mysql:///dbname</property>
	<property name="user">root</property>
	<property name="password">abc</property>
	// 初始化线程池
	<property name="initialPoolSize">5</property>
	// 设置最大线程池大小
	<property name="maxPoolSize">20</property>
  </default-config>
  
</c3p0-config>
  • Use C3P0 to write tool classes
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class JDBCUtils2 {
    // 初始化连接池
	private static final ComboPooledDataSource dataSource = new ComboPooledDataSource();
	
	/**
	 * 获得连接的方法:
	 * @throws SQLException 
	 */
	public static Connection getConnection() throws Exception{
		Connection conn = dataSource.getConnection();
		return conn;
	}
	
	/**
	 * 资源释放方法1
	 */
	public static void release(PreparedStatement pstmt,Connection conn){
		if(pstmt != null){
			try {
				pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			pstmt = null;
		}
		if(conn != null){
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			conn = null;
		}
	}
	/**
	 * 资源释放方法2
	 */
	public static void release(ResultSet rs,PreparedStatement pstmt,Connection conn){
		if(rs!= null){
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			rs = null;
		}
		if(pstmt != null){
			try {
				pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			pstmt = null;
		}
		if(conn != null){
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			conn = null;
		}
	}
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324990064&siteId=291194637