PreparedStatement ps=null;
ResultSet rs=null;
try{
conn=JdbcUtils.getConnection();
//3.写sql
String sql=“insert into person values(person_seq.nextval,?,?,?,?)”;
//4.创建ps
ps=conn.prepareStatement(sql);
//5.给占位符赋值
ps.setString(1,p.getName());
ps.setInt(2,p.getAge());
ps.setString(3,p.getTel());
ps.setString(4,p.getAddress());
//6.执行
ps.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtils.closeAll(conn,ps,rs);
}
}
/**
-
根据id把数据库表里面对应的数据删除掉
-
@param id 要删除的数据的编号
*/
public void delete(int id){
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
try{
conn=JdbcUtils.getConnection();
//3.写sql
String sql=“delete from person where id=?”;
//4.创建ps
ps=conn.prepareStatement(sql);
//5.给占位符赋值
ps.setInt(1,id);
//6.执行
ps.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtils.closeAll(conn, ps, rs);
}
}
public void update(Person p){
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
try{
conn=JdbcUtils.getConnection();
//3.写sql
String sql=“update person set name=?,age=?,tel=?,address=? where id=?”;
//4.创建ps
ps=conn.prepareStatement(sql);
//5.给占位符赋值
ps.setString(1,p.getName());
ps.setInt(2,p.getAge());
ps.setString(3,p.getTel());
ps.setString(4,p.getAddress());
ps.setInt(5,p.getId());
//6.执行
ps.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtils.closeAll(conn,ps,rs);
}
}
public Person selectOne(int id){
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
Person p=null;
try{
conn=JdbcUtils.getConnection();
//3.写sql
String sql=“select * from person where id=?”;
//4.创建ps
ps=conn.prepareStatement(sql);
//5.执行
ps.setInt(1, id);
rs=ps.executeQuery();
if(rs.next()){
//获取表中每一个字段的值
String name=rs.getString(“name”);
int age=rs.getInt(“age”);
String tel=rs.getString(“tel”);
String address=rs.getString(“address”);
//把上面这些数据封装到person对象里面
p=new Person(id,name,age,tel,address);
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtils.closeAll(conn,ps,rs);
}
return p;
}
/*
- 到数据库里面把所有的person实体查询出来,封装到list集合,然后返回该list集合。
*/
public List selectAll(){
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
List perList=new ArrayList();
try{
conn=JdbcUtils.getConnection();
//3.写sql
String sql=“select * from person”;
//4.创建ps
ps=conn.prepareStatement(sql);
//5.执行
rs=ps.executeQuery();
while(rs.next()){
//获取表中每一个字段的值
int id=rs.getInt(“id”);
String name=rs.getString(“name”);
int age=rs.getInt(“age”);
String tel=rs.getString(“tel”);
String address=rs.getString(“address”);
//把上面这些数据封装到person对象里面
Person p=new Person(id,name,age,tel,address);
//把person放入list集合
perList.add§;
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtils.closeAll(conn,ps,rs);
}
return perList;
}
}
main, Test测试类:
package jdbc;
import java.util.List;
public class Test {
public static void main(String[] args) {
//实例化对象,才能调用该类里面的方法。
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.youkuaiyun.com/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();
}