10-10 分层模式

news2025/2/22 19:48:32

Dao模式

程序员写的是业务(因为其逻辑性不太强)

软件设计原则:开闭原则,对新增加的进行开放,对修改关闭

实际开发中, web项目, 程序员编写业务代码

把所有的代码都写在业务方法中:

  • 接收前端请求,获取请求参数…

  • 编写业务代码处理请求

  • 调用jdbc代码操作数据

  • 把数据进行加工

  • 把数据响应给前端

缺点:

  1. 方法很臃肿, 这个方法不便于复用, 部分重复代码重复写

  2. 方法的扩展性不好, 因为代码全部集中在一个方法内部, 替换某部分的代码,对这个方法进行修改

解决方案: 拆的思想

  1. 把方法拆分为多个方法, 不是OOP编程思想

  2. 把方法拆分为多个方法,把这个方法分类, 把不同功能的方法放在不同的类, 不同层次的类在进行分层(包)

常见的分层:

操作数据库的层: DAO层(数据访问层)

业务处理的层: service层(业务层)

表对应实体类层: 实体层(entity,pojo)

工具类存放的层: 工具层(util)

处理前端请求层: web层

分层的目的:

  1. 使用层来技术隔离, 方便每一层的技术替换,而不需要修改其他层

  2. 使用层来进行解耦, 每一层直接的调用, 以接口的形式

  1. 上下层之分, 上层调用下层,不能下层调用上层,不能跨层调用

使用dao模式开发:

  1. 编写实体类, 与数据库的表一一对应

    类与表对应

    一行记录对应类的一个对象

    表的字段对应类的属性

    数据库的数据类型与java的数据类型对应 java推荐使用包装类型

    mysqljava
    intInteger/int
    bigintLong/long
    doubleDouble/double
    decimaljava.math.BigDecimal /Double
    char/varchar/textString
    date/datetime/time/timestampjava.util.Date
    tinyintInteger/int/Boolean

package com.fs.soso.entity;
​
/**
 * 对应tb_card表的实体类
 */
public class Card {
   private Integer id;
   private String cardNumber;
   private Integer status;
​
   //get/set  toString
​
​
    public Integer getId() {
        return id;
    }
​
    public void setId(Integer id) {
        this.id = id;
    }
​
    public String getCardNumber() {
        return cardNumber;
    }
​
    public void setCardNumber(String cardNumber) {
        this.cardNumber = cardNumber;
    }
​
    public Integer getStatus() {
        return status;
    }
​
    public void setStatus(Integer status) {
        this.status = status;
    }
​
    @Override
    public String toString() {
        return "Card{" +
                "id=" + id +
                ", cardNumber='" + cardNumber + '\'' +
                ", status=" + status +
                '}';
    }
​
    public Card() {
    }
​
    public Card(Integer id, String cardNumber, Integer status) {
        this.id = id;
        this.cardNumber = cardNumber;
        this.status = status;
    }
​
    public Card(String cardNumber, Integer status) {
        this.cardNumber = cardNumber;
        this.status = status;
    }
}
​
  1. 编写dao接口,以及dao接口的实现类

    实体类–> 实体类dao接口 –> 实体类dao实现类–> 实体类业务接口 –> 实体类业务接口实现类

    Card –> [I]CardDao –> CardDaoImpl –> [I]CardService–> CardServiceImpl

    package com.fs.soso.dao;
    ​
    import com.fs.soso.entity.Card;
    ​
    import java.util.List;
    ​
    /**
     * 卡的数据访问接口
     * CURD
     */
    public interface CardDao {
        /**
         * 添加记录
         * @param card  手机卡对象
         * @return 受影响行数
         */
        int add(Card card);
    ​
        /**
         * 根据主键修改
         * @param card  手机卡对象
         * @return 受影响行数
         */
        int updateById(Card card);
    ​
        /**
         * 根据主键删除
         * @param id 主键值
         * @return 受影响行数
         */
        int deleteById(int id);
    ​
    ​
        /**
         * 根据主键查询
         * @param id 主键
         * @return 手机卡对象
         */
        Card queryById(int id);
    ​
    ​
        /**
         * 查询所有
         * @return 手机卡List集合
         */
        List<Card> queryAll();
    }
    ​
