三层架构实现增删改查操作封装

本文介绍了Java后端开发中的三层架构,包括表示层(UI)、业务逻辑层(BLL)和数据访问层(DAL),并详细展示了如何使用JSP连接MySQL数据库实现增删改查操作。通过DAO层的JDBC实现,强调了分层设计在软件架构中的重要性,以提高代码的可维护性和解耦。
摘要由CSDN通过智能技术生成

概要

三层架构 
三层架构分为:数据(dao)层、 业务(service)层、控制(controller)层

(1)表示层(USL,即User Show Layer):视图层
    a. 前台:对应于MVC中的View,用于和用户交互、界面的显示。
    b. 对应于MVC中的Controller,用于控制跳转、调用业务逻辑层。
(2)业务逻辑层(BLL,即Business Logic Layer):Service层
    a. 接收表示层的请求及调用
    b. 组装数据访问层
(3)数据访问层(DAL,即Data Access Layer):Dao层
    直接访问数据库的操作

整体架构流程

代码顺序:

1.数据库表

2.实体层

3.dao层、daoimpl

4.service层、serviceimpl

5.controller层

就像搭房子,又下往上,像领导向下调用。controller层调用service层,再由service调用dao层。

技术名词解释

三层架构来源于后端开发的一种分层的思想。

引用自百科的解释:

三层架构(3-tier architecture)通常意义上的三层架构就是将整个业务应用划分为:界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)。

区分层次的目的即为了“高内聚低耦合”的思想。在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构。微软推荐的分层式结构一般分为三层,从下至上分别为:数据访问层、业务逻辑层(又或称为领域层)、表示层。

各层的作用如下:

表示层:主要对用户的请求接受,以及数据的返回,为客户端提供应用程序的访问。
业务逻辑层:主要负责对数据层的操作。也就是说把一些数据层的操作进行组合。
数据访问层:主要看数据层里面有没有包含逻辑处理,实际上它的各个函数主要完成各个对数据文件的操作。而不必管其他操作。

 

技术细节

一.案例(JSP连接MySQL数据库并实现增删改查)

1.代码目录

 2.应用的MySQL数据库中的表(包含username和password,后面也只会用到这两个):

3.代码介绍

(1)先要写的是pojo包中的Dept类和Emp类,最后写User类

package com.hp.pojo;

public class Dept {
    private int did;
    private String dname;
    private String dlocation;
    private String leader;

    public static void main(String[] args) {
        System.out.println(new Dept());
    }
    @Override
    public String toString() {
        return "Dept{" +
                "did=" + did +
                ", dname='" + dname + '\'' +
                ", dlocation='" + dlocation + '\'' +
                ", leader='" + leader + '\'' +
                '}';
    }

    //有参构造
    public Dept(int did, String dname, String dlocation, String leader) {
        this.did = did;
        this.dname = dname;
        this.dlocation = dlocation;
        this.leader = leader;
    }
//无参构造
    public Dept() {
    }
    //封装

    public int getDid() {
        return did;
    }

    public void setDid(int did) {
        this.did = did;
    }

    public String getDname() {
        return dname;
    }

    public void setDname(String dname) {
        this.dname = dname;
    }

    public String getDlocation() {
        return dlocation;
    }

    public void setDlocation(String dlocation) {
        this.dlocation = dlocation;
    }

    public String getLeader() {
        return leader;
    }

    public void setLeader(String leader) {
        this.leader = leader;
    }
}

 

package com.hp.pojo;

import java.util.Date;

public class Emp {
    private String id;
    private String name;
    private String sex;
    private Date birth;
    private double salary;
    private int deptId;

    public Emp(String id, String name, String sex, Date birth, double salary, int deptId) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.birth = birth;
        this.salary = salary;
        this.deptId = deptId;
    }

    public Emp() {
    }

    @Override
    public String toString() {
        return "Emp{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", birth=" + birth +
                ", salary=" + salary +
                ", deptId=" + deptId +
                '}';
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public int getDeptId() {
        return deptId;
    }

    public void setDeptId(int deptId) {
        this.deptId = deptId;
    }
}

(2)接下来进行dao层的增删改查操作(这里再附带JdbcUtil,即对jdbc的封装)
package com.hp.dao.impl;

