这个家庭食谱管理系统是我在指导计算机专业毕业设计时遇到的一个典型课题,也是很多同学会选择的方向。它本质上是一个基于SSM框架(Spring+SpringMVC+MyBatis)的Web应用,主要解决家庭场景下的食谱数字化管理问题。相比市面上的商业菜谱App,这个系统的特色在于更注重家庭成员间的协作和个性化定制。
在实际开发中,我发现很多同学容易陷入"为了用SSM而用SSM"的误区。其实这个项目的技术选型很有讲究:Spring的IoC容器非常适合管理食谱业务的各种组件依赖,SpringMVC的注解驱动开发模式能快速构建RESTful API,而MyBatis的灵活映射则能很好地处理食谱与食材这种多对多关系。下面我就结合源码实例,拆解这个系统的关键实现。
选择SSM框架组合主要基于以下考量:
注意:不建议直接使用源码中的Hibernate,对于这种中小型系统,MyBatis的SQL可控性更有优势
系统主要包含以下功能模块:
sql复制CREATE TABLE `recipe` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(100) NOT NULL,
`cover_img` VARCHAR(255),
`steps` JSON NOT NULL, -- 存储步骤图文信息
`user_id` INT NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `ingredient` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`category` ENUM('蔬菜','肉类','调味品') NOT NULL,
`nutrition_info` JSON, -- 存储营养成分数据
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
食谱与食材的关系通过中间表实现:
java复制// RecipeMapper.xml
<select id="selectRecipesWithIngredients" resultMap="recipeResultMap">
SELECT r.*, i.id as ingredient_id, i.name as ingredient_name
FROM recipe r
JOIN recipe_ingredient ri ON r.id = ri.recipe_id
JOIN ingredient i ON ri.ingredient_id = i.id
WHERE r.id = #{id}
</select>
采用基于用户的协同过滤:
java复制public List<Recipe> recommendRecipes(Integer userId) {
// 1. 获取用户历史行为数据
List<UserBehavior> behaviors = behaviorMapper.selectByUser(userId);
// 2. 计算相似用户
Map<Integer, Double> similarUsers = cfService.findSimilarUsers(userId);
// 3. 生成推荐结果
return recipeMapper.selectRecommendedRecipes(
similarUsers.keySet(),
behaviors.stream().map(b -> b.getRecipeId()).collect(Collectors.toList())
);
}
利用MyBatis的collection标签实现复杂映射:
xml复制<resultMap id="shoppingListMap" type="ShoppingList">
<id property="id" column="id"/>
<collection property="items" ofType="ShoppingItem"
select="selectShoppingItems" column="id"/>
</resultMap>
Docker Compose配置示例:
yaml复制version: '3'
services:
app:
build: .
ports:
- "8080:8080"
depends_on:
- mysql
- redis
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: recipe123
redis:
image: redis:6-alpine
可能原因及排查:
properties复制spring.servlet.multipart.max-file-size=5MB
spring.servlet.multipart.max-request-size=10MB
nginx复制client_max_body_size 10M;
确保在Service层:
java复制@Transactional(rollbackFor = Exception.class)
public void saveRecipe(RecipeDTO dto) throws Exception {
//...
}
这个项目最值得借鉴的是它对家庭场景的深度理解。比如在权限设计上,没有采用严格的RBAC模型,而是通过"家庭组"的概念实现轻量级共享。在实际开发中,建议先明确家庭成员的真实需求,再决定技术方案的复杂度。