表示层(USL,User Show Layer,视图层)
业务逻辑层(BLL,Bussiness Logic Layer,Service层)
数据访问层(DAL,Data Access Layer,Dao层)
代码位置:WebContent
代码位置:xxx.servlet包中
代码位置:xxx.service包中(有时候也称为:xxx.manager、xx. bll)
代码位置:xxx.dao
上层 将请求传递给下层,下层处理后 返回给上层
建议面向接口开发:先接口-再实现类
–service、dao加入接口
–接口与实现类的命名规范
接口:interface,
起名:I实体类Service、IStudentService、IStudentDao
实现类:implements
起名:实体类ServiceImpl、StudentServiceImpl、StudentDaoImpl
接口: I实体类层所在包名 IStudentService、IStudentDao
实现类:实体类层所在包名 Impl StudentServiceImpl、 StudentDaoImpl
以后使用接口/实现类时,推荐写法:
接口x = new 实现类();
IStudentDao studentDaoImpl = new StudentDaoImpl();
简化Dao层
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>
要实现分页,必须知道数据从哪里开始,从哪里结束
假设每页显示10条数据
第几页 | 开始 | 结束 |
---|---|---|
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 ;
出现问题 :
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 ;
第几页 | 开始 | 结束 |
---|---|---|
0 | 0 | 9 |
1 | 10 | 19 |
2 | 20 | 29 |
. | . | . |
n | n*10-1 | (n+1)*10-1 |
方法:
limt 开始,多少条
第0页
select * from student limit 0,10;
第1页
select * from student limit 10,10;
第2页
select * from student limit 20,10
第n页
select * from student limit n * 10,10;
mysql的分页语句
select * from student limit 页数 * 页面大小,页面大小;
五个变量
数据总数
查数据库,select count(*)…
页面大小(每页显示数据条数)
用户自定义
总页数
程序自动计算
总页数 = 数据总数%页面大小 == 0 ?数据总数 / 页面大小 :数据总数/页面大小+1
当前页(页码)
用户自定义
当前页的对象集合(实体类集合):每页显示的所有数据
查数据库,分页sql