JDBC - 结构优化1
文章目录
- JDBC - 结构优化1
- 三层架构
- 1 什么是三层架构
- 2 三层架构项目搭建
- 结构优化1 - 学生信息管理
- 1 封装工具类
- 2 ORM
- 3 DAO
三层架构
1 什么是三层架构
**三层架构:**将程序划分为表示层, 业务逻辑层, 数据访问层三层,各层之间采用接口相互访问,并通过实体类对象作为数据传递的载体。
- 表示(界面)层(User Interface Layer)。
- 业务逻辑(服务)层(Business Logic Layer)。
- 数据访问(持久)层(Data Access Layer)。
**调用关系:**表示层调用业务层,业务层调用数据访问层。
**目的:**是为了实现“高内聚低耦合”的思想。
2 三层架构项目搭建
开发步骤:
- util:存放工具类(DbUtils)
- entity:存放实体类(Book)
- dao:存放 DAO 接口(BookDao)
- impl:存放 DAO 接口实现类(BookDaoImpl)
- service:存放 Service 接口(BookService)
- impl:存放 service 接口实现类(PersonServiceImpl)
- view|ui:存放程序启动类(BookSystem
结构优化1 - 学生信息管理
1 封装工具类
优化1:
- 在JDBC的使用中,连接数据库、关闭连接等存在着大量的重复代码。
- 把传统的JDBC代码进行重构,抽取出通用的JDBC工具类。
重用性方案:
- 封装获取连接方法:
- public static Connection getConnection(){}
- 封装释放资源方法:
- public static void closeAll(Connection conn , Statement sm , ResultSet rs){}
代码演示:
public class DBUtils {
// 1 注册驱动
static { //静态代码块, 只执行一次
try {
// 获取驱动对象
Class.forName("com.mysql.jdbc.Driver");
} catch (Exception e) {
e.printStackTrace();
}
}
// 2 获取连接
public static Connection getConnection() {
Connection connection = null;
try {
connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/companydb?useSSL=false&characterEncoding=utf-8",
"root",
"1234"
);
} catch (SQLException e) {
throw new RuntimeException(e);
}
return connection;
}
// 3 释放资源
public static void closeAll(Connection connection, Statement statement, ResultSet resultSet) {
try {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
优化2:
- 重用性方案中的参数都是硬编码,当驱动、URL等参数需要更换时,需要重新编译。
- 通过配置文件读取配置信息,使用软编码方式,更灵活的方案。
跨平台方案:
- 创建properties配置文件。
- 创建Properties集合:
- public static final Properties prop = new Properties();
- 静态代码块中,使用输入流,读取配置文件。
代码演示:
DBUtils:
public class DBUtils {
private static String url;
private static String user;
private static String pwd;
// 1 注册驱动
static {
try {
// 读取属性配置文件
Properties properties = new Properties();
FileInputStream fis = new FileInputStream("Properties/db.properties");
properties.load(fis);
fis.close();
// 变量赋值
String driver = properties.getProperty("driver");
url = properties.getProperty("url");
user = properties.getProperty("user");
pwd = properties.getProperty("pwd");
// 获取驱动对象
Class.forName("com.mysql.jdbc.Driver");
} catch (Exception e) {
e.printStackTrace();
}
}
// 2 获取连接
public static Connection getConnection() {
try {
return DriverManager.getConnection(url,user,pwd);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
// 3 释放资源
public static void closeAll(Connection connection, Statement statement, ResultSet resultSet) {
try {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
db.properties:
driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/mysql?useSSL=false&characterEncoding=utf-8
user = root
pwd = 1234
2 ORM
概念:
- ORM(Object Relational Mapping): 对象关系映射
- 对结果集(ResultSet)遍历时, 取出的都是零散的数据
- 在实际开发中, 我们需要将零散的数据进行封装整理
实体类(Entity)
- 一行数据中, 多个零散的数据进行整理
- 通过entity的规则对表中的数据进行对象的封装
注意:
- 表名=类名; 列名=属性名; 提供个属性的getter和setter方法
- 提供无参构造方法(视情况添加有参构造)
- 包的命名: entity beans domian pojo…
代码演示:
public class Student {
private Integer stuId;
private String stuName;
private Integer stuAge;
private String stuGender;
private String stuAddress;
private Date stuBorn;
public Student() {
}
public Student(Integer stuId, String stuName, Integer stuAge, String stuGender, String stuAddress, Date stuBorn) {
this.stuId = stuId;
this.stuName = stuName;
this.stuAge = stuAge;
this.stuGender = stuGender;
this.stuAddress = stuAddress;
this.stuBorn = stuBorn;
}
//getter setter方法以及重写toString方法
}
表:
stuId | stuName | stuAge | stuGender | stuAddress | stuBorn |
---|---|---|---|---|---|
1 | 张三 | 24 | 男 | 北京 | 2000-1-1 |
2 | 李四 | 25 | 男 | 哈尔滨 | 1999-1-1 |
实体类与表一一对应:
- 属性 = 列名。
- 属性类型 = 列的类型。
- 提供构造方法、get/set方法。
3 DAO
概念:
- DAO(Data Access Object): 数据访问对象
- DAO实现了用户交互或业务逻辑与数据库访问相分离, 提高代码的重用性
- 对同一张表的所有操作都封装在 XxxDaoImpl对象中
- 根据增删改查提供具体的方法(Insert UPdate Delete Select SelectAll)
代码演示:
Dao接口
public interface StudentDao {
void insert(Student student);
void update(Student student);
void delete(int stuId);
List<Student> selectAll();
}
DaoImpl实现类
public class StudentDaoImpl implements StudentDao {
@Override
// 1 添加数据
public void insert(Student student) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
// 1 获取连接
connection = DBUtils.getConnection();
// 2 创建预编译命令
String sql = "INSERT INTO companydb.student VALUES (NULL,?,?,?,?,?)";
preparedStatement = connection.prepareStatement(sql);
// 3 参数赋值
preparedStatement.setObject(1,student.getStuName());
preparedStatement.setObject(2,student.getStuAge());
preparedStatement.setObject(3,student.getStuGender());
preparedStatement.setObject(4,student.getStuAddress());
preparedStatement.setObject(5,student.getStuBorn());
// 4 执行命令
preparedStatement.executeUpdate();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
//5 关闭
DBUtils.closeAll(connection,preparedStatement,null);
}
}
@Override
// 2 修改数据
public void update(Student student) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
// 1 获取连接
connection = DBUtils.getConnection();
// 2 创建预编译命令
String sql = "UPDATE companydb.student SET stu_name=?,stu_age=?,stu_gender=?,stu_address=?,stu_born=? where stu_id=?";
preparedStatement = connection.prepareStatement(sql);
// 3 参数赋值
preparedStatement.setObject(1,student.getStuName());
preparedStatement.setObject(2,student.getStuAge());
preparedStatement.setObject(3,student.getStuGender());
preparedStatement.setObject(4,student.getStuAddress());
preparedStatement.setObject(5,student.getStuBorn());
preparedStatement.setObject(6,student.getStuId());
// 4 执行命令
preparedStatement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
//5 关闭
DBUtils.closeAll(connection,preparedStatement,null);
}
}
@Override
// 3 删除
public void delete(int stuId) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
// 1 获取连接
connection = DBUtils.getConnection();
// 2 创建预编译命令
String sql = "DELETE FROM companydb.student WHERE stu_id = ?";
preparedStatement = connection.prepareStatement(sql);
// 3 参数赋值
preparedStatement.setObject(1, stuId);
// 4 执行命令
preparedStatement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
//5 关闭
DBUtils.closeAll(connection, preparedStatement, null);
}
}
@Override
// 4 查询
public List<Student> selectAll() {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
ArrayList<Student> list = new ArrayList<>();
try {
// 1 获取连接
connection = DBUtils.getConnection();
// 2 创建预编译命令
String sql = "SELECT * FROM companydb.student";
preparedStatement = connection.prepareStatement(sql);
// 3 执行命令
resultSet = preparedStatement.executeQuery();
// 4 处理
while (resultSet.next()) {
int stuId = resultSet.getInt("stu_id");
String stuName = resultSet.getString("stu_name");
int stuAge = resultSet.getInt("stu_age");
String stuGender = resultSet.getString("stu_gender");
String stuAddress = resultSet.getString("stu_address");
java.sql.Date stuBorn = resultSet.getDate("stu_born");
Student student = new Student(stuId, stuName, stuAge, stuGender, stuAddress, stuBorn);
list.add(student);
}
System.out.println();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
// 5 关闭
DBUtils.closeAll(connection,preparedStatement,resultSet);
}
return list;
}
}
MyStudentSystem:
public class MyStudentSystem {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//菜单
boolean flag = true;
StudentDao studentDao = new StudentDaoImpl();
do {
System.out.println("1.添加 2.修改 3.删除 4.查询全部数据 0.退出");
System.out.println("请选择...");
int choose = scanner.nextInt();
switch (choose) {
case 1:
try {
studentDao.insert(new Student(0,"刘禅",5,"男","哈尔滨",new Date()));
System.out.println("添加成功...");
} catch (Exception e) {
System.out.println("添加失败...");
}
break;
case 2:
try {
studentDao.update(new Student(108,"光头强",18,"男","东北",new Date()));
System.out.println("修改成功...");
} catch (Exception e) {
System.out.println("修改失败...");
}
break;
case 3:
System.out.println("请输入要删除的学生的stu_id");
int stu_id = scanner.nextInt();
try {
studentDao.delete(stu_id);
System.out.println("删除成功...");
} catch (Exception e) {
System.out.println("删除失败...");
}
break;
case 4:
try {
List<Student> students = studentDao.selectAll();
for (Student student : students) {
System.out.println(student.toString());
}
} catch (Exception e) {
System.out.println("查询失败...");
}
break;
case 0:
flag = false;
break;
default:
System.out.println("非法输入...");
}
} while (flag);
System.out.println("欢迎再次使用本系统...");
}
}