package com.fs.soso.dao.impl;
​
import com.fs.soso.dao.CardDao;
import com.fs.soso.entity.Card;
import com.fs.soso.util.JdbcUtil;
​
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
​
public class CardDaoImpl implements CardDao {
    @Override
    public int add(Card card) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = JdbcUtil.getConnection();
            String sql ="insert into tb_card(cardNumber,status) values(?,?)";
            pstmt = conn.prepareStatement(sql);
            pstmt.setObject(1,card.getCardNumber());
            pstmt.setObject(2,card.getStatus());
            return pstmt.executeUpdate();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            JdbcUtil.close(conn,pstmt,null);
        }
        return 0;
    }
​
    @Override
    public int updateById(Card card) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = JdbcUtil.getConnection();
            String sql ="update tb_card set status = ? where id = ? ";
            pstmt = conn.prepareStatement(sql);
            pstmt.setObject(1,card.getStatus());
            pstmt.setObject(2,card.getId());
            return pstmt.executeUpdate();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            JdbcUtil.close(conn,pstmt,null);
        }
        return 0;
    }
​
    @Override
    public int deleteById(int id) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = JdbcUtil.getConnection();
            String sql ="delete from tb_card where id = ? ";
            pstmt = conn.prepareStatement(sql);
            pstmt.setObject(1,id);
            return pstmt.executeUpdate();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            JdbcUtil.close(conn,pstmt,null);
        }
        return 0;
    }
​
    @Override
    public Card queryById(int id) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet resultSet = null;
        try {
            conn = JdbcUtil.getConnection();
            String sql ="select * from  tb_card  where id = ? ";
            pstmt = conn.prepareStatement(sql);
            pstmt.setObject(1,id);
            resultSet = pstmt.executeQuery();
            Card card=null;
            while(resultSet.next()){
                card = new Card();
                //给属性赋值
                //getXxx(int 列的序号从1开始)
                //getXxx(String 列名)  可读性高
                card.setId(resultSet.getInt("id"));
                card.setCardNumber(resultSet.getString("cardNumber"));
                card.setStatus(resultSet.getInt("status"));
            }
            return card;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            JdbcUtil.close(conn,pstmt,null);
        }
        return null;
    }
​
    @Override
    public List<Card> queryAll() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet resultSet = null;
        try {
            conn = JdbcUtil.getConnection();
            String sql ="select * from  tb_card";
            pstmt = conn.prepareStatement(sql);
            resultSet = pstmt.executeQuery();
            List<Card> cards = new ArrayList<>();
            while(resultSet.next()){
                Card card = new Card();
                //给属性赋值
                card.setId(resultSet.getInt("id"));
                card.setCardNumber(resultSet.getString("cardNumber"));
                card.setStatus(resultSet.getInt("status"));
                //把对象添加到集合中
                cards.add(card);
            }
            return cards;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            JdbcUtil.close(conn,pstmt,null);
        }
        return null;
    }
}
​

junit进行单元测试

对编写方法进行测试, 实际开发中,使用junit进行单元测试

使用步骤:

  1. 导入junit依赖

2.创建存放测试源代码的资源目录

项目完成之后, 删除测试代码

创建存放测试代码的资源目录 test

  1. 根据被测试的类(接口),生成对应的测试类

  1. 编写测试代码

  package com.fs.soso.dao;
​
  import com.fs.soso.dao.impl.CardDaoImpl;
  import com.fs.soso.entity.Card;
  import org.junit.After;
  import org.junit.Before;
  import org.junit.Test;
​
  import static org.junit.Assert.*;
​
  public class CardDaoTest {
      private CardDao cardDao;
​
      /**
       * setUp() 使用 before修饰的, 表示该方法在调用测试方法之前执行
       * 做准备工作
       * @throws Exception
       */
      @Before
      public void setUp() throws Exception {
          //System.out.println("setUp...");
          cardDao = new CardDaoImpl();
      }
​
      /**
       * tearDown() 使用 After修饰的, 表示该方法在调用测试方法之后执行
       * 释放资源
       * @throws Exception
       */
      @After
      public void tearDown() throws Exception {
          //System.out.println("tearDown...");
      }
​
      /**
       *  @Test 标记方法上,表示这个方法是一个测试方法
       *    直接运行测试方法,不需要main调用
       *  测试方法要求:
       *   1. 返回值类型只能是void
       *   2. 一定是无参方法
       *   3.不能是static修饰
       */
      @Test
      public  void add() {
          //System.out.println("add...");
          Card card = new Card("16666666666",0);
          int rs =  cardDao.add(card);
          System.out.println(rs);
      }
​
      @Test
      public void updateById() {
          Card card = new Card(12,"16666666666",1);
          cardDao.updateById(card);
      }
​
      @Test
      public void deleteById() {
      }
​
      @Test
      public void queryById() {
          System.out.println(cardDao.queryById(12));
      }
​
      @Test
      public void queryAll() {
          System.out.println(cardDao.queryAll());
      }
  }

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

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

