重新测试deepseek Jakarta EE 10编程能力

听说deepseek做了一个小更新,我重新测试了一下Jakarta EE 10编程能力;有点进步,遗漏的功能比以前少了。

采用Jakarta EE 10 编写员工信息表维护表,包括员工查询与搜索、员工列表、新增员工、删除员工,修改员工,要求用户界面主要采用JAVA SERVER FACE,如果用户界面采用JAVA SERVER FACE实现不了,增加JS完成实现不了的功能,业务逻辑采用EJB,数据库访问采用JPA. 员工信息表包含 员工编号,姓名,部门,手机号码。

下面是一个完整的Jakarta EE 10员工信息管理系统实现方案,严格遵循您的要求:JSF作为主要UI框架、EJB处理业务逻辑、JPA进行数据访问,并在需要时使用JavaScript增强功能。

解决方案架构

复制

下载

复制代码
src
├── main
│   ├── java
│   │   └── com
│   │       └── example
│   │           ├── ejb
│   │           │   └── EmployeeService.java       # EJB服务
│   │           ├── entity
│   │           │   └── Employee.java              # JPA实体
│   │           ├── managed
│   │           │   └── EmployeeBean.java          # JSF托管Bean
│   │           └── util
│   │               └── JsfUtil.java               # JSF工具类
│   ├── resources
│   │   └── META-INF
│   │       └── persistence.xml                    # JPA配置
│   └── webapp
│       ├── WEB-INF
│       │   └── templates
│       │       └── template.xhtml                 # 页面模板
│       ├── employee
│       │   ├── list.xhtml                         # 员工列表
│       │   ├── edit.xhtml                         # 编辑页面
│       │   └── search.xhtml                       # 搜索页面
│       └── resources
│           └── js
│               └── main.js                        # JavaScript增强

1. JPA实体类 (Employee.java)

java

复制

下载

复制代码
package com.example.entity;

import jakarta.persistence.*;
import java.io.Serializable;

@Entity
@Table(name = "employee")
@NamedQuery(name = "Employee.findAll", query = "SELECT e FROM Employee e")
public class Employee implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "emp_number", unique = true, nullable = false)
    private String employeeNumber;

    @Column(nullable = false)
    private String name;

    private String department;

    @Column(name = "phone")
    private String phoneNumber;

    // 省略getter/setter
}

2. EJB服务层 (EmployeeService.java)

java

复制

下载

复制代码
package com.example.ejb;

import com.example.entity.Employee;
import jakarta.ejb.Stateless;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.TypedQuery;
import java.util.List;

@Stateless
public class EmployeeService {

    @PersistenceContext(unitName = "employeePU")
    private EntityManager em;

    public void create(Employee employee) {
        em.persist(employee);
    }

    public void update(Employee employee) {
        em.merge(employee);
    }

    public void delete(Long id) {
        Employee emp = em.find(Employee.class, id);
        if (emp != null) {
            em.remove(emp);
        }
    }

    public List<Employee> findAll() {
        return em.createNamedQuery("Employee.findAll", Employee.class).getResultList();
    }

    public List<Employee> search(String keyword) {
        String jpql = "SELECT e FROM Employee e WHERE " +
                      "LOWER(e.name) LIKE :keyword OR " +
                      "LOWER(e.department) LIKE :keyword OR " +
                      "e.phoneNumber LIKE :keyword OR " +
                      "e.employeeNumber LIKE :keyword";
        
        return em.createQuery(jpql, Employee.class)
                .setParameter("keyword", "%" + keyword.toLowerCase() + "%")
                .getResultList();
    }

    public Employee findById(Long id) {
        return em.find(Employee.class, id);
    }
}

3. JSF托管Bean (EmployeeBean.java)

java

复制

下载

复制代码
package com.example.managed;

import com.example.ejb.EmployeeService;
import com.example.entity.Employee;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import java.io.Serializable;
import java.util.List;

@Named
@ViewScoped
public class EmployeeBean implements Serializable {
    private Employee employee = new Employee();
    private List<Employee> employees;
    private String searchKeyword;

