镇江网站建设制作方案全国工程信息平台官网
2026/1/16 22:47:55 网站建设 项目流程
镇江网站建设制作方案,全国工程信息平台官网,网站建设易尔通,wordpress注册直接输入密码Forest项目数据库从Derby迁移至MySQL 在开发Java EE应用时#xff0c;我们常常会使用像Apache Derby这样的嵌入式数据库作为初期原型或教学示例的存储方案。它轻量、无需额外部署#xff0c;非常适合快速上手——比如经典的示例项目 Duke’s Forest 就默认集成了Derby。但一旦…Forest项目数据库从Derby迁移至MySQL在开发Java EE应用时我们常常会使用像Apache Derby这样的嵌入式数据库作为初期原型或教学示例的存储方案。它轻量、无需额外部署非常适合快速上手——比如经典的示例项目Duke’s Forest就默认集成了Derby。但一旦进入生产环境面对真实用户流量、高并发请求和长期数据维护需求Derby的短板就暴露无遗缺乏成熟的连接池管理、不支持高效的并发写入、运维工具薄弱……这时候迁移到一个真正意义上的企业级数据库就成了必然选择。MySQL作为一个稳定、高性能且生态完善的关系型数据库自然成为许多团队的首选。本文记录的是将Forest项目从Derby切换到MySQL的完整实践过程。这不是一次简单的配置替换而是一次涉及数据源定义、JDBC驱动加载、SQL语法适配以及字符集统一的系统性调整。整个迁移过程基于GlassFish服务器运行环境并结合EclipseLinkJPA实现完成持久化层对接。准备工作搭建MySQL基础环境任何迁移的第一步都是确保目标数据库就位。这里推荐使用MySQL 5.7或8.0版本两者对Java应用的支持都较为成熟。以Ubuntu为例安装命令如下sudo apt update sudo apt install mysql-server sudo systemctl start mysql安装完成后登录MySQL并创建专用数据库与用户CREATE DATABASE forest CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER forest_userlocalhost IDENTIFIED BY secure_password; GRANT ALL PRIVILEGES ON forest.* TO forest_userlocalhost; FLUSH PRIVILEGES;这里有几个关键点值得注意- 使用utf8mb4字符集而非utf8因为后者实际上只支持3字节UTF-8编码无法正确处理emoji等4字节字符- 创建独立数据库用户避免直接使用root账户提升安全性- 权限范围限定为forest.*遵循最小权限原则。引入MySQL JDBC驱动为了让Java应用能够连接MySQL必须引入对应的JDBC驱动。如果你是通过Maven构建项目在pom.xml中添加依赖是最简洁的方式dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency但如果是在GlassFish这类应用服务器中部署WAR包则需要手动将mysql-connector-java-x.x.x.jar复制到类路径下。通常位置为glassfish/domains/domain1/lib/或者也可以放入应用的WEB-INF/lib/目录中使其随应用一起打包部署。⚠️ 常见问题提醒如果启动时报错ClassNotFoundException: com.mysql.cj.jdbc.Driver请立即检查jar包是否已正确放置并确认文件名拼写无误。修改数据源配置从Derby到MySQLForest项目通过web.xml中的data-source元素声明了一个全局数据源data-source namejava:global/ForestDataSource/name class-namecom.mysql.cj.jdbc.MysqlDataSource/class-name server-namelocalhost/server-name port-number3306/port-number database-nameforest/database-name userforest_user/user passwordsecure_password/password property nameuseSSL/name valuefalse/value /property property nameallowPublicKeyRetrieval/name valuetrue/value /property property nameautoReconnect/name valuetrue/value /property property namecharacterEncoding/name valueutf8/value /property property nameserverTimezone/name valueUTC/value /property /data-source这个配置替换了原本指向Derby的数据源。其中几个参数值得特别说明com.mysql.cj.jdbc.MysqlDataSource是MySQL Connector/J 8.0 推荐使用的数据源类useSSLfalse在本地测试环境中可以关闭SSL加密但在生产环境中应启用并配置证书allowPublicKeyRetrievaltrue解决了MySQL 8.0默认采用caching_sha2_password认证插件导致的公钥获取问题serverTimezoneUTC明确指定时区防止因服务器与数据库时间不一致引发的时间字段异常。只要该数据源名称与persistence.xml中引用的一致JPA层就能自动接管后续操作。persistence.xml 是否需要修改好消息是不需要。Forest项目的persistence.xml内容如下persistence-unit nameForestPU transaction-typeJTA jta-data-sourcejava:global/ForestDataSource/jta-data-source properties property nameeclipselink.ddl-generation valuecreate-tables/ property nameeclipselink.ddl-generation.output-mode valueboth/ /properties /persistence-unit可以看到它仅指定了JTA事务类型和DDL生成策略并未硬编码数据库方言如property nameeclipselink.target-database valueDerby/。这意味着EclipseLink会根据实际连接的数据库自动推断其类型并生成相应SQL语句。因此只要数据源切换成功框架层面几乎无需改动。SQL脚本适配跨数据库兼容的关键这才是迁移中最容易出错的部分。Derby与MySQL在SQL语法上有诸多差异尤其是主键自增、外键约束、索引命名等方面。原始的三个初始化脚本必须逐一调整。drop.sql安全清空旧表为了规避外键依赖导致的删除失败建议先禁用约束检查SET FOREIGN_KEY_CHECKS 0; DROP TABLE IF EXISTS PERSON_GROUPS; DROP TABLE IF EXISTS PERSON; DROP TABLE IF EXISTS GROUPS; DROP TABLE IF EXISTS ORDER_DETAIL; DROP TABLE IF EXISTS CUSTOMER_ORDER; DROP TABLE IF EXISTS ORDER_STATUS; DROP TABLE IF EXISTS PRODUCT; DROP TABLE IF EXISTS CATEGORY; SET FOREIGN_KEY_CHECKS 1;这种方式比逐条判断是否存在更可靠尤其适合一次性重建场景。create.sql建表结构全面重构这是最核心的脚本。原Derby使用GENERATED BY DEFAULT AS IDENTITY实现自增主键而在MySQL中应改为AUTO_INCREMENT。同时要显式设置字符集和排序规则。以下是适配后的完整版本CREATE DATABASE IF NOT EXISTS forest CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE forest; SET NAMES utf8mb4; SET character_set_client utf8mb4; CREATE TABLE CATEGORY ( ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(45) NOT NULL, TAGS VARCHAR(45) ); CREATE TABLE PERSON ( ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT, FIRSTNAME VARCHAR(50) NOT NULL, LASTNAME VARCHAR(100) NOT NULL, EMAIL VARCHAR(45) NOT NULL UNIQUE, ADDRESS VARCHAR(45) NOT NULL, CITY VARCHAR(45) NOT NULL, PASSWORD VARCHAR(100), DTYPE VARCHAR(31) ); CREATE TABLE GROUPS ( ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(50) NOT NULL, DESCRIPTION VARCHAR(300) ); CREATE TABLE PERSON_GROUPS ( GROUPS_ID INT NOT NULL, EMAIL VARCHAR(45) NOT NULL, PRIMARY KEY (GROUPS_ID, EMAIL) ); CREATE TABLE ORDER_STATUS ( ID INT NOT NULL PRIMARY KEY, STATUS VARCHAR(45) NOT NULL, DESCRIPTION VARCHAR(200) ); CREATE TABLE CUSTOMER_ORDER ( ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT, AMOUNT FLOAT(52) NOT NULL, DATE_CREATED TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, CUSTOMER_ID INT NOT NULL, STATUS_ID INT NOT NULL ); CREATE TABLE PRODUCT ( ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(45) NOT NULL, PRICE DECIMAL(10,2) NOT NULL, DESCRIPTION VARCHAR(145) NOT NULL, IMG VARCHAR(45), CATEGORY_ID INT NOT NULL, IMG_SRC LONGBLOB ); CREATE TABLE ORDER_DETAIL ( ORDER_ID INT NOT NULL, PRODUCT_ID INT NOT NULL, QTY INT NOT NULL, PRIMARY KEY (ORDER_ID, PRODUCT_ID) ); -- 外键约束统一后置添加 ALTER TABLE PERSON_GROUPS ADD CONSTRAINT FK_PERSON_GROUPS_PERSON FOREIGN KEY (EMAIL) REFERENCES PERSON(EMAIL); ALTER TABLE PERSON_GROUPS ADD CONSTRAINT FK_PERSON_GROUPS_GROUPS FOREIGN KEY (GROUPS_ID) REFERENCES GROUPS(ID); ALTER TABLE CUSTOMER_ORDER ADD CONSTRAINT FK_CUSTOMER_ORDER_ORDER_STATUS FOREIGN KEY (STATUS_ID) REFERENCES ORDER_STATUS(ID); ALTER TABLE CUSTOMER_ORDER ADD CONSTRAINT FK_CUSTOMER_ORDER_CUSTOMER FOREIGN KEY (CUSTOMER_ID) REFERENCES PERSON(ID); ALTER TABLE PRODUCT ADD CONSTRAINT FK_PRODUCT_CATEGORY FOREIGN KEY (CATEGORY_ID) REFERENCES CATEGORY(ID); ALTER TABLE ORDER_DETAIL ADD CONSTRAINT FK_ORDER_DETAIL_PRODUCT FOREIGN KEY (PRODUCT_ID) REFERENCES PRODUCT(ID); ALTER TABLE ORDER_DETAIL ADD CONSTRAINT FK_ORDER_DETAIL_ORDER FOREIGN KEY (ORDER_ID) REFERENCES CUSTOMER_ORDER(ID); -- 索引优化查询性能 CREATE INDEX SQL_PERSON_EMAIL_INDEX ON PERSON(EMAIL); CREATE INDEX SQL_PERSON_ID_INDEX ON PERSON(ID); CREATE INDEX SQL_PERSONGROUPS_EMAIL_INDEX ON PERSON_GROUPS(EMAIL); CREATE INDEX SQL_PERSONGROUPS_ID_INDEX ON PERSON_GROUPS(GROUPS_ID); CREATE INDEX SQL_ORDER_STATUS_ID_INDEX ON CUSTOMER_ORDER(STATUS_ID); CREATE INDEX SQL_ORDER_CUSTOMER_ID_INDEX ON CUSTOMER_ORDER(CUSTOMER_ID); CREATE INDEX SQL_ORDER_ID_INDEX ON CUSTOMER_ORDER(ID); CREATE INDEX SQL_PRODUCT_ID_INDEX ON PRODUCT(ID); CREATE INDEX SQL_ORDER_DETAIL_INDEX ON ORDER_DETAIL(ORDER_ID, PRODUCT_ID); CREATE INDEX SQL_ORDER_PRODUCT_ID_INDEX ON ORDER_DETAIL(PRODUCT_ID); CREATE INDEX SQL_ORDER_DETAIL_ID_INDEX ON ORDER_DETAIL(ORDER_ID);几点经验总结- 主键全部使用AUTO_INCREMENT- 图片字段改用LONGBLOB支持更大图像- 所有文本字段明确指定utf8mb4编码- 外键延迟添加避免建表顺序冲突- 关键字段建立索引提升查询效率。data.sql插入初始数据此脚本相对简单主要是验证字段长度和约束是否匹配。例如用户密码仍沿用MD5哈希值INSERT INTO PERSON (FIRSTNAME, LASTNAME, EMAIL, ADDRESS, CITY, PASSWORD, DTYPE) VALUES (Robert,Exampler,robertexample.com,Example street,San Francisco,81dc9bdb52d04dc20036dbd8313ed055,Customer); INSERT INTO PERSON (FIRSTNAME, LASTNAME, EMAIL, ADDRESS, CITY, PASSWORD, DTYPE) VALUES (Admin,Admin,adminexample.com,Example street,Belmont,81dc9bdb52d04dc20036dbd8313ed055,Administrator);注意81dc9bdb52d04dc20036dbd8313ed055对应明文1234登录后台时输入即可。分类信息也照常插入INSERT INTO CATEGORY (NAME, TAGS) VALUES (Plants, Seeds, trees, flowers ...); INSERT INTO CATEGORY (NAME, TAGS) VALUES (Food, Foods, healthy items ...);其余商品、订单状态等数据保持不变。验证迁移结果功能回归测试重启GlassFish服务器后观察日志输出是否有类似提示INFO: Connected to database: jdbc:mysql://localhost:3306/forest INFO: Creating tables from schema creation script... INFO: Successfully created table CATEGORY INFO: Successfully created table PERSON ...这些日志表明JPA已成功连接MySQL并开始执行DDL脚本。若中途未报错则可进行前端功能验证使用adminexample.com / 1234登录管理员后台浏览商品列表是否正常显示添加商品至购物车并提交订单查看订单状态流转是否准确。所有流程均能顺利完成说明迁移达到了预期目标。常见问题排查指南问题现象可能原因解决方案ClassNotFoundException: com.mysql.cj.jdbc.DriverJDBC驱动未加载检查jar包是否位于domains/domain1/lib/或WEB-INF/lib/Access denied for user forest_userlocalhost账号密码错误或权限不足重新授权并执行FLUSH PRIVILEGES;Unknown database forest数据库未创建手动执行CREATE DATABASE forest;Table doesnt exist脚本未执行或执行失败检查create.sql路径及权限可手动导入Incorrect string value: \xE2\x8C\xA9...字符集不匹配确保表、字段、连接三者均为utf8mb4遇到问题时优先查看GlassFish的日志文件通常在glassfish/domains/domain1/logs/server.log其中往往包含详细的异常堆栈和SQL执行上下文。这种从嵌入式数据库向生产级数据库迁移的做法不仅适用于Forest项目也广泛应用于各类基于Java EE JPA 应用服务器架构的传统Web系统。掌握这一套方法意味着你已经具备了将原型项目推向生产的工程能力。更重要的是这次迁移揭示了一个通用原则早期技术选型不必追求完美但必须预留演进路径。Derby用于教学无可厚非只要我们在设计之初就考虑到未来可能更换数据库保持配置解耦、SQL抽象、驱动可插拔就能在系统成长过程中从容应对变化。如今Forest项目已在MySQL支撑下运行稳定响应更快扩展性更强。而这只是迈向现代化架构的第一步——下一步或许就是引入连接池优化、读写分离甚至过渡到微服务与云原生数据库。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询