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.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配置文件中。
最后
看完美团、字节、腾讯这三家的面试问题,是不是感觉问的特别多,可能咱们又得开启面试造火箭、工作拧螺丝的模式去准备下一次的面试了。
开篇有提及我可是足足背下了1000道题目,多少还是有点用的呢,我看了下,上面这些问题大部分都能从我背的题里找到的,所以今天给大家分享一下互联网工程师必备的面试1000题。
注意不论是我说的互联网面试1000题,还是后面提及的算法与数据结构、设计模式以及更多的Java学习笔记等,皆可分享给各位朋友
互联网工程师必备的面试1000题
而且从上面三家来看,算法与数据结构是必备不可少的呀,因此我建议大家可以去刷刷这本左程云大佬著作的《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题。
ZG4ubmV0L01hY1d4,size_16,color_FFFFFF,t_70)
最后
看完美团、字节、腾讯这三家的面试问题,是不是感觉问的特别多,可能咱们又得开启面试造火箭、工作拧螺丝的模式去准备下一次的面试了。
开篇有提及我可是足足背下了1000道题目,多少还是有点用的呢,我看了下,上面这些问题大部分都能从我背的题里找到的,所以今天给大家分享一下互联网工程师必备的面试1000题。
注意不论是我说的互联网面试1000题,还是后面提及的算法与数据结构、设计模式以及更多的Java学习笔记等,皆可分享给各位朋友
[外链图片转存中…(img-LtJs8aXJ-1719252837224)]
互联网工程师必备的面试1000题
而且从上面三家来看,算法与数据结构是必备不可少的呀,因此我建议大家可以去刷刷这本左程云大佬著作的《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题。
[外链图片转存中…(img-1wM8Z7ZZ-1719252837225)]