PersonDao pd=new PersonDao();
/*//调用insert方法时,需要的实参
Person p=new Person(1,“zhangsan”,20,“152226565”,“郑州市”);
Person p2=new Person(“lisi”,20,“152226565”,“郑州市”);
//调用pd对象的insert方法。
pd.insert§;*/
// List perList=pd.selectAll();
// for(Person p:perList){
// System.out.println(p.getName()+“=====”+p.getAge());
// }
// pd.delete(76);
// Person p=new Person(77,“wangwu”,21,“152226566”,“郑州市”);
// pd.update§;
Person p=pd.selectOne(77);
System.out.println(p.getName()+“\t”+p.getAge());
}
}
上面代码存在的问题:
1.dao类中的增删改查方法里面的代码的重复度非常高
2.每个方法开始都是要建立数据库连接
3.每个方法的结尾都是要释放资源。
4.我们要去除代码的重复度。
解决办法:
在dao类抽取两个方法。
Public Connection getConnection();
Public void closeAll(Connection conn,PreparedStatement ps,ResultSet rs);
这样,增删改查方法就可以重用上面两个方法的代码。
代码改进后又有新的问题:
1.后期项目复杂后,一个项目中对应多个表。
2.多个表就会有多个dao类
3.每个dao类中都需要数据库连接和释放资源。
4.因为刚才我们把建立连接和释放资源的代码封装到了PersonDao。那么其他的dao类调用这两个方法就非常麻烦。
为了解决上面的问题,我们可以把建立连接和释放资源这两个方法封装到一个公共的工具类中JdbcUtils.这个类为所有dao类服务。
因为getConnection方法和closeAll跟JdbcUtils的对象没有关系。我们就把这两个方法定义成静态方法。这样dao类在使用这个两个方法时,就可以直接使用类名调用,而不用创建JdbcUtils对象了。
Dao类做增删改查操作,JdbcUtils类和实体类协助dao。
虽然抽出来两个方法使得我们在开发的时候代码的重复度降低,但是现在项目还存在一个问题,就是加载驱动和创建数据库连接都是我们直接写死的,但是这些字符串常量是有可能要修改的。在真实运行环境中是没有源码的。没有源码就不能修改JdbcUtils类。
所以我们就可以把这些字符串常量抽取出来存放在一个文件中,然后每次读取的时候从这个文件中读取数据,这样就很好的解决了可以单独修改连接条件。
java Jdk中有一个类叫Properties。
1.他本身是一个map集合,可以存储数据。
2.他有load(Reader r);方法,该方法可以自动加载文本文件中的数据。
3.要使用文本文件中的数据时,可以调用getProperties(String)获取文本文件中的数据。
JdbcUtil类:
package com.macw.util;
import java.io.IOException;
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;
/**
-
@author 超伟
-
@2019年5月28日 下午1:51:58
-
@博客:https://blog.csdn.net/MacWx
*/
public class JdbcUtil {
public static final Properties prop = new Properties();
//把流操作提取到静态代码块里面。
static{
InputStream in = null;
//使用类加载读取jdbc.properties文件
in = JdbcUtil.class.getResourceAsStream(“/jdbc.properties”);
try {
//读取文件中的数据
prop.load(in);
Class.forName(prop.getProperty(“DriverClassName”));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException(e);
}finally{
if (in!=null) {
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
- @return Connection
*/
public static Connection getConnection(){
Connection conn = null;
try {
conn = DriverManager.getConnection(prop.getProperty(“url”),prop.getProperty(“username”),prop.getProperty(“password”));
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException(e);
}
return conn;
}
/**
-
@param conn
-
@param ps
-
@param rs
*/
public static void toClose(Connection conn,PreparedStatement ps,ResultSet rs){
try {
if (rs!=null) {
rs.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(ps!=null){
ps.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (conn!=null) {
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void toClose(Connection conn,PreparedStatement ps){
try {
if(ps!=null){
ps.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (conn!=null) {
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
优化JdbcUtils类
1.在src里面创建一个jdbc.properties文件。在src右键—》new—》file—>jdbc.propertis
2.在这个文件中去写键值对,键值之间用=隔开
DriverClassName=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:xe
username=hr
password=mcw
为什么要使用数据库连接池:
1.频繁建立连接和释放连接非常浪费资源。
2.可以把一些连接存储起来,有人需要使用时,就从里面获取空闲连接
怎么使用数据库连接池?
C3P0,DBCP,DRUID,JDNI
DRUID是阿里实现的一种数据库连接池技术。
1.导入druid的相关jar包
2.将druid内部使用的字符串常量配置到properties配置文件中。