JDBC - 结构优化1

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方法
}

表:

stuIdstuNamestuAgestuGenderstuAddressstuBorn
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("欢迎再次使用本系统...");}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/444463.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】类和对象(1)

上节我们学习了C入门的一些语法知识&#xff0c;这篇博客来学习类和this指针。 目录 面向过程和面向对象的初步认识 类的引入 类的定义 类的访问限定符及封装 访问限定符 封装 类的作用域 类的实例化 类对象大小 this指针 this指针特性 面向过程和面向对象的初步认识…

机器视觉对中小企业有哪些优势?

机器视觉是帮助机器处理流程的硬件和软件的组合。简而言之&#xff0c;硬件为机器提供了眼睛&#xff0c;软件为机器提供了大脑。因此&#xff0c;单调的任务被精确执行的机器人接管。 机器视觉的优点 高效、准确、节省资源 一方面&#xff0c;机器人比人类管理更多的工件&a…

UE4学习笔记 FPS游戏制作2 制作第一人称控制器

文章目录 章节目标前置概念Rotator与Vector&#xff1a;roll与yaw与pitch 添加按键输入蓝图结构区域1区域2区域3区域4 章节目标 本章节将实现FPS基础移动 前置概念 Rotator与Vector&#xff1a; Vector是用向量表示方向&#xff0c;UE中玩家的正前方是本地坐标系的(1,0,0)&…

小程序定制开发前,应该考虑些什么?

引言 在移动互联网时代&#xff0c;小程序已经成为许多企业和个人推广业务、提供服务的理想平台。然而&#xff0c;在进行小程序定制开发之前&#xff0c;开发者和业务方需要细致入微地考虑一系列关键因素&#xff0c;以确保最终的小程序既能满足用户需求&#xff0c;又能够顺…

(免费分享)基于springboot,vue疗养中心管理系统

前端&#xff1a;vueelementUI 技术&#xff1a;springbootmybatisredis 数据库&#xff1a;mysql 功能&#xff1a;系统管理、信息管理、膳食管理、护理管理、床位管理、后勤管理、费用管理等 获取完整源码&#xff1a; 大家点赞、收藏、关注、评论啦 、查看 &#x1f447;…

优思学院|如何评价质量经理这个角色?

简单来说&#xff0c;公司的成败已经取决于质量的水准。质量是任何公司的重要组成部分&#xff0c;无法保证商品质量的公司将很快失去信誉与消费者的认可&#xff0c;最终导致销售额直线下降。 所以&#xff0c;质量经理的意义首先体现在他们对于质量控制体系的建立和维护上。…

日志报错:Unexpected EOF read on the socket

记一次关于网关的问题及修复问题。 项目提测后&#xff0c;修改时web端页面出现502&#xff0c;查看后台服务日志发现&#xff1a; org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOExcept…

【Spark系列2】Spark编程模型RDD

RDD概述 RDD最初的概述来源于一片论文-伯克利实验室的Resilient Distributed Datasets&#xff1a;A Fault-Tolerant Abstraction for In-Memory Cluster Computing。这篇论文奠定了RDD基本功能的思想 RDD实际为Resilient Distribution Datasets的简称&#xff0c;意为弹性分…

使用 Docker 部署扫雷小游戏

1&#xff09;源码 介绍&#xff1a;扫雷游戏是一款经典的单人益智游戏&#xff0c;旨在通过揭示方块和避开地雷来展示玩家的逻辑思维和推理能力。 源码&#xff1a;saolei.zip 个人文件站&#xff1a;https://share.wuhanjiayou.cn/ 2&#xff09;部署 2.1&#xff09;安装…

【Axure教程0基础入门】02高保真基础

02高保真基础 1.高保真原型的要素 &#xff08;1&#xff09;静态高保真原型图 尺寸&#xff1a;严格按照截图比例&#xff0c;参考线 色彩&#xff1a;使用吸取颜色&#xff0c;注意渐变色 贴图&#xff1a;矢量图/位图&#xff0c;截取&#xff0c;覆盖等 &#xff08;…

7zip压缩包乱码问题

打开压缩包查看或解压时&#xff0c;发现其中的文件名显示乱码。 经网络搜索&#xff0c;判断是编码的问题。因为我OS是UTF-8&#xff0c;而压缩包编码是CP936。 解决方法只能用命令行&#xff0c;-mcp指定了code page&#xff1a; "c:\Program Files\7-Zip\7z.exe&quo…

[技术杂谈]nvidia-smi参数和显示信息解释

GPU&#xff1a;本机中的GPU编号&#xff0c;从0开始&#xff0c;上图为0&#xff0c;一块GPU Fan&#xff1a;风扇转速&#xff08;0%-100%&#xff09;&#xff0c;N/A表示没有风扇 Name&#xff1a;GPU名字/类型&#xff0c;上图为NVIDIA GeForce . . . Temp&#xff1a;GPU…