目录
一、连接数据库
二、数据库的高级应用(连接池)
三、使用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)+"
");
}
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。