喜欢吃吗
事情的起因是这样的,宝是个略微挑食的小女生,所以我需要去记忆她对食物的相关喜好。这件事本身并不难,只是随着数量的增多,某一天我们俩一起吐槽:“感觉可以做个小网站,输入食物名称就能得到喜欢还是不喜欢的结果,这样就能随时查询了!”本是一句玩笑话,但是我事后想了想感觉完全可以做的,毕竟自己最近也一直在学习前端的东西,后端SpringBoot的框架也曾使用过只不过有段时间了,有些生疏,正好通过这个机会好好回忆一下!于是,就有了这个小项目的诞生!我先把地址放在这,可以看看效果:LikeOrNot。没有去买域名,就是简单的服务器的ip地址。下面就来回顾一下大致的开发过程和我从中学到或者回忆起来的一些东西,大致的内容应该会按照数据库、后端、前端来梳理!
数据库
数据库的建立就很简单,我只做了两个表,一个表用于存储食物的具体名称、喜好和理由,以及食物所属的类别。另一个表是食物的类别,然后主表和这个表有外键约束关系。至于为什么,可能是为未来增加功能做铺垫吧(🐶)。
数据库主要是在服务器端的配置问题,因为本身是不开放连接的。我的服务器是CentOS 7 + MySQL 5.7.24的环境配置,安装完之后设置完用户名和密码以后,登录数据库,然后运行如下命令:
grant all privileges on *.* to 'root'@'%' identified by 'password'; flush privileges; #第一个*是允许访问的数据库的名称,*表示全都允许; #第二个*是允许访问的表的名称,*表示全都允许; #root是远程登录使用的用户名; #%是指允许远程访问的ip地址,现在表示允许任意ip登录; #password是用户的登录密码; #flush privileges;是刷新数据库的意思;
后端
后端就是SpringBoot了,使用了一些工具库,诸如:JPA、MyBatis、SwaggerUI,其实这三个的详细使用方法还不是很熟练,我对JPA的认识就是让数据库中的属性可以和Java中的类相对应的工具,MyBatis就是可以将数据库的相关语句翻译成Java语句的工具,有了这两个,我们对数据库的操作就会变得简单起来。SwaggerUI则是后端和前端交互较为重要的接口文档,有了这个,前端开发人员就能较为清晰地了解到后端接口所需参数,参数含义和类型,非常好用!
SwaggerUI的相关配置如下:
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @ConditionalOnExpression("${swagger.enable:true}") //当enable为true时才选择加载该配置类 @EnableSwagger2 public class SwaggerConfig { @Bean public Docket createMainApi() { return new Docket(DocumentationType.SWAGGER_2) //.groupName("API")//如果要写多个docket,就需要为它们指定不同groupName .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("yutau.likeornot.controller"))//设定扫描范围 .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("LikeOrNot")//文档名 .description("Forbaby")//文档描述 .termsOfServiceUrl("数据源")//数据源(默认http://localhost:8080/v2/api-docs) .version("1.0.1") .build(); } }
当然,这三个都需要在pom.xml文件中进行配置,这里因为很久没写了,我还犯了一个非常可笑的错误:application.yml 中的 username 写成了 user ,导致配置出错,程序直接跳过,采用默认配置,数据库死活连不上,一直都连接的是localhost,后来在一个学长的帮助下才找到这个错误,在此表示感谢!另外,JPA如果没有实体类的话也会报错,希望注意。
前端
前端应该是个重头,我从网上找了个比较好看的登录界面的模版然后修改的,修改的最终效果呢如下:

这里主要是修改了背景的图片,换成了宝较喜欢的Kuromi,修改了右上方的图标和相关的内容。
图片设置成了半透明的,增加了background-image和opacity。爱心图标使用的是font-awesomeCSS图标库,非常好用!
这里设置了一个动态效果就是点击检测的时候右上角的爱心图标会展开成如下的样子:

这个动态效果是原版的模版做好的,但是有一个问题,在我通过jQuery增加该动态效果之后,每次点击按钮,界面都会重新刷新,这个动态效果也会立刻弹回去,这让我百思不解,最后我查阅之后发现,button每次点击都会提交表单,所以肯定会重新刷新页面,动效也就没了。于是我做了如下修改:
<!-- 添加了一个type="button" --> <button id="button" type = "button"><span>检测</span></button>
//添加了取消按钮的默认行为 e.preventDefault();
就解决了,然后就是用Ajax对后端进行调用了。
值得注意的是,本次我采用的是前后端分离的写法,但是前端的文件我是放在SpringBoot的项目里一并封装成Jar部署服务器的,因为配置了SwaggerUI之后,我们可以在项目的main文件夹下的resources下的static中放入我们的前端文件,然后在Controller中写下如下函数:
import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import springfox.documentation.annotations.ApiIgnore; /** * 主页转发静态界面 */ @Controller(value = "/") public class IndexController { @RequestMapping("/") @ApiIgnore public String index(Model model){ model.addAttribute("title", "LikeOrNot"); return "likeornot.html"; } }
这样启动SpringBoot的时候自动渲染的就是前端的界面,非常方便!当然前提是,没使用诸如Vue这样的框架,不清楚使用了还能不能行。
部署服务器之后,我们运行:
nohup java -jar likeornot.jar &
即可让程序在服务器上一直跑,而不会被清除。
至此,页面制作完毕,总的来说并不难,而且做的过程中趣味无穷,特别是在跟宝确定喜欢吃与不喜欢吃的过程中。我很享受这样的过程,在自己的能力范围内为喜欢的人做个能用上自己专业技能的事,这件事真的让我受益颇多的情况下还非常幸福,感谢宝给了我这么好的机会和创意❤️,也希望宝在接下来的生活中能尝试更多的食物,说不定原本不喜欢的就爱上了呢❤️!嘿嘿嘿!
❤️🐱!
参考:
JS阻止冒泡和取消默认事件(默认行为)
fontawesome
Spring Data JPA使用:看这一篇就够了
Linux下远程连接MySQL数据库
Github仓库:
likeornot