    @Inject
    private EmployeeService employeeService;

    public void init() {
        employees = employeeService.findAll();
    }

    public void search() {
        employees = employeeService.search(searchKeyword);
    }

    public String save() {
        if (employee.getId() == null) {
            employeeService.create(employee);
        } else {
            employeeService.update(employee);
        }
        return "/employee/list?faces-redirect=true";
    }

    public void delete(Long id) {
        employeeService.delete(id);
        employees = employeeService.findAll();
    }

    public void prepareEdit(Long id) {
        employee = employeeService.findById(id);
    }

    // 省略getter/setter
}

4. JSF工具类 (JsfUtil.java)

java

复制

下载

复制代码
package com.example.util;

import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;

public class JsfUtil {
    public static void addErrorMessage(String msg) {
        FacesContext.getCurrentInstance().addMessage(
            null, new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, null));
    }
    
    public static void addSuccessMessage(String msg) {
        FacesContext.getCurrentInstance().addMessage(
            null, new FacesMessage(FacesMessage.SEVERITY_INFO, msg, null));
    }
}

5. JPA配置 (persistence.xml)

xml

复制

下载

运行

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="3.0" xmlns="http://jakarta.ee/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://jakarta.ee/xml/ns/persistence
             http://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd">
    <persistence-unit name="employeePU" transaction-type="JTA">
        <jta-data-source>java:global/jdbc/EmployeeDS</jta-data-source>
        <class>com.example.entity.Employee</class>
        <properties>
            <property name="jakarta.persistence.schema-generation.database.action" 
                      value="drop-and-create"/>
            <property name="jakarta.persistence.sql-load-script-source"
                      value="/META-INF/sql/data.sql"/>
        </properties>
    </persistence-unit>
</persistence>

6. 页面模板 (template.xhtml)

xhtml

复制

下载

复制代码
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
    <title>员工管理系统</title>
    <h:outputStylesheet name="css/style.css"/>
    <h:outputScript name="js/main.js" target="body"/>
</h:head>
<h:body>
    <div class="container">
        <header>
            <h1>员工信息管理系统</h1>
            <nav>
                <h:link outcome="/employee/list" value="员工列表"/>
                <h:link outcome="/employee/search" value="员工搜索"/>
                <h:link outcome="/employee/edit" value="新增员工">
                    <f:param name="id" value="#{null}"/>
                </h:link>
            </nav>
        </header>
        
        <ui:insert name="content">默认内容</ui:insert>
        
        <footer>
            <p>© 2023 员工管理系统 - Jakarta EE 10</p>
        </footer>
    </div>
</h:body>
</html>

7. 员工列表页面 (list.xhtml)

xhtml

复制

下载

复制代码
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
                xmlns:h="http://xmlns.jcp.org/jsf/html"
                xmlns:f="http://xmlns.jcp.org/jsf/core"
                template="/WEB-INF/templates/template.xhtml">
    
    <ui:define name="content">
        <h2>员工列表</h2>
        
        <h:form id="listForm">
            <h:dataTable value="#{employeeBean.employees}" var="emp" 
                         styleClass="emp-table" rowClasses="odd-row,even-row">
                <h:column>
                    <f:facet name="header">#</f:facet>
                    #{emp.id}
                </h:column>
                <h:column>
                    <f:facet name="header">员工编号</f:facet>
                    #{emp.employeeNumber}
                </h:column>
                <h:column>
                    <f:facet name="header">姓名</f:facet>
                    #{emp.name}
                </h:column>
                <h:column>
                    <f:facet name="header">部门</f:facet>
                    #{emp.department}
                </h:column>
                <h:column>
                    <f:facet name="header">手机号码</f:facet>
                    #{emp.phoneNumber}
                </h:column>
                <h:column>
                    <f:facet name="header">操作</f:facet>
                    <h:link outcome="/employee/edit" value="编辑">
                        <f:param name="id" value="#{emp.id}"/>
                    </h:link>
                    <h:commandLink value="删除" action="#{employeeBean.delete(emp.id)}"
                                   οnclick="return confirmDelete()"/>
                </h:column>
            </h:dataTable>
        </h:form>
    </ui:define>
