一、 项目前期准备
1.数据库准备
创建schedule_system数据库并执行如下语句
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- 创建日程表
-- ----------------------------
DROP TABLE IF EXISTS `sys_schedule`;
CREATE TABLE `sys_schedule` (
`sid` int NOT NULL AUTO_INCREMENT,
`uid` int NULL DEFAULT NULL,
`title` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT
NULL,
`completed` int(1) NULL DEFAULT NULL,
PRIMARY KEY (`sid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE =
utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- 创建用户表
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
`uid` int NOT NULL AUTO_INCREMENT,
`username` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`user_pwd` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL
DEFAULT NULL,
PRIMARY KEY (`uid`) USING BTREE,
UNIQUE INDEX `username`(`username`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT =
Dynamic;
-- ----------------------------
-- 插入用户数据
-- ----------------------------
INSERT INTO `sys_user` VALUES (1, 'zhangsan', 'e10adc3949ba59abbe56e057f20f883e');
INSERT INTO `sys_user` VALUES (2, 'lisi', 'e10adc3949ba59abbe56e057f20f883e');
SET FOREIGN_KEY_CHECKS = 1;
获得如下表格:
2.导入依赖
jar包位置:
3.pojo包处理
在pojo包下创建实体类对象SysUser、SysSchedule,实现序列化接口
使用lombok处理getter、setter、equals、hashcode 构造器:
SysUser:
package com.fire.schedule.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
//TODO 使用lombok帮助我们生成getter、setter、equals、hashcode、全参构造、无参构造
@AllArgsConstructor //添加了全参构造
@NoArgsConstructor //添加了无参构造
@Data //getter、setter、equals、hashcode、toString
//TODO 创建实体类对象SysUser,实现序列化接口
public class SysUser implements Serializable {
private Integer uid;
private String username;
private String userPwd;
}
SysSchedule:
package com.fire.schedule.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
//TODO 使用lombok帮助我们生成getter、setter、equals、hashcode、全参构造、无参构造
@AllArgsConstructor //添加了全参构造
@NoArgsConstructor //添加了无参构造
@Data //getter、setter、equals、hashcode、toString
public class SysSchedule implements Serializable {
private Integer sid;
private Integer uid;
private String title;
private Integer completed;
}
4.dao包处理
创建util包,并在包下创建JDBCUtil连接池工具类
导入JDBCUtil连接池工具类并准备jdbc.properties配置文件:
JDBCUtil:
package com.fire.schedule.util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
public class JDBCUtil {
private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
private static DataSource dataSource;
// 初始化连接池
static{
// 可以帮助我们读取.properties配置文件
Properties properties=new Properties();
InputStream resourceAsStream=
JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
try {
properties.load(resourceAsStream);
dataSource= DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/*1 向外提供连接池的方法*/
public static DataSource getDataSource(){
return dataSource;
}
/*2 向外提供连接的方法*/
public static Connection getConnection(){
Connection connection=threadLocal.get();
if (null==connection) {
try {
connection = dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeException(e);
}
threadLocal.set(connection);
}
return connection;
}
/*定义一个归还连接的方法 (解除和ThreadLocal之间的关联关系) */
public static void releaseConnection(){
Connection connection=threadLocal.get();
if (null!=connection) {
threadLocal.remove();
// 把连接设置回自动提交的连接
try {
connection.setAutoCommit(true);
// 自动归还到连接池
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
jdbc.properties配置文件:
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/schedule_system username=root
password=root
在dao包下创建BaseDao对象并复制如下代码:
package com.fire.schedule.dao;
import com.fire.schedule.util.JDBCUtil;
import java.lang.reflect.Field;
import java.sql.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
public class BaseDao {
// 公共的查询方法返回的是单个对象
public <T> T baseQueryObject(Class<T> clazz, String sql, Object... args) { T t = null;
Connection connection = JDBCUtil.getConnection();
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
int rows = 0;
try {
// 准备语句对象
preparedStatement = connection.prepareStatement(sql);
// 设置语句上的参数
for (int i = 0; i < args.length; i++) {
preparedStatement.setObject(i + 1, args[i]);
}
// 执行查询
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
t = (T) resultSet.getObject(1);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != resultSet) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (null != preparedStatement) {
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
JDBCUtil.releaseConnection();
}
return t;
}
// 公共的查询方法返回的是对象的集合
public <T> List<T> baseQuery(Class clazz, String sql, Object... args) {
List<T> list = new ArrayList<>();
Connection connection = JDBCUtil.getConnection();
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
int rows = 0;
try {
// 准备语句对象
preparedStatement = connection.prepareStatement(sql);
// 设置语句上的参数
for (int i = 0; i < args.length; i++) {
preparedStatement.setObject(i+1,args[i]);
}
// 执行 查询
resultSet = preparedStatement.executeQuery();
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
// 将结果集通过反射封装成实体类对象
while (resultSet.next()) {
// 使用反射实例化对象
Object obj =clazz.getDeclaredConstructor().newInstance();
for (int i = 1; i <= columnCount; i++) {
String columnName = metaData.getColumnLabel(i);
Object value = resultSet.getObject(columnName);
// 处理datetime类型字段和java.util.Data转换问题
if(value.getClass().equals(LocalDateTime.class)){
value= Timestamp.valueOf((LocalDateTime) value);
}
Field field = clazz.getDeclaredField(columnName);
field.setAccessible(true);
field.set(obj,value);
}
list.add((T)obj);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null !=resultSet) {
try {
resultSet.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (null != preparedStatement) {
try {
preparedStatement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
JDBCUtil.releaseConnection();
}
return list;
}
// 通用的增删改方法
public int baseUpdate(String sql,Object ... args) {
// 获取连接
Connection connection = JDBCUtil.getConnection();
PreparedStatement preparedStatement=null;
int rows = 0;
try {
// 准备语句对象
preparedStatement = connection.prepareStatement(sql);
// 设置语句上的参数
for (int i = 0; i < args.length; i++) {
preparedStatement.setObject(i+1,args[i]);
}
// 执行 增删改 executeUpdate
rows = preparedStatement.executeUpdate();
// 释放资源(可选)
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (null != preparedStatement) {
try {
preparedStatement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
JDBCUtil.releaseConnection();
}
// 返回的是影响数据库记录数
return rows;
}
}
创建dao层接口和所有实现类:
接口:SysUserDao、SysScheduleDao
实现类:SysUserDaoImpl、SysScheduleDaoImpl
5.service包处理
创建dao层接口和所有实现类:
接口:SysUserService、SysScheduleService
实现类:SysUserServiceImpl、SysScheduleServiceImpl
6.controller包处理
BaseController处理请求路径问题
package com.fire.schedule.controller;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
public class BaseController extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String requestURI = req.getRequestURI();
String[] split = requestURI.split("/");
String methodName =split[split.length-1];
// 通过反射获取要执行的方法
Class clazz = this.getClass();
try {
Method method=clazz.getDeclaredMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
// 设置方法可以访问
method.setAccessible(true);
// 通过反射执行代码
method.invoke(this,req,resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
多个处理器继承BaseController
UserController:
package com.fire.schedule.controller;
import jakarta.servlet.annotation.WebServlet;
@WebServlet("/user/*")
public class UserController extends BaseController{
}
SysScheduleController:
package com.fire.schedule.controller;
import jakarta.servlet.annotation.WebServlet;
@WebServlet("/schedule/*")
public class SysScheduleController extends BaseController{
}
7.加密工具类的使用
导入MD5Util工具类
package com.fire.schedule.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public final class MD5Util {
public static String encrypt(String strSrc) {
try {
char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f' };
byte[] bytes = strSrc.getBytes();
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(bytes);
bytes = md.digest();
int j = bytes.length;
char[] chars = new char[j * 2];
int k = 0;
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
chars[k++] = hexChars[b >>> 4 & 0xf];
chars[k++] = hexChars[b & 0xf];
}
return new String(chars);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException("MD5加密出错!!!");
}
}
}
8.页面文件的导入
将我们在日常管理1的html文件导入进来
日常管理1
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,下节我们再来学习业务代码的开发处理