JDBC

什么是JDBC?
JDBC是Java数据库连接的简称,是由一组Java语言编写的类和接口组成,是一种用于执行SQL语句的API。JDBC API提供两类主要接口,一是面向开发人员的java.sql,另一种是面向底层数据库厂商的JDBC Drivers


为什么要使用JDBC




JDBC应用步骤?
1、加载数据库的驱动程序
Class.forName(“com.mysql.jdbc.Driver”);
2、建立数据库连接
String connStr = “jdbc:mysql://IP:PORT/em?useUnicode=true&characterEncoding=UTF-8”;
Connection conn = DriverManager.getConnection(connStr,”root”,”root”);
3、执行数据库操作SQL
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(“select * from student”);//sql语句
while(rs.next())
System.out.println(rs.getString(“sname”));
4、关闭数据库
conn.close();


Connection对象的基本方法
Statement createStatement()
CallableStatement prepareCall(String sql) //返回一个CallableStatement对象,该对象能够处理存储过程
PreparedStatement prepareStatement(String sql) //返回一个PreparedStatement对象,并能把sql语句提交到数据库进行预编译
void commit()
void rollback()
void close()


Statement常用方法
execute:执行给定的 SQL 语句,该语句可能返回多个结果
executeQuery:执行给定的 SQL 语句,该语句返回单个 ResultSet 对象
executeUpdate执行,该语句可能为 INSERT、UPDATE 或 DELET给定 SQL 语句
getConnection:获取生成此 Statement 对象的 Connection 对象
close:立即释放此 Statement 对象的数据库和 JDBC 资源,而不是等待该对象自动关闭时发生此操作
getFetchSize:获取结果集合的行数
getQueryTimeout:获取驱动程序等待 Statement 对象执行的秒数


为什么使用PreparedStatement?
PreparedStatement接口是Statement的子接口
防止SQL注入攻击(使用占位符“?”,SQL语句在程序运行前已经进行了预编译,当运行时动态地把参数传给PreprareStatement时,即使参数里有敏感字符,数据库也会作为一个参数一个字段的属性值来处理而不会作为一个SQL指令)
提高SQL的执行性能(在执行之前有预处理)
避免使用SQL方言
提高JDBC中有关SQL代码的可读性
所以往往会使用PreparedStatement


ResultSet表示数据库结果集的数据表,通常通过执行查询数据库的语句生成
next:将光标从当前位置向前移一行
getXXX:以某种对象的形式获取指定 JDBC 该类型参数的值
absolute:将光标移动到此 ResultSet 对象的给定行编号
afterLast:将光标移动到此 ResultSet 对象的末尾,正好位于最后一行之后
beforeFirst:将光标移动到此 ResultSet 对象的开头,正好位于第一行之前
close:立即释放此 ResultSet 对象的数据库和 JDBC 资源,而不是等待该对象自动关闭时发生此操作
first:将光标移动到此 ResultSet 对象的第一行。
getRow:获取当前行编号
isFirst:获取光标是否位于此 ResultSet 对象的第一行
isLast:获取光标是否位于此 ResultSet 对象的最后一行
last:将光标移动到此 ResultSet 对象的最后一行
previous:将光标移动到此 ResultSet 对象的上一行


连接池
通过JDBC访问数据库,每次访问都要经历与数据库建立连接,打开连接,访问数据库,关闭连接几个步骤,与数据库建立并打开连接是一件既费力又费时的工作,频繁的发生这种操作会严重耗费系统资源,导致系统性能下降,严重的会导致系统崩溃
数据库连接池就是为了解决上面的问题而出现的。数据库连接池负责动态的分配、管理和释放数据库连接


DataSource属于javax.sql包,是对java.sql包的扩展部分。DataSource用于提供到此 DataSource对象所表示的物理数据源的连接
使用数据库厂商驱动中提供的DataSource实现:如使用Oracle驱动自带的DataSource实现
oracle.jdbc.pool.OracleConnectionPoolDataSource

使用第三方提供的DataSource实现:Apache DBCP、C3P0

简单的连接池

package onest.db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 * 简单的数据库连接池示例
 * 
 * @author liupopo
 * 
 */
public class DatabasePool {

	private final static Map<Connection, Boolean> connPool = new HashMap<Connection, Boolean>(); // 用来存放连接的“池”
	private final static int MINI_POOL_SIZE = 3;// 最小的连接数
	private final static int MAX_POOL_SIZE = 4;// 最大的连接数
	private static int currentConnNum = 0;// 当前连接数
	
	private static DatabasePool instance = new DatabasePool(); // 唯一实例

	/**
	 * 构造方法,因为数据库连接池是个单例,所以不允许外界任意的new对象,构造方法设置为私有
	 */
	private DatabasePool() {
		init();
	}

	/**
	 * 获取这个实例的唯一方式
	 * 
	 * @return 唯一的池对象
	 */
	public static DatabasePool getInstance() {
		return instance;
	}


	/**
	 * 初始化连接池,在创建这个池实例时执行
	 */
	private void init() {
		for (int i = 0; i < MINI_POOL_SIZE; i++) {
			connPool.put(createConnection(), true);
		}
	}

	/**
	 * 创建连接对象,外界获取连接是从池里获取,该方法由类本身使用,所以该方法为私有
	 * 
	 * @return 数据库连接对象
	 */
	private Connection createConnection() {
		Connection conn = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		}
		String url = "jdbc:mysql://127.0.0.1:3306/em?useUnicode=true&characterEncoding=UTF-8";
		try {
			conn = DriverManager.getConnection(url, "root", "");
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}

	/**
	 * 外界获得一个数据库的连接
	 * @return 数据库连接
	 */
	public Connection getConnection() {
		Connection conn = null;
		if (currentConnNum < MINI_POOL_SIZE) {
			for (Connection con : connPool.keySet()) {
				if (connPool.get(con)) {
					conn = con;
					connPool.put(con, false);
					break;
				}
			}
			currentConnNum++;
			return conn;
		} else if (currentConnNum < MAX_POOL_SIZE) {
			conn = createConnection();
			connPool.put(conn, false);
			currentConnNum++;
			return conn;
		} else
			return getConnection();
	}

	/**
	 * 当使用完连接后,要把连接放回池中,或者销毁连接并中池中移掉
	 * @param conn
	 */
	public void close(Connection conn) {
		if (currentConnNum > MINI_POOL_SIZE) {
			try {
				conn.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				connPool.remove(conn);
			}
		}else{
			connPool.put(conn, true);
		}

	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值