简介基于JSP与MySQL实现的个人记事备忘系统完整源码包面向正在学习Java Web开发的初学者、毕业设计学生以及需要快速搭建轻量级记事本应用的开发者。项目采用JSPServletJDBC经典技术栈涵盖用户笔记增删改查、分类管理、登录验证等核心功能涉及MVC分层、SQL注入防范、数据库连接池等进阶要点。资源共374个文件包含Java源码与Servlet类、JSP页面、HTML/CSS/JS前端界面、数据库配置文件与jar依赖库等压缩包约27.51MB。目前已有109人学习下载。通过研读代码目录与页面实现可掌握从数据库表设计、DAO数据访问层编写到前端页面联调的全过程适合作为课程设计、毕业设计或求职作品参考也可直接部署到Tomcat运行验证学习效果。1. 基于Jsp和MySQL实现的个人记事备忘系统这套源码到底能不能拿来就用“基于Jsp和MySQL实现的个人记事备忘系统”这个标题放到今天看就像一套标准的JavaWeb课设/毕设题JSP管页面展示Servlet接请求MySQL存数据。市面上这种源码包流传很广但大多数人解压后都会卡在同一个地方——先跑哪个文件、用什么版本的环境、为什么数据库连不上。这篇笔记就从“源码包拿到手之后”的顺序走一遍先拆结构和表设计再在IDEA里跑起来打成war部署到Tomcat最后把高频踩坑现场挨个说清楚。适合刚学完JavaWeb基础的人、拿它做毕设但缺实操经验的学生以及需要快速在本地复现一套老项目来改功能的开发者。2. 拆解源码结构JSPServletMySQL的记事备忘系统是怎么分层设计的2.1 这套JSPServletMySQL组合为什么成了记事备忘系统的常见底座个人记事备忘系统的业务很简单用户注册登录、新增记事、编辑删除、按时间查看。这类系统用SpringBoot来做当然可以但JSPServletMySQL的组合在课程设计和毕业设计里仍然是最常见的题材原因是它的分层足够直观——JSP页面放在Web根目录下Servlet类控制跳转DAO类通过JDBC读写数据库。三层全部手写每个文件做什么一目了然答辩时也容易讲清楚。对比一下SpringBoot集成JSP的目录约束SpringBoot官方不推荐JSP需要额外指定spring-boot-starter-tomcat和JSP编译依赖打包时还要把JSP放到META-INF/resources下否则war包里找不到页面。传统JSP项目则没有这些限制源码包的目录结构基本都是WebContent或src/main/webappJSP文件直接放里面Tomcat会自动映射。所以这类源码包对新手友好不需要理解复杂的自动配置改一个JSP文件就能看到效果。记事备忘系统的数据量不大交互以增删改查为主不存在高并发、事务嵌套、分库分表的需求。用JDBC直连或简单连接池就够了。理解了这一点你会发现源码包里的几十个文件完全可以按“JSP视图层、Servlet控制层、DAO数据层”三条线去读不用从头到尾逐行看。2.2 user、note、category三张表个人记事系统的核心建表脚本打开源码包通常会有database或sql目录里面放一个建表脚本名字一般是note.sql或memo.sql。个人记事备忘系统最常见的表结构是三张表用户表、记事表、分类表。分类表可以没有但用户表和记事表必须有。记事表里一般存标题、正文、创建时间、是否置顶、用户ID这些字段直接决定了系统的功能边界。下面是一份符合JSPMySQL课设水平、同时兼顾MySQL 5.7和8.0兼容性的建表脚本-- 用户表 CREATE TABLE user ( id INT NOT NULL AUTO_INCREMENT, username VARCHAR(32) NOT NULL COMMENT 登录名, password VARCHAR(64) NOT NULL COMMENT 加密或明文密码看源码实现, nickname VARCHAR(32) DEFAULT NULL COMMENT 昵称可为空, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表; -- 记事表 CREATE TABLE note ( id INT NOT NULL AUTO_INCREMENT, user_id INT NOT NULL COMMENT 所属用户, title VARCHAR(100) NOT NULL DEFAULT COMMENT 记事标题, content TEXT COMMENT 正文内容, is_top TINYINT NOT NULL DEFAULT 0 COMMENT 是否置顶0不置顶 1置顶, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT 修改时间, PRIMARY KEY (id), KEY idx_user_time (user_id, create_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT记事表;这段脚本的关键参数要说明一下。username字段用UNIQUE KEY做唯一约束注册时重名会直接抛异常比在Java里先查一遍再插入更可靠。password字段长度给64是为了兼容MD5或SHA256加密后的密文如果源码里是明文存储拿到手后建议改成加密。content用TEXT而不是VARCHAR是为了让正文不受65535字节限制个人记事的日志类内容经常超过这个长度。is_top的TINYINT DEFAULT 0是热搜里“mysql设置默认值为0”的典型场景置顶逻辑就是按这个字段倒序排列。create_time用DATETIME而不是TIMESTAMP可以规避2038年问题和MySQL 8.0对TIMESTAMP默认值的一些严格限制。索引方面idx_user_time这个联合索引覆盖了“查看某用户的所有记事按时间倒序”这个核心查询查询条件里带上user_id可以高效走索引。如果你拿到手的源码表结构里没有这个索引在数据量上了几千条后列表页每次查询都会做全表扫描。MySQL的排序如果不需要可以不加但这个联合索引建议保留。导入脚本时注意先执行CREATE DATABASE note DEFAULT CHARSET utf8mb4否则直接建表会因为没选中库而报错。2.3 DBUtil与连接参数useSSL、serverTimezone、characterEncoding一次调对源码包的数据库连接层常见做法是放一个DBUtil.java内部维护一个连接池或者直接用DriverManager.getConnection。有连接池的会用DBCP、C3P0或Druid没有连接池的就是每次请求都新建连接。个人项目用连接池更好改动成本也不高。配置信息通常集中在db.properties或jdbc.properties里数据库账号密码都在这一个文件里改。jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/note?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8allowPublicKeyRetrievaltrue jdbc.usernameroot jdbc.passwordyour_password jdbc.initialSize5 jdbc.maxTotal20对应的DBUtil核心代码是这样的import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Properties; import java.io.InputStream; public class DBUtil { private static String url; private static String username; private static String password; static { try (InputStream in DBUtil.class.getClassLoader() .getResourceAsStream(db.properties)) { Properties props new Properties(); props.load(in); Class.forName(props.getProperty(jdbc.driver)); url props.getProperty(jdbc.url); username props.getProperty(jdbc.username); password props.getProperty(jdbc.password); } catch (Exception e) { throw new ExceptionInInitializerError(e); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url, username, password); } }url那一段参数值得逐字理解。useSSLfalse是关掉SSL加密连接MySQL 8.0默认开启SSL而很多老源码用的连接驱动版本对SSL握手兼容性差不关会报“SSL connection error”之类的错。serverTimezoneAsia/Shanghai解决时间差8小时的问题热搜里“mysql jdbc usessl 与 sslmode 使用”和“mysql将字符串转为日期”其实都指向这些参数。characterEncodingutf8解决中文乱码。allowPublicKeyRetrievaltrue是配合MySQL 8.0的caching_sha2_password认证插件用的不加这个参数会报“Public Key Retrieval is not allowed”。如果你下载的源码包里是纯JDBC直连而没有连接池注意不要再加initialSize和maxTotal这两个配置否则配置文件里写了但代码不读不会有问题但会让人误以为连接池已经生效。判断源码是否用了连接池看DBUtil类里有没有DataSource对象或者BasicDataSource之类的导入即可。3. 用IDEA把源码跑起来JSP项目导入、数据库配置与首次启动的完整步骤3.1 JDK、Tomcat、MySQL版本怎么配对老源码对环境敏感JSP老项目对运行环境很敏感版本不匹配会出一堆奇怪报错。最常见的是JDK版本过高导致Tomcat启动失败或JSP编译报错以及MySQL驱动版本和数据库版本不匹配。参考下面这个组合踩坑率最低组件推荐版本说明JDK1.8 (8u202)老源码绝大多数按Java 8语法写Tomcat8.5.x 或 9.0.x8.5配JDK8最稳9配JDK8也没问题MySQL5.7 或 8.08.0需用mysql-connector-java 8.x驱动IDEA2020.x 及以上新版IDEA一样兼容重点在SDK配置Maven3.6.x如果源码带pom.xml则按Maven项目导入JSP规范本身是跟着Servlet走的Tomcat 8.5对应Servlet 3.1和JSP 2.3Tomcat 9对应Servlet 4.0和JSP 2.4。老源码里如果用了Tomcat专属标签或旧版JSTL8.5比9的兼容性稍好。我一般建议先试Tomcat 8.5报错少。如果你本机只有JDK 11或17强行跑一个编译级别为1.8的老项目启动时大概率遇到java.lang.UnsupportedClassVersionError或者Tomcat内部框架反射报ClassNotFound。最简单的办法是装一个JDK 8并让IDEA的Project SDK指向它。MySQL版本要单独说。MySQL 5.7和8.0在认证方式上有本质区别8.0默认用caching_sha2_password老驱动com.mysql.jdbc.Driver只认mysql_native_password会直接报认证失败。如果你的源码包里驱动是5.x版本的jar连MySQL 8.0时要把数据库用户的插件改回mysql_native_password或者直接把驱动替换成mysql-connector-java 8.x并修改驱动类名为com.mysql.cj.jdbc.Driver。3.2 用IDEA导入既有JSP源码Web Facet、Artifacts与Tomcat配置拿到源码包后不要急着双击JSP文件那只会用浏览器打开源码文本。正确做法是把整个目录当成项目导入IDEA然后手动告诉IDEA这是Web项目。打开方式IDEA启动界面选Open选中源码根目录。如果根目录有pom.xmlIDEA会提示作为Maven项目导入选Trust Project即可如果只有WebContent或src目录就选New Project from Existing Sources一路Next到SDK选择时指定JDK 1.8。导入后最关键的一步是配置Web Facet和Artifacts。打开File → Project Structure → Facets点加号选Web然后在Web Resource Directories里把WebContent或src/main/webapp目录标记为Web资源目录。再到Artifacts确认有一个war或war exploded的产出物。如果Artifacts里是空的后面配置Tomcat时会找不到可部署的东西启动直接报错。然后是配置Tomcat运行环境Run → Edit Configurations → 左上角加号 → Tomcat Server → Local。在Server选项卡里配置Tomcat安装目录在Deployment选项卡里点加号选Artifact把项目部署进去。Application context这一栏要重点看一眼它决定了访问路径。比如写/note启动后访问地址就是http://localhost:8080/note/。很多源码包里的过滤器或登录跳转写的是绝对路径比如response.sendRedirect(/login.jsp)这时Application context配成/才行否则跳转会404。这一步是整个IDEA配置里最常见的坑。3.3 导入SQL脚本并修改数据库连接命令行和Workbench两条路数据库准备环节要先把脚本导入MySQL。两种方式任选命令行适合熟手MySQL Workbench适合需要可视化确认的人。命令行方式如下mysql -u root -p note.sql注意这条命令执行前要确认note.sql文件路径且脚本里如果没有CREATE DATABASE语句就要先手动创建库。可以用mysql -u root -p -e CREATE DATABASE note DEFAULT CHARSET utf8mb4先建库再导入。导入完成后用SHOW TABLES;验证三张表是否都在顺便执行SELECT * FROM user;看看有没有内置账号有的源码包会预置一个admin账号用于演示。改数据库连接参数是源码跑通的关键一步。打开src目录下的db.properties把密码改成你自己的MySQL密码。如果你用的MySQL是8.0同时确认jar包是8.x的驱动然后按前面2.3节的url参数修改。改完先别急着启动写一个两行的Java测试类或者直接用数据库客户端连一次确认账号能远程或本地登录。这里不推荐在代码里硬编码密码源码包该有的习惯是集中配置。3.4 启动后按什么顺序验证从Tomcat日志到数据库记录首次启动不要直接点浏览器刷新先看IDEA的Run窗口里的Tomcat日志。看到“Server startup in [xxx] milliseconds”才算真正启动完成。如果一直卡在“Deployment is in progress”或者报端口占用先查8080端口是否被其它进程占用然后检查Artifacts是否构建成功。日志里出现严重错误时点左侧的红色错误行跳转到具体异常最常见的就两类数据库连接失败和JSP编译异常。启动成功后按这个顺序验证先访问部署路径的根地址看是否能跳转到登录页如果源码有登录拦截注册一个新账号登录后新建一条带中文的记事然后执行一条SQL去库里查这条数据是否存在。如果页面显示成功但库里没有记录问题出在事务管理或SQL执行后的提交如果页面乱码则回到2.3节的字符集参数去排查。这个顺序能快速把问题定位到是前端JSP、Servlet跳转还是数据访问层。4. 传统JSP项目打包成war从源码包到可部署的Tomcat产物的标准流程4.1 war包是什么给“源码打包”补上最后一步源码包里的“打包”两个字有两层含义。第一层是源码文件的压缩归档也就是你下载到的zip或rar第二层是把整个Web项目构建成war包——这是JavaWeb的标准部署单元。war包本质上是一个特殊格式的zip里面包含JSP、class文件、jar依赖、web.xml配置。Tomcat拿到war包后会自动解压到webapps目录下不需要额外手工复制class文件。个人记事系统打包成war意味着可以脱离IDEA直接部署到任意一台装有Tomcat的机器上不管是演示还是放到自己的服务器都方便。为什么不直接把整个源码目录拷到Tomcat的webapps下因为源码目录里包含.java源文件和IDEA工程文件Tomcat运行时不关心这些它只需要编译后的.class、JSP、WEB-INF/lib下的依赖jar包和web.xml。war包就是把这一堆运行时文件按标准目录结构组织起来。很多课设源码包里会直接带一个现成的war但那个war是作者机器上构建的数据库连接配置大概率指向作者本机你依然要解压web.xml和配置文件去改数据库地址。4.2 三种打war包的方式Maven、IDEA Artifacts与手动jar对于源码包打war包的方式取决于项目结构。如果源码带pom.xml用Maven最省事在项目根目录执行mvn clean package -DskipTests命令执行完后war包在target目录下文件名一般是artifactId-version.war。由于源码包经常不配套完整的Maven配置如果pom.xml里缺了打包插件执行后会在target目录只生成class而没有war这时候给pom.xml补上maven-war-plugin插件即可。注意JDBC驱动如果声明的scope是provided或test是不会打进war的WEB-INF/lib的部署后运行会报找不到驱动类要把scope改成compile。不带Maven的纯Web目录项目用IDEA的Build Artifacts功能更直接。菜单路径为Build → Build Artifacts → Build前提是3.2节里已经配置好Web Facet和Artifacts类型。IDEA会按Artifacts定义的输出布局把编译好的class和Web目录资源打包成war。这种方式不依赖Maven适合那些解压出来就是一个纯Web目录的老源码。还有更原始的手动方式把WebContent里的内容连同WEB-INF目录一起打进zip然后改扩展名为war但class文件必须是你自己编译过的。初学者别选这个容易漏文件或放错目录。可以理解为有pom用Maven没pom用IDEA手动jar只在你明确知道要包含哪些文件时才推荐。三者的对比如下方式前置条件产物位置适合场景Maven package项目有pom.xmltarget/项目结构规范后续要持续构建IDEA Build Artifacts已配置Web Facetout/artifacts/纯Web目录源码包手动jar已编译好class自己指定老项目临时救急4.3 部署到Tomcat并验证从webapps目录到浏览器访问war包打出来后部署就变得很机械。先停掉正在运行的Tomcat避免端口占用或文件被锁定。然后把war包复制到Tomcat的webapps目录再执行启动脚本。Linux或macOS下大概是这个样子cp note.war /path/to/tomcat/webapps/ /path/to/tomcat/bin/startup.sh启动后Tomcat会自动把note.war解压成note目录。这时访问http://localhost:8080/note/如果能看到登录页说明war包内容结构正确。如果看到404先确认war文件名和访问路径一致——Tomcat默认用war包文件名作为应用上下文路径note.war对应的上下文就是/note。网页上能打开后再做一个更彻底的验证执行curl命令看返回状态码以及用数据库客户端查一下登录成功后是否生成了新的会话记录或数据。curl -I http://localhost:8080/note/ curl -L http://localhost:8080/note/login.jsp如果下面有动态请求注意一个问题很多人会把war部署到Tomcat后再用nginx做服务器前置然后问“nginx支持jsp吗”。答案是不支持nginx本身不解析JSP需要把动态请求反向代理到Tomcat端口通常是配置nginx的location块proxy_pass到http://127.0.0.1:8080。个人记事系统直接访问Tomcat就够用了不需要上nginx。5. 避坑JSPMySQL项目从源码到上手的5个高频翻车现场5.1 报错“Public Key Retrieval is not allowed”或SSL连接错误现象是项目启动后点任何需要访问数据库的功能页面直接500Tomcat日志里出现java.sql.SQLNonTransientConnectionException提示Public Key Retrieval is not allowed。或者日志里有SSL connection error相关的异常一堆带SSL关键词的堆栈。原因分两类。Public Key Retrieval是因为MySQL 8.0默认的caching_sha2_password认证需要向服务器获取公钥来加密密码传输JDBC驱动出于安全考虑默认不自动获取。SSL连接错误则是因为MySQL 8.0默认开启SSL而老驱动或老连接参数没有正确处理SSL握手。解决方法是修改jdbc.url参数把allowPublicKeyRetrievaltrue和useSSLfalse都加上。如果修改后仍报错再看驱动版本mysql-connector-java 5.x在MySQL 8.0下兼容性很差换成8.x版本并把driver类名改成com.mysql.cj.jdbc.Driver。5.2 JSP页面中文乱码三层各乱各的现象是页面显示的问号或乱码有时是标题乱码、正文正常有时全页面都乱写入数据库的也是乱码。最迷惑的是改一处编码后另一个页面又乱了。原因是JSPMySQL的中文乱码涉及三个独立节点JSP文件的保存编码和pageEncoding指令、HTTP请求响应之间的字符编码、JDBC连接MySQL时传输的字符编码。它们必须全部一致只改JSP页面的pageEncoding是不够的。解决方法是逐个统一。JSP文件头部确认% page contentTypetext/html;charsetUTF-8 pageEncodingUTF-8%MySQL数据库建库时用utf8mb4连接URL里保证characterEncodingutf8如果还有乱码检查Tomcat的server.xml里Connector是否缺少URIEncodingUTF-8属性。控制台输出乱码另说那个不影响业务数据。5.3 war部署后访问项目路径404Tomcat首页却正常现象是Tomcat启动成功访问http://localhost:8080/能看到Tomcat默认欢迎页访问http://localhost:8080/note/就404webapps目录里确认war已经解压出note目录了。原因是应用上下文路径不匹配。Tomcat的webapps下目录叫note那上下文路径就是/note。如果war包里的JSP页面有跳转逻辑写的是绝对路径例如response.sendRedirect(/index.jsp)那么这个路径实际会映射到Tomcat根上下文也就是/下当然404。还有一种情况是IDEA部署时Application context配成了/note_war和你预期的/note不一样。解决方法是先确认上下文访问http://localhost:8080/note/login.jsp试试直接打开物理JSP文件如果这个能开而/note/不能多半是欢迎页或Servlet映射的问题。然后打开Tomcat的conf/server.xml看Host里是否有Context配置覆盖了默认映射。大多数情况下把war包重新命名为你想要的上下文名比如note.war再部署就能解决。5.4 启动后页面提示找不到驱动类或连接池依赖现象是运行时抛ClassNotFoundException: com.mysql.jdbc.Driver或者在IDEA里运行正常打成war包部署到另一台机器上就报同样的错。原因是依赖没有进入war包。IDEA里运行项目时依赖在IDEA的classpath里能找到但独立部署时Tomcat只认WEB-INF/lib目录下的jar。源码包里如果带了lib目录但IDEA没有把lib里的jar纳入Artifacts或者pom.xml里驱动依赖的scope是provided都会导致war包缺少驱动。解决方法是打开Project Structure → Artifacts在右侧的Available Elements里找到lib目录下所有jar右键选Put into WEB-INF/lib。Maven项目则检查pom里mysql-connector-java的scope改成compile后重新package再打开war包确认WEB-INF/lib下有没有这个jar。5.5 记事时间比当前时间少8小时或多了8小时现象是新建一条记事列表页显示的时间比本地时间晚8小时或者数据库里存的时间对但页面显示就偏了。原因是时区在三个环节不断传递MySQL连接URL的serverTimezone参数、Java运行环境的默认时区、浏览器显示用的本地时区。老源码连接MySQL时没写serverTimezone驱动默认取JVM所在时区如果服务器是UTC就会差8小时。解决方法是统一时区。在jdbc.url里加serverTimezoneAsia/Shanghai这是最直接的手段。如果改完还差检查MySQL系统变量time_zone是否为SYSTEM可以执行SET GLOBAL time_zone 08:00但重启MySQL会恢复稳妥做法是在my.cnf的[mysqld]下配置default-time-zone08:00。源码包通常不需要改到数据库system级别优先改JDBC参数。6. 把个人记事备忘系统做深一步登录态、数据备份与扩展点6.1 登录态用一个Filter拦掉未登录访问很多源码包的登录校验都写在每个JSP页面里每次跳转都要重复判断session既容易漏又难维护。改成统一Filter是成本最低的加固动作。核心逻辑是放行登录页和登录接口其余请求都检查session里有没有用户对象。一个最小实现大致是doFilter里判断request.getSession().getAttribute(user)是否为空为空就跳转到login.jsp不为空放行。配置web.xml时把过滤路径设为/*但注意放行/css、/js这类静态资源否则登录页本身的样式也加载不出来。6.2 数据备份个人记事的后悔药记事系统用久了才知道备份多重要。MySQL单库备份一条命令就能做完整导出mysqldump -u root -p note note_backup_$(date %Y%m%d).sql配合crontab每天凌晨执行一次再配合文件保留策略比如只保留最近30天的备份文件个人项目的数据库安全基本就到位了。恢复时执行mysql -u root -p note backup.sql即可。这一条值得写进任何源码包的自述文档里。6.3 让记事系统更像成品搜索、分组和导出源码包的记事列表通常只是一个顺序倒排的表格但实际使用时搜索是刚需。后加搜索功能不用改数据库表直接在DAO层加一个LIKE查询就能验完业务。数据量大了之后再用MySQL的FULLTEXT索引优化。分类筛选在现有表基础上增加一个category_id字段配合一个分类管理页面即可。导出功能用JSP输出原生内容就行新建一个note_export.jsp通过out.println直接输出纯文本或HTML浏览器另存为就是文本文件。我自己的习惯是接到这种老项目源码第一件事不是看业务代码而是先把lib目录和web.xml扫一遍确认依赖和Servlet映射版本再启动数据库连一下。前面省10分钟后面能少踩一半的坑。希望这篇笔记能帮你把这个个人记事备忘系统从源码包变成真正能每天打开写点东西的工具。本文还有配套的精品资源点击获取