相关文章

小米澎湃OS发布,雷军小米的“统一”大棋局

千呼万唤始出来。2023年10月26日&#xff0c;小米澎湃OS终于揭开面纱。 雷军在主题为“跨越时刻”的发布会上&#xff0c;正式发布了小米澎湃OS。面对这款历时七年打造的全新操作系统&#xff0c;雷军难掩兴奋&#xff0c;他感慨道&#xff1a;“我心澎湃”。 小米新操作系统取…

docker中安装rabbitMq并配置启动

目录 1. 拉取镜像并安装&#xff08;此处实例安装的是最新版&#xff09;2.查看docker中已安装的镜像和版本3.启动RabbitMq4.配置管理端5.安装完成 1. 拉取镜像并安装&#xff08;此处实例安装的是最新版&#xff09; docker pull rabbitmq2.查看docker中已安装的镜像和版本 …

【c++|opencv】二、灰度变换和空间滤波---2.直方图和均衡化

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 图像直方图、直方图均衡化 1. 图像直方图 #include <iostream> #include <opencv2/opencv.hpp>using namespace cv; using namespace std;…

【多线程面试题十七】、如果不使用synchronized和Lock,如何保证线程安全?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;如果不使用synchronized…

文心一言 VS 讯飞星火 VS chatgpt (125)-- 算法导论10.6 6题

六、用go语言&#xff0c;任意有根树的左孩子右兄弟表示法中每个结点用到三个指针: leftchild、rightsibling 和parent。对于任何结点&#xff0c;都可以在常数时间到达其父结点&#xff0c;并在与其孩子数呈线性关系的时间内到达所有孩子结点。说明如何在每个结点中只使用两个…

军工工厂安全生产视频AI识别技术方案

一、需求分析 在国家政策、技术创新和企业发展需求转变等多个维度的共同驱动和协同下&#xff0c;特别是工业互联网作为“新基建”的提出&#xff0c;都在推动工业制造朝着数字化、网络化、智能化方向发展。军工装备制造行业承担着国民经济和国防建设的重要使命&#xff0c;构…

门面模式门面模式

目录 一.介绍 二.UML类图 未使用门面模式 使用门面模式 三.具体代码 业务代码 四.使用场景 一.介绍 门面模式&#xff08;Facade Pattern&#xff09;属于结构型模式。通过给多个复杂的子系统提供一个门面(高层接口)&#xff0c;使这些子系统更加容易的被访问&#xff0…

OpenLayers实战,OpenLayers实现TopoJson格式区划边界鼠标点击选中高亮显示,点击空白区域取消高亮

专栏目录: OpenLayers实战进阶专栏目录 前言 本章使用OpenLayers实现从vue项目中加载assets资源目录中的TopoJson格式数据,实现鼠标点击区划边界范围内时选并高亮显示,点击区划边界区域外取消高亮的功能。 本章是综合应用,为方便大家理解代码,拆分为简单的单一技术可以…

修改例程flags3_asyncio.py以解决RuntimeError错误

运行示例18-13 flags3_asyncio.py&#xff0c;程序报错如下&#xff1a; D:\Python\Python311\python.exe D:\fluentPy\chapter17_18\flags3_asyncio.py REMOTE site: https://www.fluentpython.com/data/flags/ Searching for 20 flags: from BD to VN 5 concurrent connecti…

nginx 转发数据流文件

1.问题描述 后端服务&#xff0c;从数据库中查询日志&#xff0c;并生成表格文件返回静态文件。当数据量几兆时&#xff0c;返回正常&#xff0c;但是超过几十兆&#xff0c;几百兆&#xff0c;就会超过网关的连接超时时间30秒。 时序图 这里面主要花费时间的地方在&#xff…

