尧图精选

JavaWeb课程设计实战:JSP+Servlet+JDBC实现共享租车信息管理系统

🕒 发布时间:2026/10/2 14:24:13 📁 来源:尧图网络
你有没有过这种经历接手一个“看起来简单”的JavaWeb课程设计题目真上手才发现从数据库表设计到Servlet跳转再到JSP页面取值每一步都是坑。最近正好做完一个“共享租车信息管理系统”用的就是javajspservletjdbcmysql这套经典组合很多同学问我要源码和思路我干脆把这套从零搭建的过程完整拆开讲一遍。这篇文章适合正在做JavaWeb课程设计、毕业设计或者想搞懂传统JSP项目内部原理的人。不需要Spring不需要Maven全家桶把最朴素的ServletJDBC玩明白项目一样能跑得顺背后的原理你还能讲得比用框架的人更清楚。1. 系统整体设计与技术选型1.1 为什么还选JSPServlet这套经典组合很多同学一上来就问为什么不用Spring Boot毕竟现在企业里都是SpringBootMyBatis的天下了。但你要想明白一件事课程设计考察的是你对JavaWeb底层原理的掌握程度而不是你调用框架的能力。用JSPServletJDBC写一套管理系统你能亲手摸到一次HTTP请求从浏览器到Servlet再到数据库的完整链路这是框架封装掉的东西恰恰是面试最常问的部分。另外共享租车这个业务本身不复杂。用户注册登录、浏览车辆、下单租车、归还结算、后台管理车辆和订单这么几个核心模块用Servlet完全扛得住。技术选型的核心逻辑是业务复杂度决定了你不需要重型框架反而轻量方案开发更快、部署更简单、出问题也好排查。这套项目在Tomcat上跑起来非常轻不用配Maven私服不用管一堆依赖冲突。把WAR包丢进webapps目录启动Tomcat完事。我做的时候甚至直接用Eclipse或IDEA自带的Tomcat插件考试省去了很多环境折腾的时间。1.2 共享租车业务的表结构设计表结构才是一个管理系统的灵魂。代码烂一点能跑表设计差了整个项目直接报废。我做这套租车系统时把核心表分为四张用户表、车辆表、订单表、管理员表简洁但覆盖了所有业务。用户表t_user字段我这么定义id自增主键、username唯一索引、password建议MD5加密存储、real_name、phone、id_card身份证号租车行业实名认证必须、driver_license_no驾照编号、create_time。这里要特别说明的是username加唯一索引能防重另外id_card和driver_license_no是租车业务特有的字段正常用户注册时别强制填但在下单前必须补齐这个逻辑后边会讲。车辆表t_car字段包括id、plate_no车牌号也设唯一索引、brand品牌、model车型、seat_num座位数、transmission手动/自动、fuel_type汽油/柴油/电动、status0未出租/1已出租、price_per_day日租金、image_url车辆图片地址、create_time。订单表t_order是整个系统业务流的核心id、order_no订单编号可以用时间戳随机数生成、user_id外键关联用户表、car_id外键关联车辆表、rent_start_time、rent_end_time、total_price、status订单状态用int标识0待支付、1已支付/租用中、2已归还待结算、3已取消、4已完成、create_time。管理员表t_admin就是简单的id、username、password、real_name后台登录用。这里不得不提一个实战中容易翻车的点MySQL表名和字段名别用中文也别用MySQL保留字比如order是保留字status在MySQL 8.0也是保留字建议字段名加前缀或者统一命名成order_status这类不然写SQL时各种报错。1.3 三层分层与项目目录规划JSPServlet项目虽然没有Spring帮你管理分层但你在编码时心里必须有一条清晰的线JSP只负责展示、Servlet只负责接收请求和转发、JDBC层只负责数据库操作。我习惯把项目按这个目录结构来组织src/ ├── com.rental.dao // 数据访问层对接数据库 ├── com.rental.entity // 实体类映射四张表 ├── com.rental.service // 业务逻辑层处理判断 ├── com.rental.servlet // Servlet控制层接收请求 ├── com.rental.util // 工具类比如DBUtil、MD5Util └── com.rental.filter // 过滤器登录权限控制 web/ ├── admin/ // 后台管理页面 ├── user/ // 前台用户页面 ├── common/ // 公共页面登录、注册等 ├── static/ // css、js、图片 └── index.jsp这样的划分虽然比Spring多写几个类的代码但改起来非常舒服。拿查询车辆列表举例JSP发出请求到CarListServletServlet调CarService的list方法Service里内聚了status0这类查询逻辑CarDAO负责拼SQL和结果集映射。每一层各管各的事出了问题一根线就能定位。我还建议写一个统一的DBUtil工具类把Connection、Statement、ResultSet的关闭写成close()方法避免几十个DAO类里出现重复的连库和关库代码。这一点在后续小节会详细展开。2. 核心基础设施数据库连接与JDBC封装2.1 数据库连接池的选择与配置JDBC最原始的方式就是每次请求都拿DriverManager.getConnection去MySQL建连接。但这在开发时还好一旦系统同时涌进几十个请求数据库连接反复创建和销毁很容易把MySQL搞崩。课程设计虽然不会遇到高并发但用连接池是专业性的体现面试时提这个能加分不少。我用的是DBCP连接池。配置方式也很简单在WEB-INF下放一个dbcp.propertiesdriverClassNamecom.mysql.cj.jdbc.Driver urljdbc:mysql://localhost:3306/rental_car?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai usernameroot passwordyourpassword initialSize10 maxTotal20 maxIdle10 minIdle5 maxWaitMillis3000每次从连接池拿连接用完还回连接池效率比裸建连接高一个量级。注意URL里serverTimezoneAsia/Shanghai是MySQL 8.x必须加的不加会报时区错误useSSLfalse表示关闭SSL握手本地开发别开SSL握手浪费时间和性能。还有一点细节连接池参数initialSize和maxTotal分别代表初始连接数和最大连接数课程设计场景10个初始、20个最大足够了。你要是用IDEA做项目去Maven仓库下载的commons-dbcp2包要和commons-pool2版本匹配这两兄弟不匹配时会直接启动报异常。2.2 JDBC通用DAO层的封装技巧最让我心疼的就是看到有人把JDBC代码写得又臭又长一个查询用户列表的方法里三行建连接、五行写SQL、八行处理结果集最后还要catch三个异常一个类的代码量80%都是在处理连接和资源关闭。我建议封装一个BaseDAO把重复逻辑全收走子类只要传SQL和参数就行。核心方法就两个query和update。query方法里用PreparedStatementJava 7之后可以直接用try-with-resources处理资源关闭代码干净很多。public class BaseDAO { protected T ListT query(String sql, Object[] params, RowMapperT mapper) throws SQLException { ListT list new ArrayList(); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { if (params ! null) { for (int i 0; i params.length; i) { ps.setObject(i 1, params[i]); } } try (ResultSet rs ps.executeQuery()) { while (rs.next()) { list.add(mapper.mapRow(rs)); } } } return list; } protected int update(String sql, Object[] params) throws SQLException { try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { if (params ! null) { for (int i 0; i params.length; i) { ps.setObject(i 1, params[i]); } } return ps.executeUpdate(); } } }RowMapper是个函数式接口子类里传入Lambda表达式就行public ListCar listAvailableCars() throws SQLException { String sql SELECT * FROM t_car WHERE status 0; return query(sql, null, rs - { Car car new Car(); car.setId(rs.getInt(id)); car.setPlateNo(rs.getString(plate_no)); // 其他字段映射... return car; }); }这样做的好处特别实际新增一张表要写DAO时你只需要关心SQL语句和字段映射逻辑连接管理、结果集遍历、异常处理这些纯体力活全部复用BaseDAO。我写完整套系统五个DAO类只花了不到两小时主要时间全花在了SQL和业务逻辑上。一定要记住JDBC操作里参数必须用PreparedStatement的?占位符不能String拼SQL。第一防SQL注入第二带引号的字符串值不会被MySQL解析错。我在给其他同学review代码时看到有人把用户输入的搜索关键词直接拼进SQL这是安全意识薄弱的表现课程设计也得有职业操守。2.3 实体类与业务对象映射细节实体类的字段命名要和数据库字段对应这是JavaBean规范的基本要求。但有两个映射细节我要重点提醒。第一个是日期类型。MySQL的DATETIME字段对应Java侧的java.sql.Timestamp或java.util.Date都可以但JSP页面用EL表达式直接输出Date对象时会显示成一串英文格式很难看。我通常在实体类里多写一个字符串格式化字段或者直接加一个getFormatCreateTime()方法返回new SimpleDateFormat(yyyy-MM-dd HH:mm).format(createTime)。第二个是枚举状态的映射。数据库里status用int存储但实体类里如果把status声明为intJSP页面判断逻辑会很绕。我建议实体类中声明为int同时提供一个状态下标的常量配置类public class OrderStatus { public static final int UNPAID 0; public static final int PAID 1; public static final int RETURNED 2; public static final int CANCELLED 3; public static final int COMPLETED 4; }这样在Java逻辑里判断订单状态时直接if (order.getStatus() OrderStatus.PAID)代码可读性瞬间提高一个档次。团队成员之间协作时看到OrderStatus类就知道订单状态有哪些取值不用翻数据库脚本。实体类建议都用封装类型而非基本类型用Integer不用int用Double不用double。原因很简单数据库里某条记录的字段可能是NULL查询结果映射到基本类型时会NPE封装类型为null反而能如实反映数据状态后边业务判断还能用 null做条件。3. 从请求到响应Servlet层设计与实现3.1 Servlet请求分发与路由设计Servlet层最大的坑就是“一个功能一个Servlet”结果项目里出现二十几个Servlet类类名乱成一片。我推荐两种设计思路都很适合课设规模第一种是一个模块一个Servlet第二种是纯路由分发加统一Servlet。我用的是第一种思路车辆模块全走CarServlet订单模块全走OrderServlet用户模块全走UserServlet。每个Servlet的doGet和doPost里通过request.getParameter(action)来区分具体功能。WebServlet(/order) public class OrderServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String action req.getParameter(action); if (list.equals(action)) { myOrders(req, resp); } else if (detail.equals(action)) { orderDetail(req, resp); } else if (pay.equals(action)) { payOrder(req, resp); } else if (cancel.equals(action)) { cancelOrder(req, resp); } else if (create.equals(action)) { createOrder(req, resp); } } }URL长这样/order?actioncreatecarId12。好处很明显第一管理Servlet数量一个业务域一个入口第二新增功能只需要在Servlet里加个action分支和一个方法不用新建类第三维护时找代码直接定位到对应Servlet就行。这里强烈建议用WebServlet(/order)注解省得再去web.xml里配servlet-mapping。用注解标注URL路径之后系统启动时Tomcat自动扫描注册。但要注意一点如果你在类上写WebServlet注解同时又把这个类配置进了web.xml启动时会报“重复映射”错误。还有个细节doGet和doPost不要各自写各自的逻辑最好在doGet里加一行doPost(req, resp)或者反过来。因为前端页面有时候用GET请求跳转比如a标签有时候用POST表单提交操作同一个业务功能时两个方法都指向同一段逻辑才不会出问题。3.2 车辆管理功能的Servlet实现细节车辆管理是管理员后台的核心包含车辆列表查询、新增车辆、编辑车辆、删除车辆、上下架等操作。这部分我拆解一下新增车辆和列表分页的完整逻辑。新增车辆的Servlet处理流程是这样管理员在admin/car_add.jsp页面上填写车辆信息表单提交到/car?actionadd。Servlet先接收车牌号、品牌、车型、日租金等参数做基本的非空校验然后调用CarService的addCar方法。在Service里要做的业务判断包括车牌号是否已存在查一次数据库、日租金是否是正数、座位数是否在合理范围内2-9座。车牌号查重用的是一个CarDAO.getByPlateNo(String plateNo)方法返回是Car对象还是null来判断。这里有个常被忽略的坑用户从表单提交的车牌号可能带空格或者车牌号里的英文字母大小写不一致。我一般在Service里先统一处理成大写无空格再入库比如StringUtils.trim(plateNo).toUpperCase()这类脏数据清洗逻辑放在Service层最合适。车辆列表分页的实现也是必考知识点。页面通过/car?actionlistpageNum1请求Servlet解析pageNum默认第1页每页显示8条这个值可以做成常量。Service层要返回两个东西当前页车辆列表、总记录数。然后计算总页数totalPages (totalCount pageSize - 1) / pageSize把列表、当前第几页、总页数存进request域转发到list页面。分页的SQL核心就是LIMIT ?, ?String sql SELECT * FROM t_car ORDER BY id DESC LIMIT ?, ?; int offset (pageNum - 1) * pageSize;第一页是LIMIT 0, 8第二页LIMIT 8, 8第三页LIMIT 16, 8。首页、上一页、下一页、末页四个按钮对应的URL逻辑很好写注意JSP页面上翻页时把当前查询条件品牌、状态也拼进URL不然翻一页条件就丢了。3.3 会话管理与登录权限控制登录权限这块我见过太多课设项目是空的——所有页面都能随便访问后台也裸奔。但凡要求严格一点的老师看到这个直接降档打分。我的方案是用Filter来做统一登录验证。写一个LoginFilter在web.xml里配置过滤路径需要保护的路径比如/admin/*和/order/*都走过滤器。逻辑很简单从session里取当前用户信息如果取不到就跳转登录页取到了就放行。WebFilter(urlPatterns {/admin/*, /order/*, /user/*}) public class LoginFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req (HttpServletRequest) request; HttpServletResponse resp (HttpServletResponse) response; HttpSession session req.getSession(false); Object user session ! null ? session.getAttribute(loginUser) : null; if (user null) { resp.sendRedirect(req.getContextPath() /login.jsp); return; } chain.doFilter(request, response); } }这里容易踩的坑有两个。第一个是req.getSession()和req.getSession(false)的区别getSession()如果session不存在会强制创建一个getSession(false)只在已存在时返回避免每次未登录请求都新建无意义的session。第二个是admin路径下要区分管理员角色普通用户登录了也不能进后台所以在Filter里还得判断登录对象是不是管理员把登录用户存进session时我习惯存一个包含角色信息的User对象字段role1表示管理员、role0表示普通用户Filter里判断user.getRole()1才放行。登录成功后别忘记做一件事更新session里的用户信息。比如用户下单后产生了订单数据有些姓名和手机号是从session里的User对象取的如果你不更新用户改完资料后界面上还是旧信息要重新登录才生效。4. 前端与后端交互JSP页面开发实战4.1 JSP页面布局与JSTL/EL表达式实践JSP页面最大的毛病就是Java代码和HTML混写一个页面里三四段% %看起来像山东煎饼夹意大利面——完全不搭。现代JSP开发讲究“页面中尽量不要出现Scriptlet”所有Java操作逻辑都放到Servlet里完成JSP只通过JSTL标签和EL表达式取值和循环遍历。EL表达式取值${car.brand}在后台其实就是找car.getBrand()方法所以实体类的getter方法必须写对。JSTL循环遍历车辆列表时c:forEach的格式要记熟c:forEach items${carList} varcar tr td${car.plateNo}/td td${car.brand}/td td${car.pricePerDay}元/天/td td c:if test${car.status 0}可租/c:if c:if test${car.status 1}已租/c:if /td /tr /c:forEach要在HTML页面里跑JSTL必须在JSP顶部引入标签库% taglib prefixc urihttp://java.sun.com/jsp/jstl/core %忘写这一行然后页面上一堆JSPG0048E之类的报错或者直接显示标签代码是JSP新手最常踩的坑。JSTL标准库的jar包Tomcat不自带需要你自己把jstl-1.2.jar放进WEB-INF/lib目录。我特别推荐一个习惯JSP页面用纯HTML静态页面进行视觉设计最后再把动态数据用EL表达式替换进去。这样做的好处是前端效果在浏览器里先用假数据跑通再改JSP页面出问题的时候你至少能确定不是HTML本身写错了。4.2 车辆列表页的分页与搜索实现车辆列表页是做这个系统时花时间最多的页面。它要满足三个需求默认展示所有可租车辆、支持按品牌筛选、支持分页。这三个需求组合起来页面上查询条件和当前页码的传递就必须处理好。我的做法是这样设计URL参数/car?actionlistbrand现代pageNum2。list page页面上每次翻页都要把当前选择的条件带上不然筛完品牌翻页后条件就丢了。搜索表单提交时带的是brand和pageNum两个参数排序方式可以加一个sortprice_asc参数对应SQL里ORDER BY price_per_day ASC。写分页SQL时要注意LIMIT的count参数类型是整型preparedStatement里传字符串参数也能隐式转换但最好搞干净。分页条底部显示共页 第页我一般用pageNum、totalPages两个字段在JSP里通过c:choose控制首页/上一页/下一页/末页四个按钮的显示状态——第一页隐藏上一页最后一页隐藏下一页。筛选条件动态拼SQL是另一个常考的点。我用了一个取巧但正规的方式先定义基础SQLSELECT * FROM t_car WHERE status 0有品牌条件就追加AND brand ?有价格区间就追加AND price_per_day BETWEEN ? AND ?。参数全部放进List里最后转成数组传给BaseDAO。这样的代码虽然不如MyBatis动态SQL优雅但逻辑在这套体系里已经算很清晰了。4.3 表单提交与数据回显细节表单提交和数据回显是判断一个JavaWeb项目开发经验是否老练的分界线。合格的项目能在一张表单页面上做到三件事表单校验、错误信息显示、提交失败后原数据回显。举个例子管理员新增车辆时如果某个字段填错了比如车牌号重复后端Service抛出异常后会forward回car_add.jsp。这时候又要做数据回显又要在页面上显示错误提示。我的做法是在Servlet里把用户提交的参数重新setAttribute传回request域再从Request域里读取回显到表单的value属性req.setAttribute(car, car); // car是未入库前从表单收集到的实体 req.setAttribute(errorMsg, 车牌号已存在请检查); req.getRequestDispatcher(/admin/car_add.jsp).forward(req, resp);JSP表单里的value写${car.plateNo}如果car为null显示空。${errorMsg}用c:if判断非空时显示一个红色的错误提示div。这种模式在所有add和edit页面都可以复用。注意一个关键分界线回显时用request.setAttribute转发到JSP而登录成功后跳转页面用response.sendRedirect。前者的浏览器URL不会变适合传递数据后者会发起新请求适合完成操作后的页面转向。如果你在用forward的地方用了redirect数据传不过去在应该用redirect的地方用了forward用户刷新页面时会反复提交表单。这两个概念搞不清楚做JavaWeb项目寸步难行。5. 完整业务流程与关键功能卡片5.1 租车业务的核心流程闭环共享租车系统的核心业务流程我用一条线串起来是这样的注册登录 → 浏览车辆 → 选择车辆下单 → 支付 → 到店取车 → 驾驶使用 → 归还车辆 → 结算押金和费用 → 完成订单。课程设计能不能拿高分就看这条闭环是否完整、状态流转是否正确。订单状态的变化是这条闭环的中枢。我的订单状态字段有五个值0待支付、1已支付租用中、2待结算已归还但费用未确认、3已取消、4已完成。每次状态变更都必须满足前置状态条件不能乱跳。比如用户点取消订单前提是订单处于待支付状态车辆归还后管理员确认费用订单才能从1变为2再确认结算变成4。这些状态判断写在哪一层学生经常搞混。我强调一下状态流转的条件判断要写在Service层不能在Servlet里写。举个例子用户支付订单时有个常见漏洞如果用户反复点击支付按钮订单状态已经是“已支付”了再点一次就多扣一次钱。Service层的支付方法里要先查订单当前状态只有status0时才执行更新SQL并把车辆状态改为已租这样并发或者连点也只会成功一次。5.2 订单创建与支付环节简化处理订单创建是用户下单时调用的核心逻辑。流程里有两个容易忽略的点第一创建订单时必须校验车辆仍处于可租状态。这个查询和插入订单之间没有事务在高并发时可能会超卖但课设里通过在Service层加一条SELECT ... FOR UPDATE锁或先update再验证受影响行数就能规避。我用的方案是update车辆状态时先设置条件status0int rows carDAO.updateStatusToRented(carId); // SQL: UPDATE t_car SET status1 WHERE id? AND status0 if (rows 1) { // 说明车辆状态成功从0改为1车辆确实可租 orderDAO.insertOrder(order); } else { // 说明车辆已经被租提示用户 throw new BusinessException(该车辆已被预订); }这句UPDATE ... WHERE status0是原子操作能防止两个用户同时租同一辆车。这是我在实际项目中用到过、在课设里又能讲清楚的并发控制小技巧值得写在注释里。支付环节我在项目里是用一个模拟支付的页面点击“确认支付”后直接把订单状态改为已支付。没有对接真实的支付SDK因为那是另一个复杂度。但我在支付成功后会顺手完善两件事写一条支付流水到t_payment表同时生成一个6位数的取车码存到订单记录里。取车码在业务里对应线下验车环节有了这个细节整个系统做演示时就显得很完整。5.3 车辆归还与费用结算逻辑归还车辆是反向的业务操作。用户在归还页面填入取车时间、归还时间系统根据日租金和超时费用计算总价。这里我设计了两档计费基础费用最小单位是天超出部分按小时计价超过6小时按一天计费。long rentDays (returnTime - getCarTime) / (1000 * 60 * 60 * 24); long extraHours (returnTime - getCarTime) % (1000 * 60 * 60 * 24) / (1000 * 60 * 60); long totalDays rentDays (extraHours 6 ? 1 : 0); double totalPrice totalDays * car.getPricePerDay();这里的日期计算是Java时间处理的基本功用Date的getTime相减再取整就能算出天数。演示的时候你可以故意选择一个还车晚了几小时的时间验证费用增加逻辑对不对。千万别在Service里直接写死一个天数演示和代码评审时这几行动态计算是很大的加分项。结算完成之后把订单状态从2改为4同时把车辆状态恢复为0可租。这个“归还车辆后自动释放车辆状态”的逻辑必须保证执行不然就会出现一辆已经归还的车还在列表里显示“已租”的情况。我提个醒这个业务查询只要涉及到修改两张表就应该放在同一个事务里。BaseDAO里如果顺序执行两个DAO中间出了异常会导致一边成功一边失败。正确做法是手动开启事务Connection conn DBUtil.getConnection(); conn.setAutoCommit(false); try { ...; conn.commit(); } catch { conn.rollback(); }。6. 常见问题排查与作业技巧6.1 连接MySQL时的乱码与SSL问题这套技术栈最经典的报错我帮你全部罗列出来。第一个是MySQL连接URL里没带SSL参数导致的SSL connection error解决方式是URL后面加useSSLfalse第二个是中文字符乱码可能的原因有三个维度任何一个没配置都会乱码JSP页面编码、请求参数编码、数据库连接编码。JSP页面顶部加% page contentTypetext/html;charsetUTF-8 languagejava %Servlet里对POST请求加上request.setCharacterEncoding(UTF-8)数据库连接URL里加useUnicodetruecharacterEncodingutf8。三层都对了中文才不会变问号。还有GET请求的中文参数乱码问题这是因为Tomcat 8默认GET编码还是ISO-8859-1可以通过在Tomcat的server.xml的Connector上加URIEncodingUTF-8解决。这个坑不遇到一次你根本不知道在哪调现在记住了就少走很多弯路。时区问题报错原文是The server time zone value Öйú±ê׼ʱ¼ä is unrecognized中文环境下MySQL 8的默认时区会造成JDBC驱动识别不了URL上加serverTimezoneAsia/Shanghai即可。这三个问题互相独立但经常三个一起爆把它们叠在同一行URL都配上就能安安稳稳跑数据库。6.2 传统JSP项目打包与部署问题课程设计最后一步通常是打包部署。很多学生是用IDEA/Eclipse里的Tomcat直接启动可一旦换了机器整个项目就起不来了。我更建议学会打WAR包部署到独立Tomcat这也是企业里老项目的常规操作。在IDEA里打包WAR的艺术在于Project Structure → Artifacts → Web Application: Archive → 勾选Build on make然后Build菜单里点击Build Artifact。生成的WAR文件在out/artifacts目录下把这个WAR文件拷到Tomcat的webapps目录启动Tomcat会自动解压部署。如果提示端口占用去conf/server.xml改掉8080端口就行。还有一类同学在部署到服务器时发现页面可以打开但数据全是空的排查思路是先连一下MySQL看服务是否在跑然后检查数据库名、用户名、密码是否和dbcp.properties一致最后看防火墙是否放行了3306端口。按这个顺序排查90%的部署问题都能解决。MySQL允许远程连接还需要在MySQL里执行GRANT ALL PRIVILEGES ON *.* TO root% IDENTIFIED BY password默认root只允许localhost访问。6.3 这类JavaWeb课程设计项目的加分技巧做课设除了功能跑通还要想着怎么在展示和答辩时把亮点打出来。我从自己的体会出发分享几个加分项。第一做一个好看的数据统计页。管理员首页放几个统计卡片车辆总数、可租车辆数、今日订单数、本月营收总额。SQL用SELECT COUNT(*)和SUM(total_price)即可再配合GROUP BY month做一个简单的订单趋势图。技术含量不高但展示效果极其惊艳哪怕只是几行数据老师一看就知道你做了完整思考。第二传感器级的前端校验一定要做。比如订单日期范围校验returnTime必须晚于getCarTime否则提示错误。这个校验既要在前端用JavaScript判断也要在后端Service再判断一次前后端双保险体现的是工程素养。第三把源码注释写清楚。在关键方法前用/** ... */说明业务逻辑在复杂SQL旁用-- 查询可租车辆这样的注释。代码写给别人看的能力面试官也会看重。不建议为了追求华丽而引入Redis、消息队列那超出了课题范围反而让老师觉得你重点跑偏。把一个CRUD系统做到结构清晰、功能闭合、演示顺畅就已经是课设里的优秀作品了。最后再分享一个小技巧做这种管理系统时把数据库初始化脚本schema.sql和测试数据data.sql单独放在项目根目录的sql文件夹下。这样无论开发还是答辩演示都能一键重建数据库状态不会出现演示到一半数据被我改乱了、页面一片空白的尴尬。这套JSPServletJDBC的底子打牢了以后学Spring MVC、Spring Boot时你会发现思路是完全相通的只不过框架把Servlet和JDBC的样板代码替你写好了。真正有沉淀的人是能用朴素技术做出完整管理系统、又能把每一步原理讲明白的人。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →