RowSet和DataRource
每次连接数据库执行sql都是对数据库服务器的负载,多次连续执行数据库操作势必会降低程序的性能,而这个问题可以通过结果集离线和数据库连接池来解决。
结果集离线
之前程序中用到的ResultSet对象只有在数据库链接有效的时候才能使用,如果断开链接还继续使用的话系统会抛出异常,如果关掉链接之后还能使用结果集就需要用到RowSet,下面是RowSet接口的相关信息。
RowSet 对象可以建立一个与数据源的连接并在其整个生命周期中维持该连接,在此情况下,该对象被称为连接的 rowset。rowset 还可以建立一个与数据源的连接,从其获取数据,然后关闭它。这种 rowset 被称为非连接 rowset。非连接 rowset 可以在断开时更改其数据,然后将这些更改发送回原始数据源,不过它必须重新建立连接才能完成此操作。 相比较java.sql.ResultSet 而言,RowSet 的离线操作能够有效的利用计算机越来越充足的内存,减轻数据库服务器的负担,由于数据操作都是在内存中进行然后批量提交到数据源,灵活性和性能都有了很大的提高。RowSet 默认是一个可滚动,可更新,可序列化的结果集,而且它作为 JavaBeans,可以方便地在网络间传输,用于两端的数据同步。
RowSet 接口下面包含几个常用的子接口,分别为jdbcRowSet、CachedRowSet、FilteredRowSet、JoinRowSet与WebRowSet。
JdbcRowSet是连接式(Connected)的RowSet,也就是操作JdbcRowSet期间,会保持与数据库的连接,可视为取得、操作ResultSet的行为封装,可简化JDBC程序的编写,或作为JavaBean使用,他的用法如下:
package week_one;
import java.sql.SQLException;
import javax.sql.rowset.JdbcRowSet;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;
public class rowset {
public static void main(String arg[]){
String url="jdbc:mysql://localhost:3306/java";
try {
Class.forName("com.mysql.jdbc.Driver");
RowSetFactory fac=RowSetProvider.newFactory();//通过RowSetProvider创建工厂
JdbcRowSet rowset=fac.createJdbcRowSet();
rowset.setUrl(url);//设置连接的url
rowset.setUsername("root");//数据库账号
rowset.setPassword("root");//数据库密码
rowset.setCommand("select * from java2");//数据库需要执行的sql
rowset.execute();
//数据库在执行完sql之后会直接把结果集返回给JdbcRowSet使流程比创建ResultSet更加简洁
while(rowset.next()){
System.out.print("\n"+rowset.getString(1)+" "+rowset.getString(2));
if(rowset.getInt(1)==1){
rowset.updateString(2,"hewkcopyff");
rowset.updateRow();
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
CachedRowSet则为离线式(Disconnected)的RowSet,在查询并填充完数据后,就会断开与数据源的连接,而不用占据相关连接资源,必要时也可以再与数据源连接进行数据同步,它的使用方法如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.rowset.CachedRowSet;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;
public class cachedrowset {
public static void mian(String arg[]){
Connection con=null;
String url="jdbc:mysql://localhost:3306/java";
try {
Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection(url);
con.setAutoCommit(false);
PreparedStatement pre=con.prepareStatement("select * from java2");
ResultSet res=pre.executeQuery();
RowSetFactory fac=RowSetProvider.newFactory();
CachedRowSet rowset=fac.createCachedRowSet();
rowset.setUrl(url);
rowset.setUsername("root");
rowset.setPassword("root");
rowset.populate(res);//植入结果集
res.close();
pre.close();
con.close();
while(rowset.next()){
System.out.print("\n"+rowset.getString(1)+" "+rowset.getString(2));
}
con.commit();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
WebRowSet继承自 CachedRowSet,并可以将 WebRowSet 写到 XML 文件中,也可以用符合规范的 XML 文件来填充 WebRowSet。
FilteredRowSet通过设置 Predicate(在 javax.sql.rowset 包中),提供数据过滤的功能。可以根据不同的条件对 RowSet 中的数据进行筛选和过滤。
JoinRowSet提供类似 SQL JOIN 的功能,将不同的 RowSet 中的数据组合起来。
数据源连接池
除了离线Rowset外还有一种方法可以提高程序链接数据库的效率那就是使用数据库连接池。
每一个数据库链接对象都对应一个物理链接,每次操作会打开一个物理链接使用完之后会立即关闭,频繁的开关物理链接会造成系统地下。数据库链接池解决的就是这个问题,当系统启动后主动建立一定数量的链接并组成连接池,每次程序请求数据库链接时直接取连接池中现有的连接使用完毕后不会立即关闭而是把它还给数据库连接池,这样就大大提高了系统的性能。
目前比较流行的 数据源实现有两种分别为dbcp数据源 和c3p0数据源,运用这两种数据源需要下载相应的jar包,这两种数据源的简单应用如下:
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.commons.dbcp.BasicDataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class datasource {
public static void mian(String arg[]){
//dbcp数据源
/*BasicDataSource ds=new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/java");
ds.setUsername("root");
ds.setPassword("root");
ds.setInitialSize(5);
ds.setMaxActive(20);
ds.setMinIdle(2);*/
//c390
ComboPooledDataSource ds=new ComboPooledDataSource();
try {
ds.setDriverClass("com.mysql.jdbc.Driver");
ds.setJdbcUrl("jdbc:mysql://localhost:3306/java");
ds.setUser("root");
ds.setPassword("root");
ds.setMaxPoolSize(20);//设置连接池的最大连接数
ds.setMinPoolSize(2);//设置连接池的最小连接数
ds.setInitialPoolSize(5);//设置连接池的厨师连接数
ds.setMaxStatements(180);//设置连接池缓存Statement最大数
} catch (PropertyVetoException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
Connection ca=ds.getConnection();
PreparedStatement sta=ca.prepareStatement("select * from java2");
ResultSet rest=sta.executeQuery();
while(rest.next()){
System.out.print(rest.getString(1)+" "+rest.getString(2)+"\n");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}