第四章节 JDBC的基本应用
目录
一、连接数据库
二、数据库的高级应用(连接池)
三、使用tomcat连接池
下载并配置好JDBC驱动后,我们可以来使用。
一、连接数据库
注意,如果项目中用到了mysql数据库,还要添加mysql驱动程序Connector/J到这个项目中才行。
使用JDBC连接数据库存取数据时,要执行三个步骤
- 加载及注册适当的JDBC驱动程序
加载使用
Class.forName();
加载完成后,驱动程序会建立一个Driver对象,并且会让DriverManager.rigisterDriver()自动注册这个对象。
在JDBC中用URL来标识数据库,
jdbc:<子协议>:<子名称>
使用MySQL时,语法如下
jdbc:mysql://hostname:port/databasename?param=value1
子协议:mysql
子名称://hostname:port/databasename?param=value1,其中param可以有多个。
实例如:
jdbc:mysql://localhost:3306/sample?user=root&password=root;
- 建立到指定的数据库的连接对象
有两种方法:
1.
String url = "jdbc:mysql://localhost:3306/sample?user=root&password=root";
Connection con = DriverManager.getConnection(url);
2.
String url = "jdbc:mysql://localhost:3306/sample";
String user ="root";
String password="root";
Connection con = DriverManager.getConnection(url,user,password);
- 提交数据库查询和取得查询对象
在取得数据库的连接对象后,就可以由它来创建一个陈述对象,其主要用来 传送 SQL语句到数据库服务器和执行Sql语句。
如下:
Statement stmt= con.createStatement();
Statement对象有有三种执行语句的方法:
executeQuery():执行查询。
executeUpdate():执行更新。
execute():不知道正要执行的是什么时。
执行后数据库会返回一个ResultSet集合对象到JDBC中。原理如下:
Connection ------>PreparedStatement-------->ResultSet
|------>Statement----------------->ResultSet
|-------->CallableStatement------>ResultSet
- 使用代码连接数据库
我们先建立一个testmysql的数据库,里面有一个student表。
//建立
create databse testmysql;
//查看
show databases;
//建立表
user testmysql;
create table student( id int(3), name char(20), sex boolean);
//加入数据
insert into student ('1', 'lishengjing','1');
//查看数据
select * from student ;
然后我们在本项目中加载 jdbc,右键项目,选择build path 里面的user library中的MySQL.
最后是编码。如下
package chuiyuan;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCExample {
public static void main(String args[]){
try {
Class.forName("com.mysql.jdbc.Driver") ;
String url = "jdbc:mysql://localhost:3306/testmysql?user=root&password=chuiyuan" ;
Connection connection = DriverManager.getConnection(url) ;
Statement stmt = connection.createStatement() ;
ResultSet rs = stmt.executeQuery("select * from student");
while (rs.next()) {
System.out.println("student number:"+rs.getInt(1));
System.out.println("student name:"+rs.getString(2));
System.out.println("stutent sex:"+ rs.getBoolean(3)+"\n");
}
rs.close();
stmt.close();
connection.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}catch (SQLException e) {
e.printStackTrace();
}
}
}
- 用户界面连接数据库
要在MyEclipse的DatabaseExplore中连接到数据库。
参考
http://jingyan.baidu.com/article/4e5b3e196758ad91901e24a0.html
二、数据库的高级应用(连接池)
如果对数据库的访问不是很频繁,我们可以在简单的在访问数据库时创建一个连接,用完后关闭,但是如果是一个复杂的频率的数据库应用,就不行了。
- 数据库连接池
为避免频繁地建立和关闭数据库,我们可以建立一个数据库连接池以共享连接资源。这就是共享资源里面的很出名的设计模式:资源池。
数据库连接池的基本原理:
在内部对象池中,维护一定数量的数据库连接,并对外暴露数据库连接获取和返回的方法,当要建立一个数据库连接时,只要从内存中取得一个,而不是新建一个。
用完后,只用放回到内存中,对于连接的打开和建立都由连接池自己管理 。
数据库连接池有以下特点:
资源重用。
高效的系统响应。
统一的资源管理。
- 数据库连接池的例子
先查看工程lib中是否加入了Mysql 连接驱动Connector/J,如果没有,在工程,右键的Build libs中加入。
在工程中加入 Pooling.properties文件如下
driverClassName=com.mysql.jdbc.Driver
username=root
password=chuiyuan
url=jdbc:mysql://localhost:3306/testmysql
poolSize=10
注意要写对,properties文件是用来对工程进行简单的配置的。详细相关的内容参考
http://www.open-open.com/lib/view/open1426130993279.html
http://blog.csdn.net/haiyangzhibing/article/details/6699119
然后是数据库连接池
注意下面的对数据库的操作,除了在init中的,其它的几个都进行了线程同步。
package chuiyuan;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import java.util.Vector;
public class ConnectionPool {
//实现List接口之一,与ArrayList相比,也是数组实现,
//但支持线程同步,所以访问速度慢于ArrayList
//但是大多数情况下不使用Vector,因为线程安全需要更大的系统开销
private Vector<Connection> pool;
private String url ;
private String username ;
private String password ;
private String drivderClassName ;
private int poolSize =1;//连接池大小,也就是连接池中有多少个数据库连接
private static ConnectionPool instance = null;
private ConnectionPool(){
init();
}
/**
* 返回当前连接池的一个对象
* @return
*/
public static ConnectionPool getInstance (){
if (instance==null){
instance = new ConnectionPool() ;
}
return instance ;
}
/**
* 初始化连接池,读取属性
*/
private void init() {
pool = new Vector<Connection>(poolSize) ;
readConfig();
addConnection();
}
/**
* 在连接池中创建初始设置的数据库连接
* 注意里面的循环做的工作
*/
private void addConnection() {
Connection connection = null ;
for (int i=0;i<poolSize; i++){
try {
Class.forName(drivderClassName) ;
connection= java.sql.DriverManager.
getConnection(url, username, password) ;
pool.add(connection) ;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}catch (SQLException e) {
e.printStackTrace();
}
}
}
private void readConfig() {
try {
String path = System.getProperty("user.dir")+"\\Pooling.properties";
FileInputStream fis = new FileInputStream(path) ;
Properties properties = new Properties() ;
properties.load(fis);
drivderClassName = properties.getProperty("driverClassName" );
username= properties.getProperty("username");
password = properties.getProperty("password");
url = properties.getProperty("url");
poolSize = Integer.parseInt(properties.getProperty("poolSize")) ;
} catch (Exception e) {
e.printStackTrace();
System.err.print("读取属性文件出错");
}
}
/**
* 用完后立即返回连接到连接池中
* @param conn
*/
public synchronized void release(Connection conn){
pool.add(conn) ;
}
/**
* 有所更改
*/
public synchronized void closePool(){
for (int i=0;i<pool.size();i++){
try {
pool.get(i).close();
} catch (SQLException e) {
e.printStackTrace();
}
//先close 再remove
//pool.remove(i) ;
}
pool.clear();
}
/**
* 返回数据库中的一个连接
* 下面的原来是pool.get(0),再进行remove
* 如果用pool.size()-1会更快些
* @return
*/
public synchronized Connection getConnection(){
if (pool.size()>0){
Connection conn = pool.get(pool.size()-1);
pool.remove(conn);
return conn ;
}else {
return null ;
}
}
}
里面的 getProperty("user.dir")为MyEclipse的安装目录。
测试文件
package chuiyuan;
import java.security.Policy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Test {
public static void main(String args[]) throws SQLException, ClassNotFoundException{
String sql ="select * from student" ;
long start = System.currentTimeMillis() ;
ConnectionPool pool = null;
for (int i=0;i<100;i++){
pool = ConnectionPool.getInstance() ;
Connection connection = pool.getConnection() ;
Statement stmt = connection.createStatement() ;
ResultSet rSet =stmt.executeQuery(sql) ;
while (rSet.next()) {
}
rSet.close();
stmt.close();
pool.release(connection);
}
pool.closePool();
System.out.println("用连接池时:"+(System.currentTimeMillis() - start)+"ms");
String hostname = "127.0.0.1";
String driverClass = "com.mysql.jdbc.Driver" ;
String url ="jdbc:mysql://localhost:3306/testmysql";
String username = "root" ;
String password = "chuiyuan";
start = System.currentTimeMillis() ;
for (int i=0;i<100;i++){
Class.forName(driverClass) ;
Connection connection = DriverManager.getConnection(url,username, password) ;
Statement stmt = connection.createStatement() ;
ResultSet rs = stmt.executeQuery(sql) ;
while (rs.next()) {
}
rs.close();
stmt.close();
connection.close();
}
System.out.println("不用连接池时:"+(System.currentTimeMillis() - start)+"ms");
}
}
三、使用tomcat连接池
这个项目中好像没有加入 Connector/J。
在开发项目时,编写连接池是没有必要的,因为已经存在很多数据库连接池现成了组件,只要配置一下就可以使用。而且现在很多服务器也已经内置了连接池,如tomcat.
- 配置tomcat
在tomcat的根目录conf中的context.xml文件中进行配置,使支持数据库连接池。
<!--设置数据库连接池的核心-->
<!-- name表示数据源的名字,auth表示验证方式 -->
<!-- Type设置了资源的类型 -->
<Resources name="jdbc/DBWater" auth="Container"
Type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="1000"
username="root" password="chuiyuan"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/testmysql" />
- 配置项目
新建一个DBWater的web项目,配置DBWater/WebRoot/WEB-INF/web.xml,在<web-app>中加入如下
<resource-ref>
<description> Connection Pool</description>
<res-ref-name>"java/DBWater</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
- 测试文件
package com.chuiyuan;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class DBWater {
String name ;
int number ;
boolean sex ;
public String getName (){
return name ;
}
public int getNumber(){
return number ;
}
public boolean isSex (){
return sex ;
}
public void init (){
try {
InitialContext initialContext = new InitialContext() ;
if (initialContext== null)
throw new Exception("no context");
//创建数据源ds
Context context = (Context) initialContext.lookup("java:comp/env");
DataSource ds = (DataSource)context.lookup("jdbc/DBWater");
if (ds!=null){
Connection connection = ds.getConnection() ;
if (connection!= null){
Statement stmt = connection.createStatement() ;
ResultSet rs = stmt.executeQuery("select * from student");
while (rs.next()) {
number = rs.getInt(1);
name = rs.getString(2);
sex = rs.getBoolean(3) ;
}
connection.close();
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
- 修改WebRoot/index.jsp代码如下
<%@ page contentType ="text/html; charset=UTF-8" %> <%@ page import="java.sql.*" %> <%@ page import="javax.sql.*" %> <%@ page import="javax.naming.*" %> <%@ page import="com.chuiyuan.*" %> <html> <head> <title>连接池测试</title> </head> <body> <% DBWater rs = new DBWater(); rs.init() ; %> 学生的学号:<%=rs.getNumber() %> 学生的姓名:<%=rs.getName() %> 学生的性别:<%=rs.isSex() %> </body> </html>
将这个项目发布到服务器,并启动tomcat服务器,在浏览器中输入 localhost:8080/DBWater/index.jsp。

浙公网安备 33010602011771号