文章目录
适合人群
学完了SSM框架
的相关知识,但是总感觉自己对于框架的使用和理解并不是很深刻,所以决定写一个项目来练习和提升自己对于框架的理解以及使用框架进行开发过程的理解
适合人群:
- 熟悉SSM框架,熟悉SSM框架开发流程
- 了解LayUI框架的基本知识
- 熟悉jQuery,jsp等技术
通过练习该项目,能够提升对于SSM框架的理解,了解项目的基本开发流程以及前后端数据的交互.
项目介绍
先看一下项目演示:
项目整体功能图
该项目是一个汽车租赁项目,登录成功后,能实现租车时的汽车出库和汽车入库,有客户管理,车辆管理,出租单管理,检查单管理等业务功能.也有客户管理,角色分配等系统功能,同时能实现对于客户,车辆,业绩的简单数据分析.
涉及的技术
- Spring,SpirngMVC,MyBatis框架(SSM)
- 前端LayUI框架,jsp,jQuery等技术
- Quartz定时任务框架
- log4j日志系统,druid数据源监控
- echarts为数据分析提供技术支持
- maven的使用
- 简单的RBAC角色分配技术
数据库设计
一.业务表
1,客户表(bus_customers)
字段名 | 字段说明 | 类型 | 是否主键 | 备注 |
---|---|---|---|---|
identity | 身份证 | varhcar | 是 | |
custname | 姓名 | Varchar | ||
sex | 性别 | Int | ||
address | 地址 | varchar | ||
phone | 电话 | varchar | ||
career | 职位 | varchar |
2,车辆表(bus_cars)
字段名 | 字段说明 | 类型 | 是否主键 | 备注 |
---|---|---|---|---|
carnumber | 车牌号 | varhcar | 是 | |
cartype | 类型 | varchar | ||
color | 颜色 | varchar | ||
price | 购买价格 | double | ||
rentprice | 出租价格 | double | ||
deposit | 押金 | double | ||
isrenting | 是否出租 | int | ||
description | 描述 | varchar | ||
carimg | 车辆图片 | varchar |
3,出租表(bus_rents)
字段名 | 字段说明 | 类型 | 是否主键 | 备注 |
---|---|---|---|---|
rentid | 出租单号 | varhcar | 是 | 后台使用时间生成 |
price | 出租实际价格 | double | ||
begindate | 开始时间 | Datetime | ||
returndate | 还车时间 | Datetime | ||
rentflag | 出租状态 | int | 0未归还1已归还 | |
identity | 客户身份证 | varchar | ||
carnumber | 车牌号 | varchar | ||
opername | 操作员 | varchar | 当前登陆人 |
4,还车表(bus_checks)
字段名 | 字段说明 | 类型 | 是否主键 | 备注 |
---|---|---|---|---|
checkid | 检查单号 | varhcar | 是 | 后台使用时间生成 |
checkdate | 检查时间 | datetime | ||
checkdesc | 描述 | varchar | ||
problem | 存在问题 | varchar | ||
paymoney | 赔付金额 | double | ||
opername | 操作员 | varchar | 当前登陆人 | |
rentid | 出租单号 | varchar |
二,系统表(RBAC权限管理)
1.菜单表(sys_menus)
字段名 | 字段说明 | 类型 | 是否主键 | 备注 |
---|---|---|---|---|
id | ID | Int | 是 | |
pid | 父节点id | Int | ||
name | 菜单名称 | varchar | ||
href | 跳转地址 | varchar | ||
open | 是否打开 | Int | 0不打1打开 | |
parent | 是否父节点 | Int | 0非父节点1父节点 | |
target | 打开方式 | varchar | ||
icon | 节点图标 | varchar | ||
tabicon | Tab图标 | varchar | ||
available | 是否可用 | Int | 0不可用1可用 |
2. 用户表(sys_users)
字段名 | 字段说明 | 类型 | 是否主键 | 备注 |
---|---|---|---|---|
userid | 用户编号 | Int | 是 | |
loginname | 登陆名 | varchar | ||
identity | 身份证号 | varchar | ||
realname | 真实名称 | varchar | ||
sex | 性别 | Int | 0女1男 | |
address | 地址 | varchar | ||
phone | 电话 | varchar | ||
pwd | 密码 | varchar | ||
position | 职位 | varchar | ||
type | 用户类型 | Int | 1,超级管理员2,系统用户Where type<>1 |
3.角色表(sys_roles)
字段名 | 字段说明 | 类型 | 是否主键 | 备注 |
---|---|---|---|---|
roleid | 角色编号 | Int | 是 | |
rolename | 角色名称 | varchar | ||
roledesc | 角色备注 | varchar |
4. 角色和菜单关系表(sys_role_menu)
字段名 | 字段说明 | 类型 | 是否主键 | 备注 |
---|---|---|---|---|
rid | 角色编号 | Int | 是 | 角色表的roleid外键 |
mid | 菜单编号 | Int | 是 | 菜单表的id外键 |
5.用户和角色和关系表(sys_role_user)
字段名 | 字段说明 | 类型 | 是否主键 | 备注 |
---|---|---|---|---|
uid | 用户编号 | Int | 是 | 用户表的userid外键 |
rid | 角色编号 | Int | 是 | 角色表的roleid外键 |
二,系统表(其它)
1.登陆日志表(sys_log_login)
字段名 | 字段说明 | 类型 | 是否主键 | 备注 |
---|---|---|---|---|
id | 日志ID | Int | 是 | |
loginname | 登陆名+真实姓名 | varchar | ||
loginip | 登陆IP | varchar | ||
logintime | 登陆时间 | datetime |
2. 系统公告表(sys_news)
字段名 | 字段说明 | 类型 | 是否主键 | 备注 |
---|---|---|---|---|
id | 编号 | Int | 是 | |
title | 标题 | varchar | ||
Content | 内容 | varchar | ||
createtime | 发布时间 | datetime | ||
opername | 发布人 | varchar |
环境的搭建
- 我使用的是IDEA的开发工具
个人感觉IDEA开发工具对于程序员比较友好,熟练的使用能够提高开发的效率
创建maven项目导入相关依赖的jar包创建对应的包
这部分比较基础,都是一些配置相关,详细的配置方法在我之前的博客文章中都有介绍,这里不赘述.
目录结构结合项目介绍
这里给出创建好的目录结构
- 将项目的包分为三个:分别是bus对应业务相关的包,sys对应系统功能相关,task对应数据分析相关.
合理的分包,程序不仅可读性强,开发也更高效
配置好开发环境:
-
创建项目
-
导入依赖
-
创建druid.properties
-
创建log4j.properties
-
创建spring-dao.xml
-
创建spring-service.xml
-
创建spring-context.xml
-
创建spring-mvc.xml
-
修改web.xml
-
创建file.properties
文件上传下载的配置文件
#file upload path config path=G:/upload/
-
创建AppListener
过滤器
package per.leiyu.sys.listener; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; @WebListener public class AppListener implements ServletContextListener{ @Override public void contextDestroyed(ServletContextEvent arg0) { } @Override public void contextInitialized(ServletContextEvent arg0) { //取到ServletContext ServletContext context=arg0.getServletContext(); context.setAttribute("leiyujia", context.getContextPath()); System.err.println("---------Servlet容器创建成功 leiyujia被放到ServletContext作用域-------"); } }
-
创建RandomUtils
产生随机数的工具类
package per.leiyu.sys.utils; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Random; import java.util.UUID; /** * 随机工具类 * @author leiyu */ public class RandomUtils { private static SimpleDateFormat sdf1=new SimpleDateFormat("yyyy-MM-dd"); private static SimpleDateFormat sdf2=new SimpleDateFormat("yyyyMMddHHmmssSSS"); private static SimpleDateFormat sdf3=new SimpleDateFormat("yyyyMMdd_HHmmss_SSS"); private static Random random=new Random(); /** * 得到当前日期 */ public static String getCurrentDateForString() { return sdf1.format(new Date()); } /** * 生成文件名使用时间+4位随机数 * @param fileName 文件名称 */ public static String createFileNameUseTime(String fileName) { String fileSuffix=fileName.substring(fileName.lastIndexOf("."),fileName.length()); String time=sdf2.format(new Date()); Integer num=random.nextInt(9000)+1000; return time+num+fileSuffix; } /** * 生成文件名使用时间+4位随机数 * @param fileName 文件名称 * @param suffix 临时文件的后缀 */ public static String createFileNameUseTime(String fileName,String suffix) { String fileSuffix=fileName.substring(fileName.lastIndexOf("."),fileName.length()); String time=sdf2.format(new Date()); Integer num=random.nextInt(9000)+1000; return time+num+fileSuffix+suffix; } /** * 生成文件名使用UUID * @param fileName 文件名称 */ public static String createFileNameUseUUID(String fileName) { String fileSuffix=fileName.substring(fileName.lastIndexOf("."),fileName.length()); return UUID.randomUUID().toString().replace("-", "").toUpperCase()+fileSuffix; } /** * 根据时间+五位随机数生成字符串 * @param preffx * @return */ public static String createRandomStringUseTime(String preffx) { return preffx+"_"+sdf3.format(new Date())+"_"+(random.nextInt(90000)+10000); } }
-
创建WebUtils
Web的工具类:
- 得到当前线程的请求对象
- 得到当前线程的响应对象
- 得到session对象
- 得到servletContext对象
package per.leiyu.sys.utils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * web的工具类 * @author leiyu */ public class WebUtils { public static ServletRequestAttributes getServletRequestAttributes() { return (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); } /** * 得到当前线程的请求对象 * @return */ public static HttpServletRequest getHttpServletRequest() { return getServletRequestAttributes().getRequest(); } /** * 得到当前线程的响应对象 */ public static HttpServletResponse getHttpServletResponse() { return getServletRequestAttributes().getResponse(); } /** * 得到session对象 */ public static HttpSession getHttpSession() { return getHttpServletRequest().getSession(); } /** * 得到servletContext对象 */ public static String getServletContext() { return getHttpServletRequest().getServletPath(); } }
-
创建AppFileUtils
文件上传下载的工具类
package per.leiyu.sys.utils; import org.apache.commons.io.FileUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.net.URLEncoder; import java.util.Properties; /** * 文件上传工具类 * @author leiyu */ public class AppFileUtils { /** * 得到文件上传的路径 */ public static String PATH="G:/upload/"; static { InputStream stream = AppFileUtils.class.getClassLoader().getResourceAsStream("file.properties"); Properties properties=new Properties(); try { properties.load(stream); PATH=properties.getProperty("path"); } catch (IOException e) { e.printStackTrace(); } } /** * 文件下载 * @param response * @param path * @param oldName * @return */ public static ResponseEntity<Object> downloadFile(HttpServletResponse response, String path, String oldName) { //4.使用绝对路径+相对路径去找到文件对象 File file=new File(AppFileUtils.PATH,path); //5.判断文件是否存在 if(file.exists()) { try { try { //如果名字有中文 要处理编码 oldName=URLEncoder.encode(oldName,"UTF-8"); } catch (Exception e) { e.printStackTrace(); } //把file转成一个bytes byte[] bytes=FileUtils.readFileToByteArray(file); HttpHeaders header=new HttpHeaders(); //封装响应内容类型(APPLICATION_OCTET_STREAM 响应的内容不限定) header.setContentType(MediaType.APPLICATION_OCTET_STREAM); //设置下载的文件的名称 header.setContentDispositionFormData("attachment",oldName); //创建ResponseEntity对象 ResponseEntity<Object> entity = new ResponseEntity<Object>(bytes,header,HttpStatus.CREATED); return entity; } catch (Exception e) { e.printStackTrace(); } return null; }else { PrintWriter out; try { out = response.getWriter(); out.write("文件不存在"); out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); } return null; } } /** * 根据相对路径删除硬盘上文件 * @param path */ public static void deleteFileUsePath(String path) { String realPath=PATH+path; //根据文件 File file=new File(realPath); if(file.exists()) { file.delete(); } } /** * 更改文件名 * @param carimg * @param suffix */ public static String updateFileName(String carimg,String suffix) { //找到文件 try{ File file = new File(PATH,carimg); if (file.exists()){ file.renameTo(new File(PATH,carimg.replace(suffix,""))); return carimg.replace(suffix,""); } }catch (Exception e){ e.printStackTrace(); } return null; } /** * 根据路径删除图片 * @param carimg */ public static void removeFileByPath(String carimg) { //找到文件 try{ File file = new File(PATH,carimg); if (file.exists()){ file.delete(); } }catch (Exception e){ e.printStackTrace(); } } }
这篇博客主要是数据库环境和java开发环境的搭建
下一篇博客开始详细开发流程的详细介绍.
你问为什么不把开发流程和项目环境搭建放在一起?
先理解SSM最基础的技术(当时我环境搭建也是搞了很久才搞明白(尤其是maven的依赖),可能是因为笨吧
)
我是雷雨,一个
普本科
的学生,主要专注于Java后端和大数据开发
如果这篇文章有帮助到你,希望你给我一个
大大的赞
如果有什么问题,希望你能留言
和我一起研究
,学习靠自觉,分享靠自愿
PATH,carimg);
if (file.exists()){
file.delete();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
```
不知不觉1w多字了,这篇博客主要是数据库环境和java开发环境的搭建.
下一篇博客开始详细开发流程的详细介绍.
你问为什么不把开发流程和项目环境搭建放在一起?
先理解SSM最基础的技术(当时我环境搭建也是搞了很久才搞明白(尤其是maven的依赖),可能是因为笨吧
)
我是雷雨,一个
普本科
的学生,主要专注于Java后端和大数据开发
如果这篇文章有帮助到你,希望你给我一个
的赞
如果有什么问题,希望你能评论区
和我一起研究
.
如果您要转载请转载注明出处
https://blog.csdn.net/qq_40742223