jsp学习笔记之三层架构(五)

五. 三层架构

表示层(USL,User Show Layer,视图层)
业务逻辑层(BLL,Bussiness Logic Layer,Service层)
数据访问层(DAL,Data Access Layer,Dao层)

1. 三层架构与MVC

jsp学习笔记之三层架构(五)_第1张图片

a. 表示层(USL,User Show Layer,视图层)

  • 前台:对应MVC中的view,用于和用户交互、界面的显示
    jsp、js、html、css、jquery等Web前端技术

代码位置:WebContent

  • 后台:对应MVC中的controller,用于控制跳转、调用业务逻辑层
    Servlet(SpringMVC Struts2)

代码位置:xxx.servlet包中

b. 业务逻辑层(BLL,Bussiness Logic Layer,Service层)

  • 接受表示层的请求 调用
  • 组装数据访问层,逻辑性的操作(增删改查,增删改:查+增删改)

代码位置:xxx.service包中(有时候也称为:xxx.manager、xx. bll)

c. 数据访问层(DAL,Data Access Layer,Dao层)

  • 直接访问数据库的操作,原子性操作(增删改查)

代码位置:xxx.dao

2. 三层间的关系

上层 将请求传递给下层,下层处理后 返回给上层

3. 三层优化

a.加入接口

建议面向接口开发:先接口-再实现类
–service、dao加入接口
–接口与实现类的命名规范

  • 接口:interface,
    起名:I实体类Service、IStudentService、IStudentDao

  • 实现类:implements
    起名:实体类ServiceImpl、StudentServiceImpl、StudentDaoImpl

  • 接口: I实体类层所在包名 IStudentService、IStudentDao

  • 实现类:实体类层所在包名 Impl StudentServiceImpl、 StudentDaoImpl

以后使用接口/实现类时,推荐写法:
接口x = new 实现类();

IStudentDao studentDaoImpl = new StudentDaoImpl();

a. DBUtil 数据库帮助类,

简化Dao层

4. 示例:

整体结构
jsp学习笔记之三层架构(五)_第2张图片
jsp学习笔记之三层架构(五)_第3张图片
其中几个文件
DBUtil.java

package three_tier.util;

import three_tier.entity.Student;

import java.sql.*;

/**
 * @Author: qsX
 * @Time: 2020-05-06 16:18
 * @Description: 数据库帮助类
 */
