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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis应用-哨兵模式以及缓存穿透雪崩解决方案

文章目录 Redis应用-哨兵模式以及缓存穿透雪崩哨兵模式Redis缓存穿透和雪崩缓存穿透布隆过滤器缓存空对象 缓存击穿设置热点数据永不过期加互斥锁 缓存雪崩Redis高可用限流降级数据预热 Redis应用-哨兵模式以及缓存穿透雪崩 哨兵模式 概述 主从切换技术的方法是&#xff1a;当…

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…

基于simulink的模糊PID控制器建模与仿真,并对比PID控制器

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1PID控制器原理 4.2 模糊PID控制器原理 5.完整工程文件 1.课题概述 在simulink&#xff0c;分别建模实现一个模糊PID控制器和一个PID控制器&#xff0c;然后将PID控制器的控制输出和模糊PID的控制输出…

[工具探索]Safari 和 Google Chrome 浏览器内核差异

最近有些Vue3的项目&#xff0c;使用了safari进行测试环境搞开发&#xff0c;发现页面存在不同程序的页面乱码情况&#xff0c;反而google浏览器没问题&#xff0c;下面我们就对比下他们之间的差异点&#xff1a; 日常开发google chrome占多数&#xff1b;现在主流浏览器 Goog…

双目模组 - IMSEE SDK的配置实践:含Opencv的详细编译配置

IMSEE 的环境要求: CMake(3.0以上)(需要支持vs2019) Visual Studio 2019 opencv3.3.1 IMSEE-SDK 官网参考: Windows 源码安装 — IMSEE SDK 1.4.2 文档 (imsee-sdk-docs.readthedocs.io) 【案】按照IMSEE的建议进行安装: 1 Windows 安装: 1.1 环境准备: 1.1.1 CMake:in…

当阿里云偶遇个人用户——谈幻兽帕鲁自建服

1. 快乐地闲谈 我擅长分析的云计算领域是“以工程师为操作用户的企业级IT服务”&#xff0c;但这篇文章讨论的对象甚至不是开发者用户&#xff0c;而是我从未设想过的“非IT用户”。 看到朋友转发《阿里云60秒部署幻兽帕鲁》的文章&#xff0c;我还想就是这能分析什么哪&#x…

结构体与共用体——C语言——day15

在C语言中&#xff0c;C语言允许用户自己指定这样一种数据结构&#xff0c;它称为结构体(structure) 。它相当于其他高级语言中的“记录”。 假设程序中要用到图所表示的数据结构&#xff0c;但是C语言没有提供这种现成的数据类型&#xff0c;因此用户必须要在程序中建立所需的…

C#——三角形面积公式

已知三角形的三个边&#xff0c;求面积&#xff0c;可以使用海伦公式。 因此&#xff0c;可以执行得到三角形面积公式的计算方法代码如下&#xff1a; /** / <summary>* / 三角形面积公式* / </summary>* / <param name"a">边长a</param>*…

[word] word艺术字体如何设置? #知识分享#职场发展#媒体

word艺术字体如何设置&#xff1f; 在工作中有些技巧&#xff0c;可以快速提高工作效率&#xff0c;解决大部分工作&#xff0c;今天给大家分享word艺术字体如何设置的技巧&#xff0c;希望可以帮助到你。 1、设置艺术字 选中文字&#xff0c;然后点击菜单栏的【插入】按钮一一…

版本管理工具git: 谨慎使用git中的撤回操作

文章目录 一、背景二、解决方案1、步骤一2、步骤二 三、参考 一、背景 昨天代码分支提交错了&#xff0c;idea中使用了如下操作&#xff0c;结果代码不见了 二、解决方案 1、步骤一 使用git reflog命令&#xff0c;查看提交记录&#xff0c;找到之前commit操作的哈希值 …

启动盘重装ubuntu22系统

win+R msinfo32查看 插入制作好的u盘电脑开机 进入BIOS界面的方法有多种,以下是一些常见的方法: 进入BIOS界面的最常见按键有: Del键:大多数台式机通过在启动时按下Del键来进入BIOS。Esc键:在AMI BIOS和某些品牌电脑中,进入BIOS系统需要按“Esc”键,一般在开机画面…

确认项目范围基准 常见的5大问题

确认项目范围基准的过程中&#xff0c;经常会遇到一些问题&#xff0c;如经常出现项目范围不明确、范围变更频繁等问题&#xff0c;往往会导致项目延期、超预算、质量下降等问题&#xff0c;严重的话可能会导致项目失败。 因此&#xff0c;我们在进行项目范围基准确认时&#x…

Centos慢慢长大(一)

1、写在前面 这将是一个系列性的文章。可能更多的是记录我在学习的过程中的一些感悟吧。我想强调的是在这一系列文章里我会从最小化的安装开始&#xff0c;然后逐渐的增加需要安装的软件。就象一个婴儿的诞生&#xff0c;慢慢的学走路、学说话、学使用筷子。。。。。。 这将是一…

不同生态系统蒸散发研究进展_刘超_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 存…

zookeeper(2) 服务器动态上下线监听和分布式锁案例

案例一&#xff1a;服务器动态上下线监听 某分布式系统中&#xff0c;主节点可以有多台&#xff0c;可以动态上下线&#xff0c;任意一台客户端都能实时感知 到主节点服务器的上下线。 1.服务端代码 package com.atguigu.case1;import org.apache.zookeeper.*;import java.io…

YOLOv8改进 | 损失函数篇 | 更加聚焦的边界框损失Focaler-IoU、InnerFocalerIoU(二次创新)

一、本文介绍 本文给大家带来的改进机制是更加聚焦的边界框损失Focaler-IoU已经我进行二次创新的InnerFocalerIoU同时本文的内容支持现阶段的百分之九十以上的IoU,比如Focaler-IoU、Focaler-ShapeIoU、Inner-Focaler-ShapeIoU包含非常全的损失函数,边界框的损失函数只看这一…

【每日一题】6.LeetCode——轮转数组

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》|《数据结构与算法》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有限&#xff0c;欢…

Spring Boot第一天

SpringBoot概述 Spring Boot是Spring提供的一个子项目&#xff0c;用于快速构建Spring应用程序 传统方式构建Spring应用程序 导入依赖繁琐 项目配置繁琐 为了简化如此繁琐的配置流程&#xff0c;SpringBoot这一子项目提供了如下特性 SpringBoot特性 起步依赖 本质上就是一个…

集显如何安装pytorch (CPU)

目录 前言1. 注意事项2. CPU版 前言 此为记录贴&#xff0c;原先都是独显&#xff0c;安装GPU&#xff0c;第一次查看发现是集显&#xff0c;没有配备的GPU 1. 注意事项 验证自身是否为独显&#xff1a;cmd下执行 DxDiag 如果Graphics则为集显&#xff0c;代表只能操作CPU模…

腾讯云幻兽帕鲁Palworld服务器价格表,2024年2月最新

腾讯云幻兽帕鲁服务器价格32元起&#xff0c;4核16G12M配置32元1个月、96元3个月、156元6个月、312元一年&#xff0c;支持4-8个玩家&#xff1b;8核32G22M幻兽帕鲁服务器115元1个月、345元3个月&#xff0c;支持10到20人在线开黑。腾讯云百科txybk.com分享更多4核8G12M、16核6…