作为一名有十年开发经验的Java全栈工程师,我经常被问到如何开发一个完整的图书馆管理系统。这个基于Java的图书馆管理系统是我为大学生毕业设计开发的一个典型案例,采用了当前主流的Spring Boot+Vue前后端分离架构,整合了MyBatis Plus、Shiro等常用框架,实现了图书管理、借阅管理、用户管理等核心功能模块。
这个系统特别适合作为计算机相关专业的毕业设计项目,因为它:
在技术选型上,我采用了目前Java Web开发中最流行的技术组合:
后端技术栈:
前端技术栈:
这种技术组合的选择基于以下几个考虑:
系统采用典型的三层架构设计:
表现层(Presentation Layer):
业务逻辑层(Business Logic Layer):
数据访问层(Data Access Layer):
这种分层架构的优势在于:
用户管理是系统的基础模块,实现了完整的RBAC(基于角色的访问控制)模型。
关键实现点:
java复制@Data
@TableName("sys_user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String username;
private String password;
private String salt;
private String realName;
private String avatar;
private String email;
private String mobile;
private Integer status;
private Long deptId;
private LocalDateTime createTime;
// 省略getter/setter
}
java复制public class PasswordUtil {
public static String encrypt(String password, String salt) {
return new Md5Hash(password, salt, 2).toString();
}
public static boolean verify(String password, String salt, String encryptedPassword) {
return encrypt(password, salt).equals(encryptedPassword);
}
}
java复制@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/login", "anon");
filterMap.put("/logout", "logout");
filterMap.put("/**", "authc");
factoryBean.setFilterChainDefinitionMap(filterMap);
return factoryBean;
}
}
注意事项:
图书管理是系统的核心模块,实现了图书的CRUD、分类管理、库存管理等功能。
关键实现点:
java复制@Data
@TableName("book")
public class Book {
@TableId(type = IdType.AUTO)
private Long id;
private String isbn;
private String title;
private String author;
private String publisher;
private LocalDate publishDate;
private Integer categoryId;
private Integer totalCopies;
private Integer availableCopies;
private String coverImage;
private String description;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}
java复制@Data
@TableName("book_category")
public class BookCategory {
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private Integer parentId;
private Integer sort;
private String remark;
}
java复制@RestController
@RequestMapping("/api/book")
public class BookController {
@Autowired
private BookService bookService;
@GetMapping("/search")
public Result search(
@RequestParam(required = false) String keyword,
@RequestParam(required = false) Integer categoryId,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
if (StringUtils.isNotBlank(keyword)) {
queryWrapper.like("title", keyword)
.or().like("author", keyword)
.or().like("isbn", keyword);
}
if (categoryId != null) {
queryWrapper.eq("category_id", categoryId);
}
Page<Book> page = new Page<>(pageNum, pageSize);
IPage<Book> bookPage = bookService.page(page, queryWrapper);
return Result.success(bookPage);
}
}
常见问题处理:
java复制public class ISBNValidator {
public static boolean isValidISBN(String isbn) {
// 实现ISBN校验逻辑
}
}
图书借阅是系统的核心业务流程,主要包含以下几个步骤:
关键数据库表设计:
sql复制CREATE TABLE `borrow_record` (
`id` bigint NOT NULL AUTO_INCREMENT,
`book_id` bigint NOT NULL,
`user_id` bigint NOT NULL,
`borrow_time` datetime NOT NULL,
`due_time` datetime NOT NULL,
`return_time` datetime DEFAULT NULL,
`status` tinyint NOT NULL COMMENT '0-申请中 1-已借出 2-已归还 3-已逾期 4-已取消',
`operator_id` bigint DEFAULT NULL,
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_book_id` (`book_id`),
KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
sql复制CREATE TABLE `overdue_record` (
`id` bigint NOT NULL AUTO_INCREMENT,
`borrow_id` bigint NOT NULL,
`user_id` bigint NOT NULL,
`overdue_days` int NOT NULL,
`fine_amount` decimal(10,2) NOT NULL,
`is_paid` tinyint NOT NULL DEFAULT '0',
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_borrow_id` (`borrow_id`),
KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
核心借阅逻辑:
java复制@Service
@Transactional
public class BorrowServiceImpl implements BorrowService {
@Autowired
private BookMapper bookMapper;
@Autowired
private BorrowRecordMapper borrowRecordMapper;
@Override
public Result borrowBook(Long bookId, Long userId) {
// 检查图书库存
Book book = bookMapper.selectById(bookId);
if (book == null) {
return Result.error("图书不存在");
}
if (book.getAvailableCopies() <= 0) {
return Result.error("图书已借完");
}
// 检查用户借阅资格
if (!checkBorrowQualification(userId)) {
return Result.error("您当前无法借阅更多图书");
}
// 创建借阅记录
BorrowRecord record = new BorrowRecord();
record.setBookId(bookId);
record.setUserId(userId);
record.setBorrowTime(LocalDateTime.now());
record.setDueTime(LocalDateTime.now().plusDays(30));
record.setStatus(0); // 申请中
record.setCreateTime(LocalDateTime.now());
record.setUpdateTime(LocalDateTime.now());
borrowRecordMapper.insert(record);
return Result.success("借阅申请已提交,请等待管理员审核");
}
private boolean checkBorrowQualification(Long userId) {
// 实现用户借阅资格检查逻辑
return true;
}
}
归还逻辑实现:
java复制@Override
public Result returnBook(Long recordId, Long operatorId) {
BorrowRecord record = borrowRecordMapper.selectById(recordId);
if (record == null) {
return Result.error("借阅记录不存在");
}
if (record.getStatus() != 1) {
return Result.error("图书未借出,无需归还");
}
// 更新借阅记录
record.setReturnTime(LocalDateTime.now());
record.setStatus(2); // 已归还
record.setOperatorId(operatorId);
record.setUpdateTime(LocalDateTime.now());
borrowRecordMapper.updateById(record);
// 更新图书库存
Book book = bookMapper.selectById(record.getBookId());
book.setAvailableCopies(book.getAvailableCopies() + 1);
bookMapper.updateById(book);
// 检查是否逾期
checkOverdue(record);
return Result.success("图书归还成功");
}
注意事项:
Shiro配置示例:
java复制@Bean
public Realm realm() {
UserRealm realm = new UserRealm();
realm.setCredentialsMatcher(credentialsMatcher());
return realm;
}
@Bean
public HashedCredentialsMatcher credentialsMatcher() {
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("md5");
matcher.setHashIterations(2);
matcher.setStoredCredentialsHexEncoded(true);
return matcher;
}
缓存配置示例:
java复制@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(1))
.disableCachingNullValues()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
return RedisCacheManager.builder(factory)
.cacheDefaults(config)
.transactionAware()
.build();
}
}
开发环境:
生产环境建议:
bash复制# 创建数据库
CREATE DATABASE library DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
# 导入SQL脚本
mysql -u root -p library < library.sql
bash复制# 打包
mvn clean package -DskipTests
# 运行
java -jar library-system.jar --spring.profiles.active=prod
bash复制# 安装依赖
npm install
# 构建生产环境代码
npm run build
# 部署到Nginx
cp -r dist/* /usr/share/nginx/html/library/
Nginx配置示例:
nginx复制server {
listen 80;
server_name library.example.com;
location / {
root /usr/share/nginx/html/library;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
在开发这个图书馆管理系统的过程中,我积累了一些宝贵的经验,特别适合准备做毕业设计的同学参考:
常见问题解决方案:
java复制// 使用Java 8的日期时间API
LocalDate today = LocalDate.now();
LocalDateTime now = LocalDateTime.now();
// 日期格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = now.format(formatter);
java复制// MyBatis Plus分页查询
Page<User> page = new Page<>(current, size);
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("status", 1);
IPage<User> userPage = userService.page(page, wrapper);
// 避免count查询
Page<User> page = new Page<>(current, size, false);
java复制@Service
public class BookService {
@Transactional(rollbackFor = Exception.class)
public void borrowBook(Long bookId, Long userId) {
// 借阅逻辑
}
}
这个图书馆管理系统项目涵盖了企业级应用开发的完整流程和技术要点,从需求分析、系统设计、编码实现到测试部署。对于计算机专业的同学来说,深入理解这个项目的设计和实现,能够帮助你掌握现代Java Web开发的核心技术栈,为未来的职业发展打下坚实基础。