一个JDBC访问oracle数据库表的例子,让你搞清三层架构与MVC框架模式之间的关系,以及满足设计原则的类的结构和各类的职责
Posted Java Old Man
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个JDBC访问oracle数据库表的例子,让你搞清三层架构与MVC框架模式之间的关系,以及满足设计原则的类的结构和各类的职责相关的知识,希望对你有一定的参考价值。
文章目录
问题描述
我们以访问oracl数据库的emp表为例,来对java对数据库的访问相关问题进行一下详细讨论。
我们需要完成的功能是可以通过命令控制台以及键盘输入,来实现对emp表的增,删,查,改等功能。
这里不讨论通过任何框架来实现数据库的访问,比如mybatis等。
但会考虑三层架构等设计问题。
类的设计
三层架构就是为了符合“高内聚,低耦合”思想,把各个功能模块划分为表示层(UI)、业务逻辑层(BLL)和数据访问层(DAL)三层架构,各层之间采用接口相互访问,并通过对象模型的实体类(Model)作为数据传递的载体。
从上图我们可以分析出,所需要的类有:
实体层(entity)
Emp类
Emp类,属业务实体类,因考虑到方便,实体类的名称与表的名称相一致。其属性与表中的字段一一对应,并有各属性的setter和getter方法。
所有实体类放在com.javaoldman.entity包中。
- emp表结构
名称 是否为空? 类型
------- -------- ----------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
- Emp类的定义
package com.javaoldman.entity;
public class Emp
private int empno;
private String ename;
private String job;
private int mgr;
private double sal;
private double comm;
private int deptno;
public int getEmpno()
return empno;
public String getEname()
return ename;
public String getJob()
return job;
public int getMgr()
return mgr;
public double getSal()
return sal;
public double getComm()
return comm;
public int getDeptno()
return deptno;
public void setEmpno(int empno)
this.empno = empno;
public void setEname(String ename)
this.ename = ename;
public void setJob(String job)
this.job = job;
public void setMgr(int mgr)
this.mgr = mgr;
public void setSal(double sal)
this.sal = sal;
public void setComm(double comm)
this.comm = comm;
public void setDeptno(int deptno)
this.deptno = deptno;
@Override
public String toString()
return "Emp" +
"empno=" + empno +
", ename='" + ename + '\\'' +
", job='" + job + '\\'' +
", mgr=" + mgr +
", sal=" + sal +
", comm=" + comm +
", deptno=" + deptno +
'';
数据访问层(DAO)
数据访问层实现对于数据库的具体操作,包括增删改查等。
但考虑到可能会连接不同的数据库类型,所以, 为了解除业务逻辑层与DAO层的耦合,将DAO层进行符合依赖倒置原则的设计。即分成DAO接口和DAO具体实现类两层。
同理,为了解除表示层对业务逻辑层的依赖,也将业务逻辑层分成接口和实现类两层。
EmpDao 接口
EmpDao接口,定义数据访问的方法。主要方法有:
- 查询所有emp记录
- 按empno查询emp记录
- 按empno删除emp记录
- 添加新的emp记录
- 按empno来更新emp记录
所有dao接口放在com.javaoldman.dao包内。
EmpDao代码:
package com.javaoldman.dao;
import com.javaoldman.entity.Emp;
import java.util.List;
public interface EmpDao
List<Emp> selectAllEmp();
Emp selectEmpByEmpno(int empno);
int deleteEmpByEmpno(int empno);
int insertEmp(Emp emp);
int updateEmp(Emp emp);
从接口方法的申明中可以看出,方法的入口参数以及返回值多是为Emp对象或集合,这也是将关系数据库中的表记录与实体对象进行映射的关键。这可以让业务逻辑层只面向对象,不需要面向数据库的细节。
JDBCUtil工具类
因为访问数据库,有许多的代码是重复的,包括数据库的驱动注册,连接对象等,还有数据库访问结束后的资源释放等。所以,可能定义一个工具类,来实现这些重复性的工作。比如直接获得一个连接对象,或直接释放数据库资源等。
这个类可以放在com.javaoldman.util包中
代码如下:
package com.javaoldman.util;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
/**
* JDBC工具类
*/
public class JDBCUtil
private static String driver;
private static String url;
private static String username;
private static String password;
//静态代码块,在程序编译的时候执行
static
try
//创建Properties对象
Properties p = new Properties();
//获取文件输入流
InputStream in = JDBCUtil.class.getResourceAsStream("/db.properties");
//加载输入流
p.load(in);
//获取数据库连接驱动名字
driver = p.getProperty("driver",null);
//获取数据库连接地址
url = p.getProperty("url",null);
//获取数据库连接用户名
username = p.getProperty("username",null);
//获取数据库连接密码
password = p.getProperty("password",null);
if(driver != null && url != null
&& username != null && password != null)
//加载驱动
Class.forName(driver);
catch (Exception e)
e.printStackTrace();
/**
* 获取连接对象
* @return Connection连接对象
*/
public static Connection getConn()
Connection conn = null;
try
conn = DriverManager.getConnection(url,username,password);
catch (SQLException e)
e.printStackTrace();
return conn;
/**
* 关闭连接(Connection连接对象必须在最后关闭)
* @param conn Connection连接对象
* @param st 编译执行对象
* @param rs 结果集
*/
public static void close(Connection conn, Statement st, ResultSet rs)
try
if(rs != null)
rs.close();
if(st != null)
st.close();
if(conn != null)
conn.close();
catch (SQLException e)
e.printStackTrace();
属性文件
数据库连接需要一些属性数据,比如URL,用户名,密码,还有驱动的类名等,为了让修改,可以将这些信息保存在一个属性文件中,方便修改。在工具类中,读取这个属性文件来设置相关的值。
在项目目录中创建一个properties的属性文件db.properties,里面定义了四行数据,分别对应着JDBC连接所需要的几个参数(注:Properties底层为一个Hashtable,配置文件中“=”之前的代表Map中的键,之后的代表相应键所对应的值)
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:orcl
username=scott
password=tiger
EmpDaoImpl实现类
EmpDaoImpl是对EmpDao接口的具体实现,分别实现接口中的所有方法。在该类中,实现具体的通过JDBC访问ORACLE数据库的相关操作。
该类放在com.javaoldman.dao.impl包中。
代码:
package com.javaoldman.dao.impl;
import com.javaoldman.dao.EmpDao;
import com.javaoldman.entity.Emp;
import com.javaoldman.util.JDBCUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class EmpDaoImpl implements EmpDao
@Override
public List<Emp> selectAllEmp()
Connection connection = JDBCUtil.getConn(); //通过工具类直接得到Connection对象
String sql = "select * from emp";
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
List<Emp> empList = new ArrayList<>();
try
preparedStatement = connection.prepareStatement(sql);
resultSet = preparedStatement.executeQuery();
while (resultSet.next())
Emp emp = new Emp();
emp.setEmpno(resultSet.getInt("empno"));
emp.setEname(resultSet.getString("ename"));
emp.setJob(resultSet.getString("job"));
emp.setMgr(resultSet.getInt("mgr"));
emp.setSal(resultSet.getDouble("sal"));
emp.setComm(resultSet.getDouble("comm"));
emp.setDeptno(resultSet.getInt("deptno")); //组装emp对象
empList.add(emp); //组装emp集合
catch (SQLException e)
e.printStackTrace();
finally
JDBCUtil.close(connection,preparedStatement,resultSet); //释放数据库资源
return empList; //返回emp集合
@Override
public Emp selectEmpByEmpno(int empno)
Connection connection = JDBCUtil.getConn(); //通过工具类直接得到Connection对象
String sql = "select * from emp where empno = ?";
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
List<Emp> empList = new ArrayList<>();
Emp emp = null;
try
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,empno);
resultSet = preparedStatement.executeQuery();
if (resultSet.next())
emp = new Emp();
emp.setEmpno(resultSet.getInt("empno"));
emp.setEname(resultSet.getString("ename"));
emp.setJob(resultSet.getString("job"));
emp.setMgr(resultSet.getInt("mgr"));
emp.setSal(resultSet.getDouble("sal"));
emp.setComm(resultSet.getDouble("comm"));
emp.setDeptno(resultSet.getInt("deptno")); //组装emp对象
catch (SQLException e)
e.printStackTrace();
finally
JDBCUtil.close(connection,preparedStatement,resultSet); //释放数据库资源
return emp; //如果有记录,就返回emp,否则返回null
@Override
public int deleteEmpByEmpno(int empno)
Connection connection = JDBCUtil.getConn(); //通过工具类直接得到Connection对象
String sql = "delete from emp where empno = ?";
PreparedStatement preparedStatement = null;
int num = 0;
try
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,empno);
num = preparedStatement.executeUpdate();
catch (SQLException e)
e.printStackTrace();
finally
JDBCUtil.close(connection,preparedStatement,null); //释放数据库资源,因为没有记录集对象,所以,用null
return num; //返回受影响的行数
@Override
public int insertEmp(Emp emp)
Connection connection = JDBCUtil.getConn(); //通过工具类直接得到Connection对象
int empno;
String ename;
String job;
int mgr;
double sal;
double comm;
int deptno;
empno = emp.getEmpno();
ename = emp.getEname();
job = emp.getJob();
mgr = emp.getMgr();
sal = emp.getSal();
comm = emp.getComm();
deptno = emp.getDeptno();
String sql = "insert into emp(empno,ename,job,mgr,sal,comm,deptno) values(?,?,?,?,?,?,?)";
PreparedStatement preparedStatement = null;
int num = 0;
try
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,empno);
preparedStatement.setString(2,ename);
preparedStatement.setString(3,job);
preparedStatement.setInt(4,mgr);
preparedStatement.setDouble(5,sal);
preparedStatement.setDouble(6,comm);
preparedStatement.setInt(7,deptno);
num = preparedStatement.executeUpdate();
catch (SQLException e)
e.printStackTrace();
finally
JDBCUtil.close(connection,preparedStatement,null); //释放数据库资源,因为没有记录集对象,所以,用null
return num; //返回受影响的行数
@Override
public int updateEmp(Emp emp)
Connection connection = JDBCUtil.getConn(); //通过工具类直接得到Connection对象
int empno;
String ename;
String job;
int mgr;
double sal;
double comm;
int deptno;
empno = emp.getEmpno();
ename = emp.getEname();
job = emp.getJob();
mgr = emp.getMgr以上是关于一个JDBC访问oracle数据库表的例子,让你搞清三层架构与MVC框架模式之间的关系,以及满足设计原则的类的结构和各类的职责的主要内容,如果未能解决你的问题,请参考以下文章