import com.hp.dao.IDeptDao;
import com.hp.pojo.Dept;
import com.hp.utils.JdbcUtil;
import com.hp.utils.JdbcUtilPlus;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/*
DeptDaoImpl:
Dept 表示操作的实体
Dao 表示执行层/数据访问层/基层
Impl 表示实现类
*/
public class DeptDaoImpl implements IDeptDao {
    @Override
    public List<Dept> list() {
        return JdbcUtil.list("select * from t_dept where did=13",Dept.class);
      }

    @Override
    public Dept selectRow(int did) {
        return JdbcUtilPlus.selectRow("select * from t_Dept where did= ?",Dept.class,did);
    }
}
//查询多行多列
public static <T> List<T> list(String sql,Class<T> c) {
    //创建一个集合,存放所有对象
    List<T> tList = new ArrayList<>();
    try {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/salary?characterEncoding=utf-8", "root", "root");
        Statement statement = conn.createStatement();
        //statement执行sql,返回结果集
        ResultSet rs = statement.executeQuery(sql);
        //结果集rs得到结果集元数据
        ResultSetMetaData md = rs.getMetaData();
        //获取结果集的总列数
        int columnCount = md.getColumnCount();
        //解析rs(循环打印)
        while (rs.next()) {//读取结果集的光标向下移动,光标默认在哪一行,列名所在的那一行
            //根据每一行的数据,封装成一个实体对象
            T t = c.newInstance();
            //1.取出某一行的每一列数据,封装到对象t的属性中
            for (int i = 1; i <= columnCount; i++) {
                //通过列的序号,获取每一列的值
                Object value = rs.getObject(i);
                if (value!=null){
                    //通过列的序号,获取每一列的列名
                    String columnName = md.getColumnName(i);
                    //因为列名和实体类t中的属性名一致,为每一个属性构造一个反射中的set方法
                    Field f = c.getDeclaredField(columnName);
                    //赋予私有属性的赋值权限
                    f.setAccessible(true);
                    //使用反射,把value给到对象t的属性中
                    f.set(t,value);//理解为:把value赋值给对象t的columnName属性,相当于set方法
                }
            }
            //把对象存入集合中
            tList.add(t);
        }
        //关闭资源
        statement.close();
        conn.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return tList;
}
//查询一行
public static <T> T selectRow(String sql,Class<T> c) {
    try {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/salary?characterEncoding=utf-8", "root", "root");
        Statement statement = conn.createStatement();
        //statement执行sql,返回结果集
        ResultSet rs = statement.executeQuery(sql);
        //结果集rs得到结果集元数据
        ResultSetMetaData md = rs.getMetaData();
        //获取结果集的总列数
        int columnCount = md.getColumnCount();
        //解析rs(循环打印)
        // 根据每一行的数据,封装成一个实体对象
        T t=null;
        if (rs.next()) {//读取结果集的光标向下移动,光标默认在哪一行,列名所在的那一行
            t = c.newInstance();
            //1.取出某一行的每一列数据,封装到对象t的属性中
            for (int i = 1; i <= columnCount; i++) {
                //通过列的序号,获取每一列的值
                Object value = rs.getObject(i);
                if (value!=null){
                    //通过列的序号,获取每一列的列名
                    String columnName = md.getColumnName(i);
                    //因为列名和实体类t中的属性名一致,为每一个属性构造一个反射中的set方法
                    Field f = c.getDeclaredField(columnName);
                    //赋予私有属性的赋值权限
                    f.setAccessible(true);
                    //使用反射,把value给到对象t的属性中
                    f.set(t,value);//理解为:把value赋值给对象t的columnName属性,相当于set方法
                }
            }
        }
        //关闭资源
        statement.close();
        conn.close();
        return t;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
//查询一列
public static <T> List<T> selectColumn(String sql,Class<T> c) {
    //创建一个集合,存放所有对象
    List<T> tList = new ArrayList<>();
    try {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/salary?characterEncoding=utf-8", "root", "root");
        Statement statement = conn.createStatement();
        //statement执行sql,返回结果集
        ResultSet rs = statement.executeQuery(sql);
        //结果集rs得到结果集元数据
        ResultSetMetaData md = rs.getMetaData();
        //获取结果集的总列数
        int columnCount = md.getColumnCount();
        //解析rs(循环打印)
        while (rs.next()) {//读取结果集的光标向下移动,光标默认在哪一行,列名所在的那一行
                //通过列的序号,获取每一列的值
                T t = (T) rs.getObject(1);
                //把对象存入集合中
                tList.add(t);
            }
        //关闭资源
        statement.close();
        conn.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return tList;
}
//查询单个
public static <T> T selectOne(String sql,Class<T> c) {
    try {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/salary?characterEncoding=utf-8", "root", "root");
        Statement statement = conn.createStatement();
        //statement执行sql,返回结果集
        ResultSet rs = statement.executeQuery(sql);
        //结果集rs得到结果集元数据
        ResultSetMetaData md = rs.getMetaData();
        //获取结果集的总列数
        int columnCount = md.getColumnCount();
        //解析rs(循环打印)
        T t=null;
        if (rs.next()){
            t = (T) rs.getObject(1);
        }
        //关闭资源
        statement.close();
        conn.close();
        return t;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
//增 删 改
public static int update(String sql) {
    try {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/salary?characterEncoding=utf-8", "root", "root");
        Statement statement = conn.createStatement();
        //statement执行sql,返回结果集
        int i = statement.executeUpdate(sql);
        //关闭资源
        statement.close();
        conn.close();
        return i;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return 0;
}

上述难度跳动比较大,涉及到反射、泛类,而且这还是没有升级后的代码,存在sql注入的问题。我们后续还需要改进代码,让代码变得更加安全简洁。需要帮助理解的可以留言私信我!我们接着往下面看

(3)是逻辑性的service包啦
package com.hp.service.impl;

import com.hp.dao.IDeptDao;
import com.hp.dao.impl.DeptDaoImpl;
import com.hp.pojo.Dept;
import com.hp.service.IDeptService;

import java.util.List;

/*
DeptServiceImpl:
Dept 操作的实体类,或者操作某个表
Service 表示业务层
Impl 表示实现类*/
public class DeptServiceImpl implements IDeptService {
    //引入dao层
    private IDeptDao deptDao=new DeptDaoImpl();
    @Override
    public int add() {
        return 0;
    }

    @Override
    public List<Dept> list() {
        return deptDao.list();
    }

    @Override
    public Dept selectRow(int did) {
        return deptDao.selectRow(did);
    }
}
因为我们都已经把实现类写出来了,所以说它的接口类很容易就能写出,这里就不一一给大家说明了
(4)最后我想给大家实现一个入口测试类,用来判断所写的功能是否实现
@Test
public void testRow(){
    Dept dept = selectRow("select * from t_Dept where did=6", Dept.class);
    System.out.println(dept);
}
@Test
public void testColumn(){
    List<String> list = selectColumn("select dname from t_Dept", String.class);
    System.out.println(list);
}
@Test
public void testOne(){
    String dname = selectOne("select dname from t_Dept where did=1", String.class);
    System.out.println(dname);
}
@Test
public void testUpdate(){
    int j = update("insert into t_Dept values (null,'a','b','c')");
    System.out.println(j);
}
@Test//测试登录
public void testLogin(){
    String username="cc'or'1'='1";
    String password="cc'or'1'='1";
    User user = selectRow("select * from t_users where username='" + username + "' and password='" + password+"'", User.class);
    System.out.println(user!=null?"登陆成功":"登录失败");
}
最后一个也是下次讲述的内容之一,这里我留一个悬念,聪明的小伙伴们也看到这里我用了@Test,注意这里要导一个包junit-4.12.jar,需要的可以私信我!有什么问题后续也可以提出来,知无不言言无不尽。

小结

本节课我们大家搭建了三层架构:控制层、业务层、数据访问层,让我们的数据在各个层之间传递,最后我们要简化代码——抽取工具类。从总结来看,我们的核心就是抽取工具类。所以我们最重要的就是理解工具类的方法,在java基础中好好学习泛类,面向对象,反射,这样在后续的java进阶学习中,才能更加如鱼得水,游刃有余!最后我们为什么要用三层架构的设计模式?这一点也困惑我许久。通过老师的讲解和自己的总结得出dao层是基层,而service是中层管理人员,最后controller是高层,一个项目需要每个人发挥自己的能力,这样反映了java编程工作团队合作的重要性。只有我们一层管理着下一层,秩序才不会紊乱,功能模块才会更加稳定。有不同见解的朋友也可以底下留言,也可以私下联系我,让我们遨游在java的海洋里面吧!

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值