引言:企业信息管理系统的核心价值
在企业日常运营中,高效的信息管理是提升效率的关键。本文将手把手教你开发一套企业信息管理系统,涵盖用户登录、信息增删改查、权限控制等核心功能。系统采用 Spring Boot 作为后端框架,MyBatis 处理数据交互,Thymeleaf 实现前端页面渲染,Druid 作为数据源保障性能,最终形成一套轻量、易用、可扩展的企业级解决方案。
一、系统架构与技术栈
1.1 系统功能概述
本系统聚焦企业用户信息管理,核心功能包括:
- 用户登录 / 退出(含权限拦截)
- 用户信息列表展示
- 用户信息添加、修改、删除
- 前端页面动态渲染与交互
1.2 技术栈选择
- 后端:Spring Boot 3.2.8(框架核心)、MyBatis 3.0.3(ORM 框架)、Druid 1.2.20(数据源)
- 前端:Thymeleaf 3.1.2(模板引擎)、HTML5/CSS3(页面结构与样式)、jQuery 3.7.1(前端交互)
- 数据库:MySQL 8.0(数据存储)
- 开发工具:IntelliJ IDEA、Maven(依赖管理)
二、环境搭建与项目初始化
2.1 数据库设计
首先创建系统所需的数据库表,以my_user
表为例(存储用户信息):
sql
SET FOREIGN_KEY_CHECKS=0;
-- 用户表结构
DROP TABLE IF EXISTS `my_user`;
CREATE TABLE `my_user` (
`pid` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`username` varchar(255) DEFAULT NULL COMMENT '用户名',
`password` varchar(255) DEFAULT NULL COMMENT '密码',
`p_addr` varchar(255) DEFAULT NULL COMMENT '地址(下划线命名)',
`gender` int(11) DEFAULT NULL COMMENT '性别(1-男,0-女)',
`birth` date DEFAULT NULL COMMENT '生日',
PRIMARY KEY (`pid`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户信息表';
-- 初始化测试数据
INSERT INTO `my_user` VALUES (1, 'zhangsan', '123', '北京', 1, '2020-06-14');
2.2 项目结构设计
遵循 Spring Boot 最佳实践,项目结构如下:
src/
├── main/
│ ├── java/com/qcby/inforcontrollersystem/
│ │ ├── config/ # 配置类(Druid、MyBatis、MVC等)
│ │ ├── controller/ # 控制器(处理请求)
│ │ ├── entity/ # 实体类(与数据库表映射)
│ │ ├── interceptor/ # 拦截器(登录验证等)
│ │ ├── mapper/ # MyBatis映射接口
│ │ ├── service/ # 业务逻辑层(含Impl实现)
│ │ └── InforControllerSystemApplication.java # 启动类
│ ├── resources/
│ │ ├── application.yaml # 主配置文件
│ │ ├── static/ # 静态资源(css、images、js)
│ │ └── templates/ # Thymeleaf模板(login.html、main.html等)
└── test/ # 单元测试目录
2.3 核心依赖配置(pom.xml)
通过 Maven 管理依赖,关键依赖如下:
XML
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.8</version>
</parent>
<dependencies>
<!-- Spring Boot Web核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Thymeleaf模板引擎 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- MyBatis整合 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<!-- Druid数据源(适配Spring Boot 3) -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>1.2.20</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- jQuery(WebJars方式) -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.7.1</version>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
三、核心配置详解
3.1 数据源配置(Druid)
Druid 作为高性能数据源,需配置连接池参数和监控功能,创建DruidConfig.java
:
java
package com.qcby.inforcontrollersystem.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class DruidConfig {
// 绑定application.yaml中spring.datasource前缀的配置
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return new DruidDataSource();
}
}
3.2 MyBatis 配置(解决驼峰映射)
数据库表字段采用下划线命名(如p_addr
),实体类采用驼峰命名(如pAddr
),需配置映射规则:
java
package com.qcby.inforcontrollersystem.config;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisConfig {
@Bean
public ConfigurationCustomizer configurationCustomizer() {
// 开启下划线转驼峰映射
return configuration -> configuration.setMapUnderscoreToCamelCase(true);
}
}
3.3 MVC 配置(视图映射与拦截器)
配置页面路由和登录拦截器,确保未登录用户无法访问核心功能:
java
package com.qcby.inforcontrollersystem.config;
import com.qcby.inforcontrollersystem.interceptor.LoginInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
import java.util.List;
@Configuration
@MapperScan("com.qcby.inforcontrollersystem.mapper") // 扫描MyBatis Mapper接口
public class TxMvcConfig implements WebMvcConfigurer {
// 视图映射:直接将请求路径映射到模板页面
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/toLogin").setViewName("login"); // /toLogin -> login.html
registry.addViewController("/index").setViewName("index"); // /index -> index.html
registry.addViewController("/menu").setViewName("menu"); // /menu -> menu.html
}
// 注册拦截器:拦截未登录用户
@Override
public void addInterceptors(InterceptorRegistry registry) {
List<String> excludePaths = new ArrayList<>();
// 排除登录页、静态资源等不需要拦截的路径
excludePaths.add("/css/**");
excludePaths.add("/images/**");
excludePaths.add("/toLogin");
excludePaths.add("/login");
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**") // 拦截所有请求
.excludePathPatterns(excludePaths); // 排除指定路径
}
}
四、核心功能实现
4.1 实体类设计(MyUser.java)
与my_user
表映射,包含用户基本信息:
java
package com.qcby.inforcontrollersystem.entity;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
public class MyUser {
private Integer pid; // 主键
private String username; // 用户名
private String password; // 密码
private String pAddr; // 地址(驼峰命名,对应表中p_addr)
private Integer gender; // 性别
@DateTimeFormat(pattern = "yyyy-MM-dd") // 日期格式转换
private Date birth; // 生日
// 构造方法、Getter、Setter(省略,需手动生成)
}
4.2 登录拦截器(LoginInterceptor.java)
拦截未登录用户,强制跳转至登录页:
java
package com.qcby.inforcontrollersystem.interceptor;
import com.qcby.inforcontrollersystem.entity.MyUser;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
MyUser user = (MyUser) session.getAttribute("user"); // 从Session获取用户信息
if (user == null) {
// 未登录,重定向到登录页
response.sendRedirect(request.getContextPath() + "/toLogin");
return false;
}
// 已登录,放行
return true;
}
}
4.3 数据访问层(Mapper 接口)
通过 MyBatis 注解实现数据库操作:
java
package com.qcby.inforcontrollersystem.mapper;
import com.qcby.inforcontrollersystem.entity.MyUser;
import org.apache.ibatis.annotations.*;
import java.util.List;
import java.util.Map;
public interface MyUserMapper {
// 新增用户(自增主键回写)
@Options(useGeneratedKeys = true, keyProperty = "pid")
@Insert("insert into my_user(username, password, p_addr, gender, birth) " +
"values(#{username}, #{password}, #{pAddr}, #{gender}, #{birth})")
void insert(MyUser user);
// 查询所有用户
@Select("select * from my_user")
List<MyUser> selectUsers();
// 登录验证(根据用户名和密码查询)
@Select("select * from my_user where username = #{username} and password = #{password}")
MyUser selectUsersByUsernameAndPassword(Map<String, String> map);
// 根据ID查询用户(用于修改)
@Select("select * from my_user where pid = #{pid}")
MyUser selectUserById(int pid);
// 更新用户信息
@Update("update my_user set username=#{username}, password=#{password}, p_addr=#{pAddr}, " +
"gender=#{gender}, birth=#{birth} where pid=#{pid}")
void update(MyUser user);
// 删除用户
@Delete("delete from my_user where pid = #{pid}")
void delete(int pid);
}
4.4 业务逻辑层(Service)
封装业务逻辑,调用 Mapper 接口:
java
// 接口定义
package com.qcby.inforcontrollersystem.service;
import com.qcby.inforcontrollersystem.entity.MyUser;
import java.util.List;
import java.util.Map;
public interface MyUserService {
void insert(MyUser user);
List<MyUser> selectUsers();
MyUser selectUsersByUsernameAndPassword(Map<String, String> map);
MyUser selectUserById(int pid);
void update(MyUser user);
void delete(int pid);
}
// 实现类
package com.qcby.inforcontrollersystem.service.Impl;
import com.qcby.inforcontrollersystem.entity.MyUser;
import com.qcby.inforcontrollersystem.mapper.MyUserMapper;
import com.qcby.inforcontrollersystem.service.MyUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
@Service
@Transactional // 开启事务管理
public class MyUserServiceImpl implements MyUserService {
@Autowired
private MyUserMapper userMapper;
@Override
public void insert(MyUser user) {
userMapper.insert(user);
}
@Override
public List<MyUser> selectUsers() {
return userMapper.selectUsers();
}
@Override
public MyUser selectUsersByUsernameAndPassword(Map<String, String> map) {
return userMapper.selectUsersByUsernameAndPassword(map);
}
@Override
public MyUser selectUserById(int pid) {
return userMapper.selectUserById(pid);
}
@Override
public void update(MyUser user) {
userMapper.update(user);
}
@Override
public void delete(int pid) {
userMapper.delete(pid);
}
}
4.5 控制器(Controller)
处理前端请求,协调视图与数据:
(1)登录控制器(LoginController.java)
java
package com.qcby.inforcontrollersystem.controller;
import com.qcby.inforcontrollersystem.entity.MyUser;
import com.qcby.inforcontrollersystem.service.MyUserService;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.HashMap;
import java.util.Map;
@Controller
public class LoginController {
@Autowired
private MyUserService myUserService;
// 跳转到登录页
@GetMapping("/toLogin")
public String toLogin() {
return "login";
}
// 处理登录请求
@PostMapping("/login")
public String login(HttpSession session, String username, String password, Model model) {
Map<String, String> map = new HashMap<>();
map.put("username", username);
map.put("password", password);
MyUser user = myUserService.selectUsersByUsernameAndPassword(map);
if (user != null) {
// 登录成功,将用户信息存入Session
session.setAttribute("user", user);
return "redirect:/index"; // 重定向到首页
} else {
// 登录失败,回显错误信息
model.addAttribute("tip", "用户名或密码错误");
return "login";
}
}
// 退出登录
@GetMapping("/logout")
public String logout(HttpSession session) {
session.invalidate(); // 清除Session
return "redirect:/toLogin";
}
}
(2)用户管理控制器(UserController.java)
java
package com.qcby.inforcontrollersystem.controller;
import com.qcby.inforcontrollersystem.entity.MyUser;
import com.qcby.inforcontrollersystem.service.MyUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
@Controller
public class UserController {
@Autowired
private MyUserService myUserService;
// 展示用户列表
@GetMapping("/main")
public String showUserList(Model model) {
List<MyUser> users = myUserService.selectUsers();
model.addAttribute("users", users); // 存入模型,供前端渲染
return "main";
}
// 跳转到添加用户页面
@GetMapping("/add")
public String toAddPage() {
return "add";
}
// 保存新用户
@PostMapping("/save")
public String saveUser(MyUser user, @RequestParam String birth) {
try {
// 转换日期格式(前端传递字符串,需转为Date)
if (birth != null && !birth.isEmpty()) {
user.setBirth(new SimpleDateFormat("yyyy-MM-dd").parse(birth));
}
myUserService.insert(user);
} catch (ParseException e) {
e.printStackTrace();
}
return "redirect:/main"; // 重定向到列表页
}
// 跳转到修改页面(携带用户ID)
@GetMapping("/getUser")
public String toUpdatePage(@RequestParam int pid, Model model) {
MyUser user = myUserService.selectUserById(pid);
model.addAttribute("user", user); // 回显用户信息
return "update";
}
// 更新用户信息
@PostMapping("/update")
public String updateUser(MyUser user, @RequestParam String birth) {
try {
if (birth != null && !birth.isEmpty()) {
user.setBirth(new SimpleDateFormat("yyyy-MM-dd").parse(birth));
}
myUserService.update(user);
} catch (ParseException e) {
e.printStackTrace();
}
return "redirect:/main";
}
// 删除用户
@GetMapping("/delete")
public String deleteUser(@RequestParam int pid) {
myUserService.delete(pid);
return "redirect:/main";
}
}
五、前端页面实现(Thymeleaf 模板)
5.1 登录页(login.html)
html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
<link th:href="@{/css/login.css}" rel="stylesheet"> <!-- 引入CSS -->
<script th:src="@{/webjars/jquery/3.7.1/jquery.min.js}"></script> <!-- 引入jQuery -->
<script>
// 登录表单验证
function login1() {
const username = $("input[name='username']").val().trim();
const password = $("input[name='password']").val().trim();
if (!username) {
alert("请输入用户名");
return;
}
if (!password) {
alert("请输入密码");
return;
}
$("form").submit(); // 提交表单
}
</script>
</head>
<body>
<div id="login">
<div id="top">
<div id="top_left"><img th:src="@{/images/login_03.gif}" alt="系统Logo"></div>
</div>
<form th:action="@{/login}" method="post">
<div id="center">
<div id="center_middle">
<!-- 登录错误提示 -->
<div style="color: red; text-align: center" th:text="${tip}"></div>
<div id="user">
用户名:<input type="text" name="username" placeholder="请输入用户名">
</div>
<div id="password">
密码:<input type="password" name="password" placeholder="请输入密码">
</div>
<div id="btn">
<a href="#" onclick="login1()">登录</a>
<a href="#" onclick="$('form')[0].reset()">清空</a>
</div>
</div>
</div>
</form>
</div>
</body>
</html>
5.2 用户列表页(main.html)
html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>用户列表</title>
<style>
.mt { margin: 20px auto; width: 90%; border-collapse: collapse; }
.mt th, .mt td { border: 1px solid #ddd; padding: 10px; text-align: center; }
.add-btn { margin: 20px 0 0 5%; padding: 6px 12px; background: #4CAF50; color: white; text-decoration: none; }
</style>
</head>
<body>
<!-- 添加用户按钮 -->
<a th:href="@{/add}" class="add-btn">添加用户</a>
<!-- 用户列表表格 -->
<table class="mt">
<tr>
<th>用户名</th>
<th>密码</th>
<th>地址</th>
<th>性别</th>
<th>生日</th>
<th>操作</th>
</tr>
<!-- 遍历用户列表(Thymeleaf语法) -->
<tr th:each="user : ${users}">
<td th:text="${user.username}"></td>
<td th:text="${user.password}"></td>
<td th:text="${user.pAddr}"></td>
<td th:text="${user.gender == 1 ? '男' : '女'}"></td> <!-- 性别转换 -->
<td th:text="${#calendars.format(user.birth, 'yyyy-MM-dd')}"></td> <!-- 日期格式化 -->
<td>
<a th:href="@{/getUser(pid=${user.pid})}">修改</a>
<a th:href="@{/delete(pid=${user.pid})}" onclick="return confirm('确定删除?')">删除</a>
</td>
</tr>
</table>
</body>
</html>
5.3 添加用户页(add.html)
html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>添加用户</title>
<style>
.mt { margin: 30px auto; border-collapse: collapse; }
.mt td { padding: 10px; }
input { padding: 6px; width: 250px; }
</style>
</head>
<body>
<form th:action="@{/save}" method="post">
<table class="mt">
<tr>
<td>用户名</td>
<td><input type="text" name="username" required></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password" required></td>
</tr>
<tr>
<td>地址</td>
<td><input type="text" name="pAddr"></td>
</tr>
<tr>
<td>性别</td>
<td>
<input type="radio" name="gender" value="1" checked>男
<input type="radio" name="gender" value="0">女
</td>
</tr>
<tr>
<td>生日</td>
<td><input type="date" name="birth"></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="保存"></td>
</tr>
</table>
</form>
</body>
</html>
六、系统配置文件(application.yaml)
统一配置数据源、MyBatis 等参数:
spring:
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/boot_demo?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
# Druid连接池参数
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
filters: stat,wall # 开启监控和防火墙
# MyBatis配置
mybatis:
mapper-locations: classpath:mapper/*.xml # 若使用XML映射,需指定路径
type-aliases-package: com.qcby.inforcontrollersystem.entity # 实体类别名
七、系统测试与运行
- 启动项目 :运行
InforControllerSystemApplication.java
的main
方法,Spring Boot 内置 Tomcat 启动,默认端口 8080。 - 访问登录页 :浏览器输入
http://localhost:8080/toLogin
,使用初始化数据(用户名zhangsan
,密码123
)登录。 - 功能验证 :
- 登录成功后跳转至首页,展示用户列表;
- 点击 "添加用户",填写信息后保存,列表页会新增记录;
- 点击 "修改" 可更新用户信息,点击 "删除" 可移除记录;
- 未登录时直接访问
/main
会被拦截,强制跳转至登录页。