网站建设与管理自考本,南宁市哪里有帮搞网页设计的,seo品牌,钓鱼网站在线下载Forest项目中将Derby数据库替换为MySQL
在开发Java Web应用时#xff0c;我们常常会用到像Apache Derby这样的嵌入式数据库——启动快、配置简单#xff0c;特别适合教学演示或本地调试。比如经典的Forest示例项目#xff0c;默认就使用Derby作为持久化存储。但一旦进入类生…Forest项目中将Derby数据库替换为MySQL在开发Java Web应用时我们常常会用到像Apache Derby这样的嵌入式数据库——启动快、配置简单特别适合教学演示或本地调试。比如经典的Forest示例项目默认就使用Derby作为持久化存储。但一旦进入类生产环境问题就来了连接不稳定、并发支持弱、缺乏运维工具……这时候就得换上真正“能打”的数据库比如MySQL。那怎么把一个原本跑在Derby上的Java EE项目平滑迁移到MySQL别担心整个过程其实并不复杂只要搞清楚几个关键点数据源怎么改、SQL脚本有哪些坑、驱动包放哪儿。接下来我就带你一步步完成这次迁移照着做就行连初学者也能搞定。从web.xml开始重新定义数据源Forest这类基于Java EE/Jakarta EE的应用通常会在web.xml里通过JNDI注册全局数据源。原来的配置长这样data-source namejava:global/ForestDataSource/name class-nameorg.apache.derby.jdbc.EmbeddedDataSource/class-name database-nameforest/database-name property namecreateDatabase/name valuecreate/value /property /data-source现在我们要把它换成MySQL的连接方式。找到你的WEB-INF/web.xml文件把上面那段替换成如下内容data-source namejava:global/ForestDataSource/name class-namecom.mysql.cj.jdbc.MysqlDataSource/class-name server-namelocalhost/server-name port-number3306/port-number userroot/user passwordadmin/password property namedatabaseName/name valueforest/value /property property nameuseSSL/name valuefalse/value /property property nameallowPublicKeyRetrieval/name valuetrue/value /property /data-source这里有几个细节要注意com.mysql.cj.jdbc.MysqlDataSource是MySQL Connector/J 8.x推荐的数据源实现类比老式的DriverManager.getConnection()更适合容器管理。原来的database-name标签其实是非标准写法在新版本中应该用property包裹databaseName。useSSLfalse和allowPublicKeyRetrievaltrue这两个参数在开发环境下很实用避免因为证书验证或公钥获取失败导致连不上数据库线上请务必开启SSL并妥善配置。如果你MySQL不是跑在默认3306端口记得改port-number。改完之后先别急着重启服务器——数据库还没建呢。先动手创建MySQL数据库与用户权限在应用启动前得确保目标数据库已经准备就绪。登录MySQL命令行或者用Navicat这类工具执行CREATE DATABASE IF NOT EXISTS forest CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;为什么强调utf8mb4因为它是真正完整的UTF-8支持能存emoji、特殊符号这些四字节字符。而所谓的utf8在MySQL里其实是阉割版最多只支持三字节容易出乱码。如果你不想用root账户跑应用强烈建议不要这么做那就提前建个专用用户并授权CREATE USER forest_user% IDENTIFIED BY your_secure_password; GRANT ALL PRIVILEGES ON forest.* TO forest_user%; FLUSH PRIVILEGES;然后回头去web.xml里把user和password改成对应值即可。persistence.xml需要动吗大多数情况下不需要。Forest项目一般使用JPA比如EclipseLink或Hibernate它的持久化单元会自动根据连接的数据库类型选择合适的方言。典型的persistence.xml看起来是这样的persistence-unit nameforest jta-data-sourcejava:global/ForestDataSource/jta-data-source properties property namejavax.persistence.schema-generation.database.action valuedrop-and-create/ /properties /persistence-unit只要jta-data-source指向的是正确的JNDI名称Hibernate就能从JDBC URL推断出这是MySQL并启用MySQL8Dialect。但如果你之前手动指定过方言比如property namehibernate.dialect valueorg.hibernate.dialect.DerbyTenSevenDialect/那就一定要改成property namehibernate.dialect valueorg.hibernate.dialect.MySQL8Dialect/否则你会发现一些语法报错比如分页查询用不了LIMIT或者自增主键生成策略有问题。别忘了加JDBC驱动包GlassFish、Payara这类Java EE应用服务器不会自带MySQL驱动所以你必须手动把mysql-connector-java.jar放进类路径。最稳妥的位置是服务器的domain库目录domains/domain1/lib/mysql-connector-java-8.0.33.jar下载哪个版本建议选8.0.x系列兼容MySQL 5.7和8.0。如果是Maven项目也可以直接打入WEB-INF/lib但独立部署时还是推荐放在domain lib下统一管理。✅ 放好后重启服务器确认日志没有类找不到的错误。SQL脚本适配这才是最容易踩坑的地方Forest项目通常附带三组初始化脚本drop.sql、create.sql、data.sql。它们最初是为Derby写的直接扔给MySQL可能会炸。drop.sql先关外键检查Derby允许DROP TABLE IF EXISTS无脑删表但MySQL对顺序敏感尤其是有外键约束的时候。稳妥做法是先关闭约束检查SET FOREIGN_KEY_CHECKS 0; DROP TABLE IF EXISTS ORDER_DETAIL; DROP TABLE IF EXISTS CUSTOMER_ORDER; DROP TABLE IF EXISTS PRODUCT; DROP TABLE IF EXISTS CATEGORY; DROP TABLE IF EXISTS PERSON_GROUPS; DROP TABLE IF EXISTS PERSON; DROP TABLE IF EXISTS GROUPS; DROP TABLE IF EXISTS ORDER_STATUS; SET FOREIGN_KEY_CHECKS 1;这样不管依赖关系如何都能干净清除旧结构。create.sql核心DDL重写指南这是最关键的一步。下面是针对MySQL优化后的完整版本-- 创建并切换数据库 CREATE DATABASE IF NOT EXISTS forest CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE forest; -- 启用事务保证一致性 SET autocommit0; START TRANSACTION; -- 类别表 CREATE TABLE CATEGORY ( ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY, NAME VARCHAR(45) NOT NULL, TAGS VARCHAR(45) ); CREATE UNIQUE INDEX SQL_CATEGORY_ID_INDEX ON CATEGORY(ID); -- 用户表 CREATE TABLE PERSON ( ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 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 UNIQUE INDEX SQL_PERSON_EMAIL_INDEX ON PERSON(EMAIL); CREATE UNIQUE INDEX SQL_PERSON_ID_INDEX ON PERSON(ID); -- 组表 CREATE TABLE GROUPS ( ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY, NAME VARCHAR(50) NOT NULL, DESCRIPTION VARCHAR(300) ); -- 用户-组关联表 CREATE TABLE PERSON_GROUPS ( GROUPS_ID INT NOT NULL, EMAIL VARCHAR(45) NOT NULL, CONSTRAINT PK_PERSON_GROUPS PRIMARY KEY (GROUPS_ID, EMAIL) ); ALTER TABLE PERSON_GROUPS ADD CONSTRAINT FK_PERSON_GROUPS_GROUP FOREIGN KEY (GROUPS_ID) REFERENCES GROUPS(ID); ALTER TABLE PERSON_GROUPS ADD CONSTRAINT FK_PERSON_GROUPS_PERSON FOREIGN KEY (EMAIL) REFERENCES PERSON(EMAIL); CREATE INDEX SQL_PERSONGROUPS_EMAIL_INDEX ON PERSON_GROUPS(EMAIL); CREATE INDEX SQL_PERSONGROUPS_ID_INDEX ON PERSON_GROUPS(GROUPS_ID); -- 订单状态表 CREATE TABLE ORDER_STATUS ( ID INT NOT NULL PRIMARY KEY, STATUS VARCHAR(45) NOT NULL, DESCRIPTION VARCHAR(200) ); CREATE UNIQUE INDEX SQL_ORDERSTATUS_ID_INDEX ON ORDER_STATUS(ID); -- 客户订单表 CREATE TABLE CUSTOMER_ORDER ( ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY, AMOUNT FLOAT(52) NOT NULL, DATE_CREATED TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, CUSTOMER_ID INT NOT NULL, STATUS_ID INT NOT NULL ); 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); 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 UNIQUE INDEX SQL_ORDER_ID_INDEX ON CUSTOMER_ORDER(ID); -- 商品表 CREATE TABLE PRODUCT ( ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 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 ); ALTER TABLE PRODUCT ADD CONSTRAINT FK_PRODUCT_CATEGORY FOREIGN KEY (CATEGORY_ID) REFERENCES CATEGORY(ID); CREATE UNIQUE INDEX SQL_PRODUCT_ID_INDEX ON PRODUCT(ID); -- 订单明细表 CREATE TABLE ORDER_DETAIL ( ORDER_ID INT NOT NULL, PRODUCT_ID INT NOT NULL, QTY INT NOT NULL, CONSTRAINT SQL_ORDER_PRODUCT_PK PRIMARY KEY (ORDER_ID, PRODUCT_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 UNIQUE 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); COMMIT;重点差异总结一下功能Derby 写法MySQL 调整自增主键GENERATED ALWAYS AS IDENTITYAUTO_INCREMENT大对象字段BLOB(1073741823)改用LONGBLOB更合理字符集默认Latin1显式声明utf8mb4时间戳默认值TIMESTAMP DEFAULT CURRENT_TIMESTAMP支持无需改动特别提醒IMG_SRC用来存图片二进制流小图可能没问题但如果上传大文件记得检查MySQL的max_allowed_packet设置否则会报“packet too large”错误。data.sql数据插入基本兼容初始化数据这块改动不大主要是注意字符串引号和日期格式。例如INSERT INTO CATEGORY (NAME, TAGS) VALUES (Plants, Seeds, trees, flowers ...); INSERT INTO PERSON (FIRSTNAME, LASTNAME, EMAIL, ADDRESS, CITY, PASSWORD, DTYPE) VALUES (Robert, Exampler, robertexample.com, Example street, San Francisco, 81dc9bdb52d04dc20036dbd8313ed055, Customer);这类语句在两种数据库中都通用。唯一需要注意的是枚举型字段如DTYPE要确保值合法且长度不超过定义。最后一步验证一切是否正常做完所有修改后重新构建并部署项目。打开浏览器访问首页看看能不能加载商品列表、用户信息等数据。同时可以进MySQL验证USE forest; SHOW TABLES; SELECT COUNT(*) FROM PERSON; SELECT * FROM PRODUCT LIMIT 5;如果表都建好了数据也进去了说明迁移成功小结把Forest项目从Derby换成MySQL本质上是一次典型的企业级数据库迁移实践。虽然步骤不多但每一步都有潜在陷阱数据源配置要符合JNDI规范SQL脚本不能照搬特别是DDL语句驱动包必须正确放置字符集、外键、事务这些细节决定成败。完成这次迁移后你会发现应用更稳定了也更容易集成监控、备份等运维流程。更重要的是你对Java EE应用的数据层工作机制有了更深理解——这比单纯跑通一个demo要有价值得多。至于文中提到的Z-Image-ComfyUI那是另一个故事了专用于AI图像生成推理跟这套传统Web应用架构没啥关系。如果你感兴趣可以另开一篇聊聊它的部署方案。