public class DBUtil {
    private static final String URL = "jdbc:oracle:thin:@localhost:1521:ORCL";
    private static final String USERNAME = "scott";
    private static final String PSAAWORD = "tiger";
    public static Connection connection = null;
    public static PreparedStatement pstmt = null;
    public static ResultSet rs = null;
    /**
     * @Description 获取连接
     * @Param []
     * @Return java.sql.Connection
     */
    public static  Connection getConnection() throws ClassNotFoundException, SQLException {
        Class.forName("oracle.jdbc.OracleDriver");
        return DriverManager.getConnection(URL, USERNAME, PSAAWORD);
    }
    /**
     * @Description 关闭所有接口
     * @Param [rs, stmt, connection]
     * @Return void
     */
    public static void closeAll (ResultSet rs,Statement stmt,Connection connection) {
        try {
            if (rs != null) {
                rs.close();
            }
            if (pstmt != null) {
                pstmt.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    /**
     * @Description 获取PreparedStatement
     * @Param [String sql,Object[] params]
     * @Return PreparedStatement
     */

    public  static  PreparedStatement createPreparedStatement(String sql,Object[] params) throws SQLException, ClassNotFoundException {
        //Object[] params = {name,age,...};
        pstmt = getConnection().prepareStatement(sql);

        //setxxx()的个数依赖于?的个数 ; ?的个数依赖于数组params的长度
        if (params!=null) {
            for (int i = 0 ; i < params.length ; i++) {
                pstmt.setObject(i+1,params[i]);
            }
        }
        return pstmt;
    }
    /**
     * @Description 通用增删改
     * @Param [String sql,Object[] params]
     * @Return boolean
     */
    public static boolean executeUpdate(String sql,Object[] params) {
        try {
            pstmt = createPreparedStatement(sql, params);
            int count = pstmt.executeUpdate();
            if (count > 0) {
                return true;
            } else {
                return false;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return false;
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            closeAll(null , pstmt , connection);
        }
    }

    /**
     * @Description 通用查询
     * @Param [String sql,Object[] params]
     * @Return ResultSet
     */

    public static ResultSet executeQuery(String sql,Object[] params) {
        Student student = null;

        try {
            pstmt = createPreparedStatement(sql, params);
            rs = pstmt.executeQuery();

            return rs;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

StudentDaoImpl.java

package three_tier.dao.impl;

import three_tier.dao.IStudentDao;
import three_tier.entity.Student;
import three_tier.util.DBUtil;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: qsX
 * @Time: 2020-05-04 14:21
 * @Description:数据访问层,原子性的增删改查,不可拆
 */
public class StudentDaoImpl implements IStudentDao {
    private final String URL = "jdbc:oracle:thin:@localhost:1521:ORCL";
    private final String USERNAME = "scott";
    private final String PSAAWORD = "tiger";

    /**
     * @Description 根据学号查询是否有此人
     * @Param [sno]
     * @Return boolean
     */
    @Override
    public boolean isExist(int sno) {
        return queryStudentBySno(sno) == null ? false : true;
    }

    /**
     * @Description 增加学生
     * @Param [student]
     * @Return boolean
     */
    @Override
    public boolean addStudent(Student student) {
        String sql = "insert into student values(?,?,?,?)";
        Object[] params = {student.getSno(),student.getSname(),student.getSage(),student.getSaddress()};
        return DBUtil.executeUpdate(sql,params);
    }

    /**
     * @Description 根据学号删除学生
     * @Param [sno]
     * @Return boolean
     */
    @Override
    public boolean deleteStudent(int sno) {
        String sql = "delete from student where sno = ?";
        Object[] params = {sno};
        return DBUtil.executeUpdate(sql,params);
    }
    /**
     * @Description 根据学号修改学生信息
     * @Param [student]
     * @Return boolean
     */
    @Override
    public boolean updateStudentBySno(int sno, Student student) {
        String sql = "update student set sname = ?,sage = ?,saddress = ? where sno = ?";
        Object[] params = {student.getSname(),student.getSage(),student.getSaddress(),sno};
        return DBUtil.executeUpdate(sql,params);
    }


    /**
     * @Description 根据学号查学生具体信息
     * @Param [sno]
     * @Return Student
     */
    @Override
    public Student queryStudentBySno(int sno) {
        Student student = null;
        Connection connection = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Class.forName("oracle.jdbc.OracleDriver");
            connection = DriverManager.getConnection(URL, USERNAME, PSAAWORD);
            String sql = "select * from student where sno = ? ";
            pstmt = connection.prepareStatement(sql);
            pstmt.setInt(1, sno);
            rs = pstmt.executeQuery();
            if (rs.next()) {
                int no = rs.getInt("sno");
                String name = rs.getString("sname");
                int age = rs.getInt("sage");
                String address = rs.getString("saddress");
                student = new Student(no, name, age, address);
            }
            return student;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (pstmt != null) {
                    pstmt.close();
                }
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @Description 查学生全部信息
     * @Param [sno]
     * @Return List
     */
    @Override
    public List<Student> queryAllStudent() {
        Student student = null;
        PreparedStatement pstmt = null;
        List<Student> students = null;
        ResultSet rs = null;
        try {
            String sql = "select * from student order by sno";
            rs = DBUtil.executeQuery(sql,null);
            if (rs != null) {
                students = new ArrayList<>();
                while (rs.next()) {
                    int no = rs.getInt("sno");
                    String name = rs.getString("sname");
                    int age = rs.getInt("sage");
                    String address = rs.getString("saddress");
                    student = new Student(no, name, age, address);
                    students.add(student);
                }
            }
            return students;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
           DBUtil.closeAll(rs , pstmt , DBUtil.connection);
        }
    }
}

add.jsp

<%--
  Created by IntelliJ IDEA.
  User: qsX
  Date: 2020/5/5
  Time: 15:00
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <script type="text/javascript" src="../../jquery-3.3.1.js"></script>
    <script type="text/javascript">
        function check() {          //onsubmit: return true ,表单正常提交;false 终止提交
            var sno = $("#sno").val();
            var sname = $("#sname").val();
            var sage = $("#sage").val();
            var saddress = $("#saddress").val();
            if (!(sno > 0 && sno < 101)) {
                alert("学号有误!必须是1~100");
                return false;
            }
            if (!(sname.length > 1 && sname.length < 5)) {
                alert("姓名有误!长度必须是2到4位");
                return false;
            }
            if (!(sage > 0 && sage < 100)) {
                alert("年龄有误!必须是1~100");
                return false;
            }
            if (!(saddress.length >= 2 && saddress.length <= 30)) {
                alert("地址有误!长度必须是2~30位");
                return false;
            }
            return true;
        }
    </script>

    <title>新增学生</title>
</head>
<body>
<form action="../../AddStudentServlet" method="post" onsubmit="return check()">
    学号:<input type="text" name="sno" id="sno"/> <br>
    姓名:<input type="text" name="sname" id="sname"/> <br>
    年龄:<input type="text" name="sage" id="sage"/> <br>
    地址:<input type="text" name="saddress" id="saddress"/> <br>
    <input type="submit" value="添加"/>
    <a href="/QueryAllStudentServlet">返回</a><br><br>
</form>
</body>
</html>

jsp学习笔记之三层架构(五)_第4张图片

jsp学习笔记之三层架构(五)_第5张图片

5. 如何实现数据分页

要实现分页,必须知道数据从哪里开始,从哪里结束

假设每页显示10条数据

5.1 sql语句怎么写

a. Oracle、sqlserver从1开始计数

第几页 开始 结束
1 1 10
2 11 20
3 21 30
. . .
n (n-1)*10-1 n*10

Oracle:
a方法:

 select * 
 from student
 where sno >=(n-1)*10+1 and sno<=n*10;

–此种写法的前提:必须是Id连续,否则不能实现每页显示十条

b方法:

select rownum, t. * 
from student t. 
where rownum >= (n-1)*10+1 and rownum <=n*10 
order by sno ;

出现问题 :

  1. 如果根据sno排序则rownum会混乱(解决方案:分开使用->先只排序,再只查询rownum)
  2. rownum不能查询大于只能查询小于

b方法改进:

select rownum,t.* from
	(select s.* 
	from student s 
	order by sno asc)t;

最终版:

select * from 
	(select rownum r, t.* from 
		(select s.* 
		from student s 
		order by sno asc
		)t 
	where ruwnum<=n*10 
	)r 
where r>=(n-1)*10-1 ;

sqlserver:

	row_number()       	over(字段)
select *from 
	(select row_ number() over (sno order by sno asc) as r,* from student 
	where r<=n*10
	)
where r>=(n-1)*10+1 ;

b. mysql从0开始计数

第几页 开始 结束
0 0 9
1 10 19
2 20 29
. . .
n n*10-1 (n+1)*10-1

方法:

	limt		开始,多少条
0select * from student limit 0,10;1select * from student limit 10,10;2select * from student limit 20,10
第n页
select * from student limit n * 10,10;

mysql的分页语句

select * from student limit 页数 * 页面大小,页面大小;

5.2 分页实现

五个变量

  1. 数据总数

    查数据库,select count(*)…

  2. 页面大小(每页显示数据条数)

    用户自定义

  3. 总页数

    程序自动计算
    总页数 = 数据总数%页面大小 == 0 ?数据总数 / 页面大小 :数据总数/页面大小+1

  4. 当前页(页码)

    用户自定义

  5. 当前页的对象集合(实体类集合):每页显示的所有数据
    查数据库,分页sql

分析:
jsp学习笔记之三层架构(五)_第6张图片

你可能感兴趣的:(jsp,java)