JDBC - 结构优化1

news2024/11/15 15:42:03

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.coloradmin.cn/o/1424095.html

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

相关文章

【51单片机系列】中断优先级介绍及使用

文章来源&#xff1a;《51单片机原理及应用&#xff08;第3版&#xff09;》5.4节。 51单片机采用了自然优先级和人工设置高、低优先级的策略。 当CPU处理低优先级中断&#xff0c;又发生更高级中断时&#xff0c;此时中断处理过程如下图所示。 一个正在执行的低优先级中断服…

Kotlin快速入门系列11

Kotlin的集合 集合类 Java类库有一套相当完整的容器集合类用来持有对象。跟Java一样&#xff0c;集合类存放的都是对象的引用&#xff0c;而非对象本身(我们经常说的集合指的是集合中对象的引用)&#xff0c;Kotlin的集合类是在Java的集合类库基础上进行的优化&#xff0c;新引…

-1- Python环境安装

1、Python安装 1.1、Windows安装Python 进入python官网&#xff1a;Welcome to Python.org点击 download——>all releases&#xff1b;建议选择3.7.2版本&#xff08;网页链接&#xff1a;Python Release Python 3.7.2 | Python.org&#xff09;&#xff1b;下拉&#xf…

【C++】默认成员函数

与普通成员函数差距较大&#xff0c;形式对于我们比较陌生&#xff0c;但这是语法&#xff0c;是我们是必须要掌握的。 目录 类的默认成员函数&#xff1a;构造函数&#xff1a;概念&#xff1a;语法&#xff1a;特性&#xff1a; 析构函数&#xff1a;概念&#xff1a;语法&a…

rp-bf:一款Windows下辅助进行ROP gadgets搜索的Rust库

关于rp-bf rp-bf是一款Windows下辅助进行ROP gadgets搜索的Rust库&#xff0c;该工具可以通过模拟Windows用户模式下的崩溃转储来爆破枚举ROP gadgets。 在很多系统安全测试场景中&#xff0c;研究人员成功劫持控制流后&#xff0c;通常需要将堆栈数据转移到他们所能够控制的…

Spark入门01-Spark简介

1 Spark是什么 Spark是用于大规模数据处理的统一分析引擎。对任意类型的数据进行自定义计算。 可以计算&#xff1a;结构化、非结构化&#xff0c;半结构化的数据结构&#xff0c;支持使用Python&#xff0c;Java&#xff0c;Scala、Sql语言开发应用程序计算数据。 计算框架&a…

一文掌握SpringBoot注解之@Configuration知识文集(1)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

不同生态系统蒸散发研究进展_刘超_2023

不同生态系统蒸散发研究进展_刘超_2023 摘要关键词 1 研究方法1.1 实测法1.1.1 蒸渗仪1.1.2 气孔计法1.1.3 化学示踪法1.1.4 大孔径闪烁仪1.1.5 涡动相关法 1.2 模型法1.2.1 水量平衡法1.2.2 波文比-能量平衡法1.2.3 遥感技术1.2.4 综合法和辐射法 2 研究展望2.1 研究进展2.2 存…

使用 Docker 部署扫雷小游戏

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

中科大计网学习记录笔记(一):Internet | 网络边缘

计算机网络 前言&#xff1a; 学习视频&#xff1a;中科大郑烇、杨坚全套《计算机网络&#xff08;自顶向下方法 第7版&#xff0c;James F.Kurose&#xff0c;Keith W.Ross&#xff09;》课程 该视频是B站非常著名的计网学习视频&#xff0c;但相信很多朋友和我一样在听完前面…

学习嵌入式第十五天之结构体

用变量a给出下面的定义 a) 一个整型数&#xff08;An integer&#xff09; //int a;b) 一个指向整型数的指针&#xff08;A pointer to an integer&#xff09; //int *a;c) 一个指向指针的的指针&#xff0c;它指向的指针是指向一个整型数&#xff08;A pointer to a poin…

