第四章节 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。  

 

 

 

 

 

 

 

posted @ 2015-06-02 20:40  chuiyuan  阅读(230)  评论(0编辑  收藏  举报