一、生成连接方法:在通过控制台对数据库表进行操作时,每个增删改查动作都需要重新连接数据库,重新创建PrepareStatement对象如果有结果集的话还需要重新创建结果集,而这些代码是很冗长的,并且如果改变了数据库的用户名及密码时我们需要在每个用到了用户名及密码的位置都进行修改,那么既然如此我们就可以将这些重复进行的代码提取出来形成数据库单元类,让这个类进行数据库的连接及创建PrepareStatement对象与结果集对象,这样不仅在写连接代码时会方便很多,而且在修改代码时也方便很多。
例一:DButil类
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class DBUtil {
/**
* 先加载驱动类,由于只需要加载一次且
* 要在类执行的时候就加载,所以我们可
* 以将代码写到静态代码块中
*/
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取连接,工厂方法,所以为静态,异常应该抛出,谁调用谁处理
*/
public static Connection getConnection() throws Exception {
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql_zyd?useUnicode=true&characterEncoding=UTF-8","root","19980609rwx");
return conn;
}
/**
* 关闭连接,异常应该处理,否则无法关闭
* 第一个关闭方法为无结果集关闭
*/
public static void closeConnection(PreparedStatement ps,Connection conn) {
if(ps!=null) {
try {
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 重载方法,有结果集关闭
*/
public static void closeConnection(ResultSet rs,PreparedStatement ps,Connection conn) {
if(rs!=null) {
try {
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if(ps!=null) {
try {
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
二、连接方法简化:例一中的代码示例是在mysql数据库下进行的,而如果需要使用Oracle数据库时,如果仍然想使用这个连接类,那就需要修改源码,而我们知道,一旦程序运行后就会生成.class文件,如果修改了源码,是会生成新的.class文件,而我们需要将新的.class文件再加入到工程中,所以需要对连接类进行进一步的简化。在类库中有一个Properties类,它是Map类的子类,而Map类中的数据都是以key-value键值对存在,那么在Properties类中,Key为String,Value也为String类型,我们可以使用Properties类对象解析.properties配置文件拿到数据,而.properties配置文件又是什么。.properties配置文件是Properties类提取数据的一个配置文件,其中存储的是用户名、密码等连接数据库所需要的一切数据,是以k-v键值对存在。如果我们使用该类与.properties配置文件,就可以在不改变源代码的基础下对数据库的连接进行修改,而不用新生成.class文件。
例二:
第一步:在数据库单元类同一包下创建一个.properties文件,将连接数据库所需要的数据都存入其中,如图所示
文件内所存信息:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mysql_zyd?useUnicode=ture&chacarterEncoding=UTF-8
user=root
password=root
保存后.properties文件就配置完成了。
第二步:
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
public class DButil {
/**
* 加载驱动
* 使用Properties类读取properties配置文件
* 1)创建Properties类的对象
* 2)使用Properties中的load的方法读取配置文件
*/
private static Properties p=new Properties();
private static String driver;
private static String url;
private static String user;
private static String pwd;
static {
try {
//获取输入流
InputStream inStream=DButil.class.getClassLoader().getResourceAsStream("com/hyxy/jdbc2/db.properties");
//加载配置文件
p.load(inStream);
driver=p.getProperty("driver");
url=p.getProperty("url");
user=p.getProperty("user");
pwd=p.getProperty("password");
Class.forName(driver);
}catch(Exception e) {
e.printStackTrace();
}
}
/**
* 获取连接
*/
public static Connection getConnection() throws Exception{
Connection conn=DriverManager.getConnection(url,user,pwd);
return conn;
}
/**
* 无结果集关闭连接
*/
public void closeMysqlConnection(PreparedStatement ps,Connection conn) {
if(ps!=null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 有结果集关闭连接
*/
public void closeMysqlConnection(ResultSet rs,PreparedStatement ps,Connection conn) {
if(rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(ps!=null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
三、连接池:在每次使用增删改查操作时我们都需要使用DriverManager进行数据库的连接,连接后返回一个connection对象,在使用完成后再进行关闭,但是Connection接口的开关是极其耗费资源的,我们也称之为重型接口。为了解决这个问题,我们引入了连接池。什么是连接池?顾名思义,就是连接的池,也就是说里面有很多的连接,也就是说在程序开始之初就创建很多连接,当我们需要获取连接时,会从其中取出一个空闲连接来供我们使用。在我们使用完关闭后,就将我们占用的这个连接重新还给连接池,对于连接池来说就是一个重新将该连接置为空闲状态。这就解决了上述问题。而连接池是中连接是有数量的,我们可以进行设置,假设我们创建了100个连接,那么当101个人来获取连接时,以为连接池中没有空闲连接,所以系统会再创建100个连接,最多访问量也可以设置,假设设置最多访问量为1000,如果超过1000,当1001人来访问时,那么这地1001个人就需要等待。同时,连接池也用到.properties配置文件,并且需要多增两个参数,初始连接数initSize及最大活跃连接数maxActive。连接池有多种,在本例中使用的为jdbc连接池,需要导入jar包。
例三:
第一步:导入jar包并BuildPath
第二步:进行DBUtil类书写
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import org.apache.commons.dbcp.BasicDataSource;
public class DButil {
private static Properties prop=new Properties();
private static String driver;
private static String url;
private static String user;
private static String pwd;
private static String initSize;
private static String maxActive;
//数据库连接池对象
private static BasicDataSource bds=new BasicDataSource();
static {
try {
//1.读取配置文件
prop.load(DButil.class.getClassLoader().getResourceAsStream("com/hyxy/teacher/util/db.properties"));
//2.获取配置文件中的value值
driver=prop.getProperty("driver");
url=prop.getProperty("url");
user=prop.getProperty("user");
pwd=prop.getProperty("password");
initSize=prop.getProperty("initSize");
maxActive=prop.getProperty("maxActive");
//为bds的成员变量赋值
bds.setDriverClassName(driver);
bds.setUrl(url);
bds.setUsername(user);
bds.setPassword(pwd);
bds.setInitialSize(Integer.parseInt(initSize));
bds.setMaxActive(Integer.parseInt(maxActive));
//3.加载驱动
//Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws Exception{
Connection conn=bds.getConnection();
return conn;
}
public static void closeConnection(ResultSet rs,PreparedStatement ps,Connection conn) {
if(rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(ps!=null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void closeConnection(PreparedStatement ps,Connection conn) {
if(ps!=null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}