本文是课上资料的总结非原创没有转载地址
目录
JDBC应用
回顾
1 JDBC介绍 :
Java Database Connectity java数据库连接技术
定义一套连接数据库的规范和标准。
2 JDBC包含两个部分
JDBC API 包括 DriverManger Driver Connection Statement ResultSet SQLException
JDBC 驱动程序 MySQL驱动程序 不同数据库厂商有不同的驱动程序
3 JDBC的使用步骤
1 导入驱动包 项目根目录下创建文件夹--->lib-->把数据库驱动文件jar包放在里面-->右键lib文件夹-->add as library
2 注册驱动 Class.forName();
3 获取连接 jdbc:mysql://localhost:3306/myschool root root
4 创建命令 statement
5 执行命令,处理结果 boolean execute(String sql); int executeUpdate(String sql);
ResultSet executeQuery(String sql)
6 释放资源 close. 按依赖顺序关闭!rs st conn
4 JDBC的api
Driver 驱动
DriverManager 驱动管理类
Connection 负责连接数据库
Statement 负责执行命令
ResultSet 封装结果集
PreparedStatment 预编译命令
今日内容
1、封装工具类
2、ORM封装
3、DAO模式
4、Druid连接池
第一节 封装工具类
DbUtils类功能:1 注册驱动 2 获取连接 3释放资源
1.1重用性方案:
/**
* 1 注册驱动
* 2 获取连接
* 3 释放资源
* @author gq
*
*/
public class DbUtils {
//驱动名称
static String driver="com.mysql.jdbc.Driver";
//url连接字符串
static String url="jdbc:mysql://localhost:3306/school";
//用户名
static String user="root";
//密码
static String password="root";
static {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
System.out.println("注册驱动失败");
}
}
/**
* 获取连接
* @return
*/
public static Connection getConnection() {
try {
return DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 释放资源
* @param rs
* @param stat
* @param conn
*/
public static void closeAll(ResultSet resultSet,Statement stat,Connection connection) {
try {
if (resultSet != null) {
resultSet.close();
}
if (stat != null) {
stat.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
1.2跨平台方案:
db.properties配置文件:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb3
user=root
password=1234
DBUtils类
/**
* 数据库相关的封装 获取连接 关闭连接
*/
public class DbUtils {
//1.声明属性。
private static String driver;
private static String url;
private static String user;
private static String password;
static {
try {
//通过类加载器,加载资源(配置文件)!
InputStream is = DbUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
//通过load方法,将配置文件资源加载到集合里
properties.load(is);
//获取集合里的键。对应的值是数据库连接的内容
driver = properties.getProperty("driver");
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("password");
//注册驱动
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//3.获取数据库连接对象的方法
public static Connection getConnection() {
try {
return DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
//4.关闭所有连接
public static void closeAll(ResultSet rs, Statement st, Connection conn) {
try {
if (rs != null) {
rs.close();
}
if (st != null) {
st.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
第二节 ResultSet查询封装
ORM(Object Relational Mapping)实体类(Entity):零散数据的载体。
在应用开发中,我们从数据库查询出的结果集(ResultSet)一般都需要取得(get)其中的数据然后存放到(set)实体对象(Entity)中,以便进一步的处理需要。常用也最容易理解的方式就是从ResultSet中get相应的字段值后调用实体对象的对应的属性的set方法,把值保存在实体对象中。
实体类:
package com.qf.www.entity;
import java.util.Date;
public class Emp {
private int empno;
private String ename;
private String job;
private int mgr;
private Date hiredate;
private double sal;
private double comm;
private int deptno;
public Emp() {
}
public Emp(int empno, String ename, String job, int mgr, Date hiredate, double sal, double comm, int deptno) {
this.empno = empno;
this.ename = ename;
this.job = job;
this.mgr = mgr;
this.hiredate = hiredate;
this.sal = sal;
this.comm = comm;
this.deptno = deptno;
}
@Override
public String toString() {
return "Emp{" +
"empno=" + empno +
", ename='" + ename + '\'' +
", job='" + job + '\'' +
", mgr=" + mgr +
", hiredate=" + hiredate +
", sal=" + sal +
", comm=" + comm +
", deptno=" + deptno +
'}';
}
public int getEmpno() {
return empno;
}
public void setEmpno(int empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public int getMgr() {
return mgr;
}
public void setMgr(int mgr) {
this.mgr = mgr;
}
public Date getHiredate() {
return hiredate;
}
public void setHiredate(Date hiredate) {
this.hiredate = hiredate;
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
public double getComm() {
return comm;
}
public void setComm(double comm) {
this.comm = comm;
}
public int getDeptno() {
return deptno;
}
public void setDeptno(int deptno) {
this.deptno = deptno;
}
}
//根据员工编号查询单个员工,查到就封装成对象,返回
public Emp getEmpByEmpNo(int empno) {
connection = DbUtils.getConnection();
String sql = "select * from emp where empno = ?";
try {
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, empno);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
int empno = resultSet.getInt("empno");
String ename = resultSet.getString("ename");
String job = resultSet.getString("job");
int mgr = resultSet.getInt("mgr");
Date hiredate = resultSet.getDate("hiredate");
double sal = resultSet.getDouble("sal");
double comm = resultSet.getDouble("comm");
int deptno = resultSet.getInt("deptno");
Emp emp = new Emp(empno, ename, job, mgr, hiredate, sal, comm, deptno);
return emp;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DbUtils.closeAll(resultSet, preparedStatement, connection);
}
return null;
}
总结:
- 将一行中多个零散数据进行整理。
- 通过Entity的规则将表中的数据进行对象的封装。
- 表名=类名;列名=属性名;提供各属性的get、set方法。
- 提供无参构造方法(视情况添加有参构造方法)。
第三节 DAO模式
3.1 工具类封装
案例实现:实现emp表的查询、添加、删除、修改
3.1.1 封装DbUtils
-
由于多个地方都需要使用数据库连接和释放,所以把功能封装到工具类中DbUtils
-
四个功能:1注册驱动 2 获取连接 3 释放资源
public class DbUtils {
private static String driver;
private static String url;
private static String user;
private static String password;
static{
try {
driver="com.mysql.jdbc.Driver";
url="jdbc:mysql://localhost:3306/mydb1";
user="root";
password="1234";
//加载驱动
Class.forName(driver);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 获取连接
* @return
* @throws SQLException
*/
public static Connection getConnection() throws SQLException{
return DriverManager.getConnection(url,user,password);
}
/**
* 释放资源
* @param rs
* @param stat
* @param conn
*/
public static void release(ResultSet resultSet,Statement stat,Connection conn){
try {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
1.1.2优化DbUtils工具类:把数据库连接信息封装到Properties文件中
项目下创建的db.properties error方式
src下创建db.properties could not initialize class com.qf.www.dbutils
Properties properties=new Properties();
InputStream is=DbUtils.class.getClassLoader().getResourceAsStream("database.properties");
properties.load(is);
//初始化参数
driver=properties.getProperty("driver");
url=properties.getProperty("url");
user=properties.getProperty("user");
password=properties.getProperty("password");
3.2 DAO设计模式
DAO(Database Access Object 数据库访问对象)
为了降低耦合性,提出了DAO封装数据库操作的设计模式。
它可以实现业务逻辑与数据库访问相分离。相对来说,数据库是比较稳定的,其中DAO组件依赖于数据库系统,提供数据库访问的接口,隔离了不同的数据库实现。
DAO模式的组成部分
- DAO接口(主要包含 添加 修改 查询 删除方法)
- DAO实现类
- 实体类 (domain、beans、entity、pojo、model)
- 作用:用在数据访问代码和业务逻辑代码之间通过实体类来传输数据
- 实体类特征:
- 属性一般使用private修饰
- 提供public修饰的getter/setter方法
- 实体类提供无参构造方法,根据业务提供有参构造
- 实现java.io.Serializable接口,支持序列化机制
- 数据库连接和关闭工具类
设计的包名 :
entity、存放实体类
utils 存放工具类
dao 存放接口
dao.impl 存放实现类
使用DAO设计模式实现emp表的查询、添加、删除、修改
Employee类
/**
* 员工类
* 实体类
* @author wgy
*
*/
public class Emp implements Serializable {
/**
*
*/
private static final long serialVersionUID = 373910607014836778L;
private int empno;
private String ename;
private String job;
private int mgr;
private Date hiredate;
private double sal;
private double comm;
private int deptno;
public Emp() {
// TODO Auto-generated constructor stub
}
public Emp(int empno, String ename, String job, int mgr, Date hiredate, double sal, double comm, int deptno) {
super();
this.empno = empno;
this.ename = ename;
this.job = job;
this.mgr = mgr;
this.hiredate = hiredate;
this.sal = sal;
this.comm = comm;
this.deptno = deptno;
}
public int getEmpno() {
return empno;
}
public void setEmpno(int empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public int getMgr() {
return mgr;
}
public void setMgr(int mgr) {
this.mgr = mgr;
}
public Date getHiredate() {
return hiredate;
}
public void setHiredate(Date hiredate) {
this.hiredate = hiredate;
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
public double getComm() {
return comm;
}
public void setComm(double comm) {
this.comm = comm;
}
public int getDeptno() {
return deptno;
}
public void setDeptno(int deptno) {
this.deptno = deptno;
}
@Override
public String toString() {
return "Employee [empno=" + empno + ", ename=" + ename + ", job=" + job + ", mgr=" + mgr + ", hiredate="
+ hiredate + ", sal=" + sal + ", comm=" + comm + ", deptno=" + deptno + "]";
}
}
接口:
public interface EmpDao {
//1查询
List<Emp> findAll();
//2更新
void update(Emp e);
//3删除
void delete(int empno);
//4添加
void add(Emp e);
}
实现类
public class EmpDaoImpl implements EmpDao{
Connection conn=null;
PreparedStatement pstat=null;
ResultSet rs=null;
@Override
public List<Emp> findAll() {
ArrayList<Emp> emps=new ArrayList<Emp>();
//1获取连接
try {
conn=DbUtils.getConnection();
pstat=conn.prepareStatement("select * from emp;");
rs=pstat.executeQuery();
while(rs.next()){
int empno=rs.getInt("empno");
String ename=rs.getString("ename");
String job=rs.getString("job");
int mgr=rs.getInt("mgr");
Date date=rs.getDate("hiredate");
double sal=rs.getDouble("sal");
double comm=rs.getDouble("comm");
int deptno=rs.getInt("deptno");
Emp emp=new Emp(empno, ename, job, mgr, date, sal, comm, deptno);
emps.add(emp);
}
return emps;
} catch (Exception e) {
throw new RuntimeException("查询emp失败");
} finally {
DbUtils.closeAll(rs, pstat, conn);
}
}
@Override
public void update(Emp emp) {
conn=DbUtils.getConnection();
String sql = "update emp set ename=?,job=?,mgr=?,hiredate=?,sal=?,comm=?,deptno=? where empno = ?";
try {
pstat = conn.prepareStatement(sql);
pstat.setObject(1,emp.getEname());
pstat.setObject(2,emp.getJob());
pstat.setObject(3,emp.getMgr());
pstat.setObject(4,emp.getHiredate());
pstat.setObject(5,emp.getSal());
pstat.setObject(6,emp.emp.getComm());
pstat.setObject(7,emp.getDeptno());
pstat.setObject(8,emp.getEmpno());
pstat.executeUpdate();
} catch (Exception e) {
throw new RuntimeException("修改emp失败");
}finally {
DbUtils.closeAll(rs, pstat, conn);
}
}
@Override
public void delete(int empno) {
conn=DbUtils.getConnection();
String sql = "delete from emp where empno = ?";
try {
pstat = conn.prepareStatement(sql);
pstat.setObject(1,empno);
pstat.executeUpdate();
} catch (Exception e) {
throw new RuntimeException("删除emp失败");
}finally {
DbUtils.closeAll(rs, pstat, conn);
}
}
@Override
public void add(Emp emp) {
conn=DbUtils.getConnection();
String sql = "insert into emp(empno,ename,job,mgr,hiredate,sal,comm,deptno) values(?,?,?,?,?,?,?,?)";
try {
pstat = conn.prepareStatement(sql);
pstat.setObject(1,emp.getEmpno());
pstat.setObject(2,emp.getEname());
pstat.setObject(3,emp.getJob());
pstat.setObject(4,emp.getMgr());
pstat.setObject(5,emp.getHiredate());
pstat.setObject(6,emp.getSal());
pstat.setObject(7,emp.emp.getComm());
pstat.setObject(8,emp.getDeptno());
pstat.executeUpdate();
} catch (Exception e) {
throw new RuntimeException("新增emp失败");
}finally {
DbUtils.closeAll(rs, pstat, conn);
}
}
}
第四节 Druid连接池
4.1为什么使用连接池
- 数据库连接池的发展:
用户每次请求都需要向数据库获得连接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长。假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出、宕机。
现流行的有:DBCP、C3P0、Druid等
- Druid特点:
Druid 是目前比较流行的高性能的,分布式列存储的OLAP框架(具体来说是MOLAP)。它有如下几个特点:
一. 亚秒级查询
druid提供了快速的聚合能力以及亚秒级的OLAP查询能力,多租户的设计,是面向用户分析应用的理想方式。
二.实时数据注入
druid支持流数据的注入,并提供了数据的事件驱动,保证在实时和离线环境下事件的实效性和统一性
三.可扩展的PB级存储
druid集群可以很方便的扩容到PB的数据量,每秒百万级别的数据注入。即便在加大数据规模的情况下,也能保证时其效性
四.多环境部署
druid既可以运行在商业的硬件上,也可以运行在云上。它可以从多种数据系统中注入数据,包括hadoop,spark,kafka,storm和samza等
五.丰富的社区
druid拥有丰富的社区,供大家学习
4.2 使用步骤
- 配置文件 database.properties:
#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/school
username=root
password=root
#<!-- 初始化连接 -->
initialSize=10
#最大连接数量
maxActive=50
#<!-- 最小空闲连接 -->
minIdle=5
#<!-- 超时等待时间以毫秒为单位 60000毫秒/1000等于60秒 -->
maxWait=5000
4.2.1 导入jar包
druid-1.1.5.jar
mysql驱动包
4.2.2 编写工具类
/**
* 阿里的数据库连接池
* 性能最好的
* Druid
* */
public class DbUtils {
//声明连接池对象
private static DruidDataSource ds;
static{
//实例化配置对象
Properties properties=new Properties();
try {
//加载配置文件内容
properties.load(DbUtils.class.getResourceAsStream("database.properties"));
ds = (DruidDataSource)DruidDataSourceFactory.createDataSource(properties);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//获取连接对象
public static Connection getConnection() {
try {
return ds.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
4.2.3 测试
package com.qf.utils;
import java.sql.Connection;
public class Test {
public static void main(String[] args) throws Exception {
for(int i=0;i<100;i++) {
Connection connection=DbUtils.getConnection();
if(connection!=null) {
System.out.println("连接成功"+i+"..."+connection.hashCode()+connection.toString());
}
connection.close();
}
}
}
作业题
1、实现一个学生管理系统,要求实现增删改查,基于控制台实现即可
要求可以对学生信息进行添加、修改、删除、查询的功能
面试题
1、什么是JDBC,在什么时候会用到它?
2、execute,executeQuery,executeUpdate的区别是什么?
3、JDBC的PreparedStatement是什么?
4、相对于Statement,PreparedStatement的优点是什么?
来源:CSDN
作者:慕兴
链接:https://blog.csdn.net/qq_42646672/article/details/103725951