</ui:composition>

8. 员工编辑页面 (edit.xhtml)

xhtml

复制

下载

复制代码
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
                xmlns:h="http://xmlns.jcp.org/jsf/html"
                xmlns:f="http://xmlns.jcp.org/jsf/core"
                template="/WEB-INF/templates/template.xhtml">
    
    <ui:define name="content">
        <h2>#{employeeBean.employee.id == null ? '新增' : '编辑'}员工</h2>
        
        <h:form id="editForm">
            <h:inputHidden value="#{employeeBean.employee.id}"/>
            
            <h:panelGrid columns="3" styleClass="form-grid">
                <h:outputLabel for="empNumber" value="员工编号 *"/>
                <h:inputText id="empNumber" value="#{employeeBean.employee.employeeNumber}"
                             required="true" requiredMessage="员工编号不能为空"/>
                <h:message for="empNumber" styleClass="error"/>
                
                <h:outputLabel for="name" value="姓名 *"/>
                <h:inputText id="name" value="#{employeeBean.employee.name}"
                            required="true" requiredMessage="姓名不能为空"/>
                <h:message for="name" styleClass="error"/>
                
                <h:outputLabel for="department" value="部门"/>
                <h:inputText id="department" value="#{employeeBean.employee.department}"/>
                <h:message for="department"/>
                
                <h:outputLabel for="phone" value="手机号码"/>
                <h:inputText id="phone" value="#{employeeBean.employee.phoneNumber}"/>
                <h:message for="phone"/>
            </h:panelGrid>
            
            <div class="form-actions">
                <h:commandButton value="保存" action="#{employeeBean.save}" 
                                styleClass="btn-save"/>
                <h:button value="取消" outcome="/employee/list" styleClass="btn-cancel"/>
            </div>
        </h:form>
        
        <f:metadata>
            <f:viewParam name="id" value="#{employeeBean.employee.id}"/>
            <f:event type="preRenderView" 
                    listener="#{employeeBean.prepareEdit(employeeBean.employee.id)}"/>
        </f:metadata>
    </ui:define>
</ui:composition>

9. 员工搜索页面 (search.xhtml)

xhtml

复制

下载

复制代码
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
                xmlns:h="http://xmlns.jcp.org/jsf/html"
                xmlns:f="http://xmlns.jcp.org/jsf/core"
                template="/WEB-INF/templates/template.xhtml">
    
    <ui:define name="content">
        <h2>员工搜索</h2>
        
        <h:form id="searchForm">
            <h:inputText value="#{employeeBean.searchKeyword}" 
                        placeholder="输入姓名、部门或手机号"/>
            <h:commandButton value="搜索" action="#{employeeBean.search}" 
                            styleClass="btn-search"/>
            
            <h:dataTable value="#{employeeBean.employees}" var="emp" 
                         rendered="#{not empty employeeBean.employees}"
                         styleClass="search-results">
                <!-- 同列表页的列定义 -->
            </h:dataTable>
            
            <h:outputText value="未找到匹配的员工" 
                          rendered="#{empty employeeBean.employees and not empty employeeBean.searchKeyword}"/>
        </h:form>
    </ui:define>
</ui:composition>

10. JavaScript增强功能 (main.js)

javascript

复制

下载

复制代码
// 删除确认
function confirmDelete() {
    return confirm("确定要删除该员工记录吗?此操作不可撤销!");
}

// 表单验证增强
document.addEventListener('DOMContentLoaded', function() {
    const forms = document.querySelectorAll('form');
    forms.forEach(form => {
        form.addEventListener('submit', function() {
            const requiredFields = form.querySelectorAll('[required]');
            let valid = true;
            
            requiredFields.forEach(field => {
                if (!field.value.trim()) {
                    valid = false;
                    field.classList.add('input-error');
                } else {
                    field.classList.remove('input-error');
                }
            });
            
            if (!valid) {
                alert('请填写所有必填字段(标有*的字段)');
            }
            
            return valid;
        });
    });
});

