九、数据访问和 DAO 模式
9.1 Properties 配置文件
9.1.1 Properties 配置文件简介
- Java 中有一个比较重要的 Properties 类,可以读取 Java 配置文件
- 可以把常用的配置信息写在配置文件中,方便软件工程师进行维护和修改
- 即可以将操作数据库所用的服务器参数写入配置文件中
- Java 配置文件通常是扩展名为 .properties 的文件
- 文件中以 “键=值” 的格式存储数据
- 可以使用 “#” 添加注释
- 为数据库访问添加的配置文件会被命名为 datebase.properties
9.1.2 使用 Properties 配置文件的步骤
1. 添加 properties 文件
- 选中项目下的 src 文件并右击,在弹出的快捷键菜单中执行 “New-File” 命令
- 再打开的 “New File” 创建文件,后缀为 properties
2. 编辑配置文件
-
在 database.properties 文件中添加配置信息
-
在连接数据库时,可能会修改的部分时数据库驱动 (driver)、数据库连接 URL (url)、
连接数据库的用户名 (user) 和密码 (password)
-
按照 Properties 文件格式填写配置文件,如下
dirver=com.mysql.jdbc.Driver;
url=jdbc:mysql://localhost:3306/hospital?useUnicode=ture&characterEncoding=UTF-8
user=root
password=root
- 配置文件中的数据格式和 Java 中的 Map 结构相似,等号之前是 键、等号之后是指
- 配置文件当中,键应该唯一,但值可以不唯一
3. 读取配置信息
- 使用 java.util 包下的 Properties 类读取配置文件,Properties 类继承自 Hashtable 类
- Properties 类的常用方法
方法 | 描述 |
---|---|
String getProperty(String key) | 用指定的键在此属性列表中搜索属性,通过参数 key 得到其所对应的值 |
Object serProperty(String key,String value) | 通过调用基类 Hashtable 的 put() 方法设置键-值对 |
void load(InputStream inStream) | 从输入流中读取属性列表 (键和元素对),通过对指定文件进行装载获取 该文件中所有的键-值对 |
void clear() | 清除所装载的键-值对,该方法由基类 Hashtable 提供 |
9.1.3 使用 Properties 配置文件来配置文件的参数
- 编写一个 DBUtil 工具类,来方便以后数据库的连接
- 编写 inti() 方法,用来配置连接数据库的参数
public class DBUtil {
public static String driver;
public static String url;
public static String user;
public static String password;
//静态方法,创建该类时自动调用
static{
init();
}
//配置文件
public static void init(){
String file="database.properties";
InputStream in=DBUtil.class.getClassLoader().getResourceAsStream(file);
Properties ties=new Properties();
try {
ties.load(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
driver= ties.getProperty("driver");
url=ties.getProperty("url");
user=ties.getProperty("user");
password=ties.getProperty("password");
}
- 再次连接数据库时,则不需要在配置 driver 等参数,直接调用该类的静态变量即可
9.2 DAO 模式
9.2.1 DAO 模式 概念
- DAO(Data Access Object)数据访问对象。主要的功能就是用于进行数据操作的,在程序的标准开发架构中属于数据层的操作
- 方便在不同的数据库之间切换
- DAO 模式主要有三个参与者
- 数据访问对象接口: 定义在一个模型对象上要执行的标准操作
- 数据访问对象实体类:实现数据访问对象接口,负责从数据库等存储机制中获取数据
- 模型对象/数值对象:用来存储获取到的数据的类对象
- DAO模式的UML图
- 上图中,Student 为模型对象/数值对象(实体类)
- StudentDao 为数据访问对象接口,规定了对student类型的数据要进行那些操作
- StudentDaoImpl 是数据访问对象实体类的角色,具体实现了如何从数据库获取数据,来进行这些增删改查的操作
9.2.2 实体类
-
Entity(实体类)是在 Java 项目中,与数据表相对应的类
-
实体类特征
- 属性一般使用
private
修饰 - 提供public修饰的
getter/setter
方法 - 实体类提供无参构造方法,根据业务提供有参构造
- 实现
java.io.Serializable
接口,支持序列化机制,可以将该对象转换成字节序列而保存在磁盘上或在网络上传输
- 属性一般使用
-
操作数据库时,会将数据库中的实体及关系以实体类的方式组织起来
-
通常在 Java 工程中,创建一个名为 entity 的 Package 集合保存实体类
-
示例
以下表格为 patient 表中的字段,构造 patient 实体,实体类中的属性与 patient 表中的字段相对应
名 | 类型 | 长度 | 小数点 | 不是null | 虚拟 | 键 | 注释 |
---|---|---|---|---|---|---|---|
patientID | int | 4 | 0 | ☑ | □ | 主键 | 病人编号 |
password | varchar | 20 | 0 | ☑ | □ | 登录密码 | |
birthDate | date | 0 | 0 | □ | □ | 出生日期 | |
gender | varchar | 4 | 0 | ☑ | □ | 性别 | |
patirentName | varchar | 50 | 0 | ☑ | □ | 病人姓名 | |
phoneNum | varchar | 50 | 0 | □ | □ | 联系电话 | |
varchar | 70 | 0 | □ | □ | 邮箱 | ||
identityNum | varchar | 20 | 0 | □ | □ | 身份证号 | |
address | varchar | 255 | 0 | □ | □ | 地址 |
在 Java 项目中构造 patient 表的实体类
package cn.QiaoYun.entity;
/*
* 患者表
* */
public class Patient {
private int patientId;
private String password;
private String birthDate;
private String gender;
private String patientName;
private String phoneNum;
private String email;
private String identityNum;
private String address;
public int getPatientId() {
return patientId;
}
public void setPatientId(int patientId) {
this.patientId = patientId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getBirthDate() {
return birthDate;
}
public void setBirthDate(String birthDate) {
this.birthDate = birthDate;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getPatientName() {
return patientName;
}
public void setPatientName(String patientName) {
this.patientName = patientName;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getIdentityNum() {
return identityNum;
}
public void setIdentityNum(String identityNum) {
this.identityNum = identityNum;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Patient() {
}
public Patient(int patientId, String password, String birthDate, String gender, String patientName, String phoneNum, String email, String identityNum, String address) {
this.patientId = patientId;
this.password = password;
this.birthDate = birthDate;
this.gender = gender;
this.patientName = patientName;
this.phoneNum = phoneNum;
this.email = email;
this.identityNum = identityNum;
this.address = address;
}
@Override
public String toString() {
return "Patient{" +
"patientId=" + patientId +
", password='" + password + '\'' +
", birthDate='" + birthDate + '\'' +
", gender='" + gender + '\'' +
", patientName='" + patientName + '\'' +
", phoneNum='" + phoneNum + '\'' +
", email='" + email + '\'' +
", identityNum='" + identityNum + '\'' +
", address='" + address + '\'' +
'}';
}
}
9.2.3 实现 DAO 模式
- 实现 DAO 模式时,首先要定义统一的抽象 API ,将操作数据的代码抽象成接口,只需要调用这些代码就可以实现对数据的访问
- 接口创建完后,通常会创建新接口实现类,考虑不同数据库实现代码的差异性,可以定义实现类,如下
- 在编写实现类的时候,每个操作都需要进行数据库的连接,可以将连接数据库的这些操作,专门写到一个类当中,放到一个专门类---- BaseDao 中
- 同时,也可以在 BaseDao 中编写一种 增、删、改 通用操作,当需要进行操作时,传入不同的参数即可
9.2.4 DAO 模式总结
- DAO 模式的优势在于它实现了两次隔离
- 隔离了数据访问代码和业务逻辑代码,即代码耦合
- 隔离了不同数据库的实现。
- 典型 DAO 模式的主要部分
- 实体类:用于存放传输对象数据
- 数据库操作工具类:即 BaseDao 类,避免数据库连接和关闭代码的重复使用,方便进行修改
- DAO 接口:把对数据库的所有操作定义抽象方法,可以提供多种实现
- DAO 实现类:针对不同数据库给出 DAO 接口定义方法的具体实现
9.3 项目 包命名规范
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z69HuFkU-1679566464725)(assets/%E9%A1%B9%E7%9B%AE%E5%8C%85%E5%91%BD%E5%90%8D%E8%A7%84%E8%8C%83.png)]
9.2.4 DAO 模式总结
- DAO 模式的优势在于它实现了两次隔离
- 隔离了数据访问代码和业务逻辑代码,即代码耦合
- 隔离了不同数据库的实现。
- 典型 DAO 模式的主要部分
- 实体类:用于存放传输对象数据
- 数据库操作工具类:即 BaseDao 类,避免数据库连接和关闭代码的重复使用,方便进行修改
- DAO 接口:把对数据库的所有操作定义抽象方法,可以提供多种实现
- DAO 实现类:针对不同数据库给出 DAO 接口定义方法的具体实现