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.mzph.cn/news/660891.shtml

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

相关文章

vit细粒度图像分类(七)TBNet学习笔记

1.摘要 细粒度鸟类图像识别致力于实现鸟类图像的准确分类&#xff0c;是机器人视觉跟踪中的一项基础性工作。鉴于濒危鸟类的监测和保护对保护濒危鸟类具有重要意义&#xff0c;需要采用自动化方法来促进鸟类的监测。在这项工作中&#xff0c;我们提出了一种新的基于机器人视觉…

代码随想录算法训练营29期|day36任务以及具体安排

第八章 贪心算法 part05 435. 无重叠区间 class Solution {public int eraseOverlapIntervals(int[][] intervals) {Arrays.sort(intervals, (a,b)-> {return Integer.compare(a[0],b[0]);});if(intervals.length 1) return 0;int result 0;for(int i 1 ; i < interva…

新概念英语第二册(49)下

【Key structures】 复合句的语序 复合句可用两种方法构成&#xff1a;一是用连词把从句与主句连接起来&#xff1b;二是用分词结构或不定式。 1、用连词连接的复合句 ① 在复合句中&#xff0c;从句可以是名词从句&#xff08;即起名词的作用&#xff09;。在句子中&#xf…

分布式事务(三)—— 两阶段提交解决方案(2PC)

系列目录&#xff1a; 《分布式事务&#xff08;一&#xff09;—— 事务的基本概念》 《分布式事务&#xff08;二&#xff09;—— CAP和Base理论》 一、常见分布式事务解决方案 两阶段提交&#xff08;2PC&#xff0c;Two-phase Commit&#xff09;TCC补偿模式基于本地消…

SQL 快速参考手册

SQL 语句语法AND / ORSELECT column_name(s) FROM table_name WHERE condition AND|OR conditionALTER TABLEALTER TABLE table_name ADD column_name datatype 或者&#xff1a; ALTER TABLE table_name DROP COLUMN column_name AS (alias)SELECT column_name AS column_alia…

springboot mybatis-plus 项目分层笔记

整体定义 config: 配置项&#xff0c;包含configuration注解 constants: 常量类enums: 枚举 exceptions: 全局异常处理&#xff0c;自定义异常&#xff0c;RestControllerAdvice 注解 fia3: 三大器依据执行顺序&#xff1a;过滤器filter、拦截器interceptor、切面aop 简称 fia…

考研经验总结——政治篇

文章目录 一、前言二、学习情况三、最后 一、前言 不要提前&#xff0c;不要提前&#xff0c;不要提前&#xff0c; 我曾在暑假的时候上了7天左右的政治课&#xff0c;讲真话是很有趣的&#xff0c;并且对于自身的世界观、人生观和价值观的改善也是相当不错的&#xff0c;把我…

算法设计与分析实验:快速选择与单调栈

目录 一、找到K个最接近的元素 1.1 具体思路 1.2 思路展示 1.3 代码实现 1.4 复杂度分析 1.5 运行结果 二、前K个高频元素 2.1 思路一&#xff1a;哈希表 2.2 思路二&#xff1a;快速选择 2.3 思路三&#xff1a;堆 三、柱形图中的最大矩形 3.1 具体思路 3.2 思路…

Mysql单行函数练习

数据表 链接&#xff1a;https://pan.baidu.com/s/1dPitBSxLznogqsbfwmih2Q 提取码&#xff1a;b0rp --来自百度网盘超级会员V5的分享 单行函数练习 单行函数(一行数据返回一个结果) #1.显示系统时间(注:日期时间) #2.查询员工工号,姓名,工资以及提高百分之20后的结果(new…

2024年Java SpringBoot 计算机软件毕业设计题目推荐

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行交流合作✌ 主要内容&#xff1a;SpringBoot、Vue、SSM、HLM…

Flume搭建

压缩包版本&#xff1a;apache-flume-1.9.0-bin.tar 百度盘链接&#xff1a;https://pan.baidu.com/s/1ZhSiePUye9ax7TW5XbfWdw 提取码&#xff1a;ieks 1.解压 tar -zxvf /opt/software/apache-flume-1.9.0-bin.tar.gz -C /opt/module/ 2. 修改文件名 [rootbigdata1 opt]…

【stm32】hal库学习笔记-FSMC连接TFT_LCD

【stm32】hal库学习笔记-FSMC连接TFT LCD 触摸屏结构与原理 LCD模块接口原理图 LCD 接口连接在 FSMC 总线上面&#xff0c;图中的 T_MISO/T_MOSI/T_PEN/T_SCK/T_CS 连接在 MCU 的 PB2/PF11/PB1/PB0/PC13 上&#xff0c;这些信号用来实现对液晶触摸屏的控制&#xff08;支持电阻…

RHCE DNS域名解析服务器

目录 1. 正向解析 1.1 安装必要软件 1.2 配置静态ip 1.3 DNS配置 1.4 测试 2. 反向解析 2.1 关闭安全软件&#xff0c;安装必要软件 2.2 配置静态ip 2.3 DNS配置 2.4 测试 1. 正向解析 1.1 安装必要软件 1.2 配置静态ip 服务器配置 nmcli c modify ens32 ipv4.method man…

Unity中常见的单词

前言 unity中常见的单词学习积累 一.常用的基础词。 new:新建; as:像。。一样; null:对象空值; void:函数返回空值; switch:开关; abstract:抽象的; event:事件&#xff1b; return:返回; class:类; …

如何使用 Mermaid、GitHub 和 VSCode 用代码创建关系图三

Mermaid 系列 如何使用 Mermaid、GitHub 和 VSCode 用代码创建关系图一如何使用 Mermaid、GitHub 和 VSCode 用代码创建关系图二 1.如何创建甘特图 Gantt 甘特图以条形图的形式用作可视化表示。它有效地展示了项目的时间表&#xff0c;揭示了各个项目组件完成所需的持续时间…

leetcode刷题(剑指offer) 509.斐波那契数

509.斐波那契数 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;其中 n…

Java玩转《啊哈算法》排序综合篇之小哼买书

是诸法空相&#xff0c;不生不灭&#xff0c;不垢不净&#xff0c;不增不减 非目录 缘起代码地址案例桶排序冒泡排序快速排序 缘起 各位大哥大姐&#xff0c;兄弟姐妹们好呀&#xff01;本人最近看了下《啊哈算法》&#xff0c;说来惭愧&#xff0c;买几年了&#xff0c;当初看…

Office提取某一页转成图片

目录结构 前言支持的文件格式代码整理maven依赖文本文档解析转换电子表格解析转换演示文档解析转换PDF解析转换小编代码整理(完整版)特别感谢扩展前言 近期公司需求,要将office文件提取第一页内容转成图片;一番调查后整理如下: 支持的文件格式 文本文档电子表格演示文档…

Java 数据结构篇 二叉树与红黑树详细讲解通俗易懂

二叉树&#xff08;Binary Tree&#xff09; 二叉树&#xff08;Binary Tree&#xff09; 二叉树是一种特殊的树形数据结构&#xff0c;其中每个节点最多有两个子节点&#xff0c;分别称为左子节点和右子节点。二叉树可以是空的&#xff0c;也可以是由根节点以及左右两个子树…

python 读图片封装

python 读图片封装 支持 视频&#xff0c;图片文件夹&#xff0c;图片 2024.02.01更新 安装依赖项&#xff1a;pip install natsort #-*-coding:utf-8-*- import os.path from natsort import natsorted import cv2class ImgReader:def __init__(self, source, typemp4):if …