11. 数据库初始化脚本 (data.sql)

sql

复制

下载

复制代码
INSERT INTO employee (employee_number, name, department, phone) VALUES
('EMP001', '张三', '技术部', '13800138000'),
('EMP002', '李四', '市场部', '13900139000'),
('EMP003', '王五', '财务部', '13700137000');

12. 系统功能说明

  1. 员工管理

    • 列表展示:分页显示所有员工

    • 新增员工:带表单验证

    • 编辑员工:通过URL参数传递ID

    • 删除员工:JavaScript确认对话框

  2. 搜索功能

    • 关键字搜索:支持姓名/部门/手机号模糊搜索

    • 实时结果显示:AJAX风格体验

  3. 技术亮点

    • JSF组件化UI:Facelets模板、数据表格、表单验证

    • EJB事务管理:@Stateless EJB处理业务逻辑

    • JPA ORM:实体关系映射、JPQL查询

    • 响应式设计:CSS媒体查询适配移动设备

    • JavaScript增强:表单验证、删除确认

13. 部署指南

  1. 环境要求

    • Jakarta EE 10兼容服务器(WildFly 27+ / GlassFish 7+)

    • Java 17+

    • 数据库(MySQL / PostgreSQL / H2)

  2. 部署步骤

bash

复制

下载

复制代码
# 1. 创建数据库和数据源
$ sudo mysql -e "CREATE DATABASE employeedb"
$ sudo mysql -e "CREATE USER 'employee'@'localhost' IDENTIFIED BY 'password'"
$ sudo mysql -e "GRANT ALL ON employeedb.* TO 'employee'@'localhost'"

# 2. 配置WildFly数据源
$ /path/to/wildfly/bin/jboss-cli.sh
connect
module add --name=com.mysql --resources=/path/to/mysql-connector-j.jar --dependencies=javax.api,javax.transaction.api
data-source add --name=EmployeeDS --jndi-name=java:global/jdbc/EmployeeDS \
    --driver-name=mysql --connection-url=jdbc:mysql://localhost:3306/employeedb \
    --user-name=employee --password=password

# 3. 构建部署
mvn clean package wildfly:deploy
  1. 访问路径

14. 技术选择原因

  1. JSF作为主要UI框架

    • 组件化开发模式

    • 内置AJAX支持

    • 强大的生命周期管理

    • 与Jakarta EE无缝集成

  2. JavaScript增强场景

    • 客户端表单验证

    • 删除操作确认

    • 动态UI效果

    • AJAX回调处理

  3. EJB + JPA架构优势

    • 声明式事务管理

    • 容器管理持久化

    • 分布式事务支持

    • 线程安全保证

此实现严格遵循Jakarta EE 10规范,采用分层架构设计,实现了所有需求功能,并提供了良好的用户体验和代码可维护性。

相关推荐
徐子童24 分钟前
《Spring Cloud Gateway 快速入门:从路由到自定义 Filter 的完整教程》
java·开发语言·spring cloud·nacos·gateway
Maxwellhang2 小时前
【音频处理】java流式调用ffmpeg命令
java·ffmpeg·音视频
Maỿbe2 小时前
阻塞队列的学习以及模拟实现一个阻塞队列
java·数据结构·线程
we风3 小时前
【SpringCache 提供的一套基于注解的缓存抽象机制】
java·缓存
趙卋傑5 小时前
网络编程套接字
java·udp·网络编程·tcp
两点王爷6 小时前
Java spingboot项目 在docker运行,需要含GDAL的JDK
java·开发语言·docker
万能螺丝刀18 小时前
java helloWord java程序运行机制 用idea创建一个java项目 标识符 关键字 数据类型 字节
java·开发语言·intellij-idea
zqmattack8 小时前
解决idea与springboot版本问题
java·spring boot·intellij-idea
Hygge-star8 小时前
【Java进阶】图像处理:从基础概念掌握实际操作
java·图像处理·人工智能·程序人生·职场和发展
Honmaple8 小时前
IDEA修改JVM内存配置以后,无法启动
java·ide·intellij-idea