通用CI/CD软件平台TeamCity全新发布v2023.11——增强Git托管平台的集成

TeamCity是一个通用的 CI/CD 软件平台&#xff0c;可以实现灵活的工作流、协作和开发做法。我们的解决方案将帮助在您的 DevOps 流程中成功实现持续集成、持续交付和持续部署。 TeamCity 2023.11正式版下载 TeamCity 2023.11 带来了矩阵构建和构建缓存等多项备受期待的功能&a…

Redis -- 单线程模型

失败是成功之母 ——法国作家巴尔扎克 目录 单线程模型 Redis为什么这么快 单线程模型 redis只使用一个线程&#xff0c;处理所有的命令请求&#xff0c;不是说redis服务器进场内部真的就只有一个线程&#xff0c;其实也有多个线程&#xff0c;那就是处理网络和io的线程。 R…

计算机设计大赛 深度学习 opencv python 实现中国交通标志识别_1

文章目录 0 前言1 yolov5实现中国交通标志检测2.算法原理2.1 算法简介2.2网络架构2.3 关键代码 3 数据集处理3.1 VOC格式介绍3.2 将中国交通标志检测数据集CCTSDB数据转换成VOC数据格式3.3 手动标注数据集 4 模型训练5 实现效果5.1 视频效果 6 最后 0 前言 &#x1f525; 优质…

【零基础学习CAPL】——CAN报文的发送(按下按钮同时周期性发送)

🙋‍♂️【零基础学习CAPL】系列💁‍♂️点击跳转 文章目录 1.概述2.面板创建3.系统变量创建4.CAPL实现4.1.函数展示4.2.全量报文展示5.效果1.概述 本章主要介绍使用CAPL和Panel在按下按钮时发送周期性CAN报文。 本章主要在“【零基础学习CAPL】——CAN报文的发送(配合P…

即时设计和xd对比有什么优势?

Adobe XD 是 Adobe 公司推出的用户体验设计工具主要用于创建和设计用户界面的原型和设计草案&#xff0c;如网站、移动应用程序和桌面应用程序。然而&#xff0c;由于其复杂的功能使用和全英文操作界面&#xff0c;许多设计师被说服离开。Adobe XD 这是一款价格相对较高的商业软…

【微服务】Spring Boot集成ELK实用案例

推荐一款我一直在用国内很火的AI网站&#xff0c;包含GPT3.5/4.0、文心一言、通义千问、智谱AI等多个AI模型&#xff0c;支持PC、APP、VScode插件同步使用&#xff0c;点击链接跳转->ChatGPT4.0中文版 一、前言 在现代软件开发中&#xff0c;微服务架构已成为一种流行趋势。…

Kafka运维相关知识

目录 一、基本概念 二、技术特性 三、设计思想 四、运维建议 一、基本概念 Apache kafka 是一个分布式的基于push-subscribe的消息系统&#xff0c;它具备快速、可扩展、可持久化的特点。它的最大的特性就是可以实时的处理大量数据以满足各种需求场景&#xff1a;比如基于h…

辽宁链家新房数据采集与可视化实现

摘 要 网络爬虫也叫做网络机器人&#xff0c;是一种按照一定的规则&#xff0c;自动地抓取网络信息&#xff0c;进行数据信息的采集与整理的程序或者脚本。随着海量数据的出现&#xff0c;如何快速有效的获取到我们想要的数据成为难题。以房源信息为例&#xff0c;该文使用Pyt…

【JAVE SE】---运算符和程序逻辑控制语句

1.运算符 算数运算符 - * / % 注意&#xff1a;1.Java的%符号左右两边可以是小数&#xff0c;也可以是负数 //运算符float a1.0f;float b2.0f;float c-1.5f;System.out.println(a%b); //1.0System.out.println(a%c); //1.0 2.Java中除数不可以为0&#xff0c…