使用tensorflow创建自己的量化金融工具

介绍 在充满活力的金融领域,高频交易 (HFT) 已经成为游戏规则的改变者。高频交易能够在几毫秒内执行数千个订单,利用先进的算法和计算技术实时利用微小的价格差异。随着金融市场的不断发展,支持高频交易策略的工具和框架也必须不断发展。在这一背景下,TF Quant Finance (T…

AGENTTUNING:为LLM启用广义的代理能力

背景 翻译智谱这篇文章的初衷是&#xff0c;智谱推出了他们所谓的第三代大模型。这第三代的特点在哪呢&#xff1a;个人总结主要有一下几个点&#xff1a; 1.用特定prompt方式自闭环方式解决安全注入问题 2.增加了模型function call、agent能力 3.具备代码能力 4.做了能力…

excel从身份证号截取出生年月日

1、身份证号第7-14位&#xff0c;代表出生日期 2、用鼠标选中出生日期要存入的单元格&#xff0c;在编辑栏&#xff0c;输入函数公式&#xff1a;TEXT(MID(B3,7,8),"00-00-00")&#xff0c;然后按【CtrlEnter】结束确认&#xff0c;即可提取出身份证中的出生日期&am…

应急响应—挖矿病毒与勒索病毒

应急响应—挖矿病毒与勒索病毒 1. 前言2. 挖矿病毒2.1. 挖矿病毒传播方式2.2. 挖矿病毒危害2.3. 挖矿病毒防范2.4. 威胁情报中心 3. 勒索病毒3.1. 勒索病毒传播方式3.2. 勒索病毒危害3.3. 勒索病毒防范3.4. 勒索病毒家族及识别3.5. 解密工具下载3.5.1. 勒索病毒搜索平台3.5.2. …

群晖设置DDNS (服务商Godaddy被墙 DDNS-GO无法解析 采用自定义脚本方式完成DDNS更新)

起因&解决思路 事情的开始大概是这样的。。godaddy买了个域名&#xff0c;好好的用了半个月。。然后一直更新失败发现被狗东西墙了 在提一嘴DDNS-GO 解析失败原因 DDNS-GO必须要先向godaddy请求自己的IP地址[这里被墙卡住了]&#xff0c;然后比对&#xff0c;再决定是否上…

okhttp post请求 header post参数加密遇到的两个问题

如果你对于网络请求用了https后是否还有必要对参数加密有疑问可以看我上篇的文章&#xff1a;网络安全https 记得耐心看完&#xff0c;下面说问题&#xff1a; Caused by: java.lang.IllegalArgumentException: Unexpected char 0x0a 一开始以为是okhttp框架对特殊字符做了现在…

私有网络的安全保障,WorkPlus Meet内网视频会议助力企业高效会议

在企业内部沟通与协作中&#xff0c;视频会议成为了一种必不可少的沟通方式。然而&#xff0c;传统的互联网视频会议往往受制于网络不稳定因素&#xff0c;给企业带来不便与困扰。WorkPlus Meet作为一款专注内网视频会议的软件&#xff0c;致力于为企业打造高效、稳定的内网视频…

openpnp - code review - 开机对话框历史记录和贡献者名单

文章目录 openpnp - code review - 开机对话框历史记录和贡献者名单概述笔记D:\my_openpnp\openpnp_dev_2022_0801\src\main\java\org\openpnp\gui\AboutDialog.javaEND openpnp - code review - 开机对话框历史记录和贡献者名单 概述 偶然发现, 自己打包后的openpnp, 开机后…

js中获取json的值:使用 JSON.parse() 方法

比如json为&#xff1a;configs: "{"type":1}" 直接打印configs如下图 我们可以使用 JSON.parse() 方法将JSON格式字符串转换为 JavaScript 对象。 let a JSON.parse(configs) console.log(a) a打印出来如下图 此时就可以用a.type来得到1。 JSON.parse(…

配电柜监控原来还能这样?真的太爽啦!

在现代社会中&#xff0c;电力作为基础设施的一部分&#xff0c;扮演着至关重要的角色。为了确保电力系统的可靠性、安全性和高效性&#xff0c;配电柜监控系统变得越来越重要。 配电柜监控系统提供了实时数据和控制&#xff0c;有助于迅速识别并解决问题&#xff0c;从而降低停…