Oracle Enterprise Pack for Eclip…

本文介绍了如何使用Oracle Enterprise Pack for Eclipse (OEPE)的JPA功能构建Java EE应用程序,包括从现有表或Java类创建实体,开发测试实体的会话Bean和Servlet,并在WebLogic Server上部署。文章详细阐述了配置Eclipse与WebLogic、创建JPA项目、从表生成实体、编辑实体、测试实体等步骤。
摘要由CSDN通过智能技术生成

作者:Andrei Cioroianu

了解如何使用 Oracle Enterprise Pack for Eclipse (OEPE) 的 Java 持久性 API (JPA) 构建 Java EE 应用程序,从而将对象映射到关系数据库。

Oracle Enterprise Pack for Eclipse (OEPE) 是一系列经认证的插件,用于开发可以从 Eclipse IDE 轻松部署到 Oracle WebLogic Server 上的 Java EE 应用程序。在本文中,您将了解如何使用 OEPE 的 Java 持久性 API (JPA) 编辑器和向导从现有表或 Java 类创建实体。您还将了解如何开发用于测试实体的会话 Bean 和 Servlet。所有这些组件都将打包到一个在 WebLogic Server 上运行的 Java EE 应用程序中。本文假设您已经安装了带有 OEPE 11g、Oracle WebLogic 10g 第 3 版和 Oracle 数据库 XE 的 Eclipse 3.4。

应用程序设置

在本部分中,您将了解如何在 Eclipse 中配置 WebLogic,以便能够在代码中使用 Java EE API 并从 IDE 直接部署应用程序(如后文中所示)。您还将了解如何在 Eclipse 和 WebLogic 中设置数据源并使用 OEPE 11g 向导创建 JPA 项目。

在 Eclipse 中配置 Oracle WebLogic Server

首先,确保已正确配置 WebLogic 域。要创建一个新域或查看现有域,单击 Start > Programs > Oracle Fusion Middleware > WebLogic Server 10.3 > Tools > Configuration Wizard

图 1
图-1

在验证或创建 WebLogic 域之后,返回 Eclipse,单击 File > New > Other...,选择 Server 并单击 Next

图 2
图-2

输入服务器的主机名,选择 Oracle WebLogic Server 10gR3 并单击 Next

图 3
图-3

选择 WebLogic Home 并单击 Next

图 4
图-4

选择 Server TypeDomain Directory,然后单击 Finish

图 5
图-5

要从 Eclipse 启动 WebLogic,转至 Servers 视图,右键单击 Oracle WebLogic Server 10gR3 并单击 Start

从 Eclipse 和 WebLogic 连接到 Oracle 数据库

如果您刚刚安装 Oracle 数据库,则必须取消锁定 HR 用户,这样才可以访问 Oracle 数据库 XE 的示例模式。单击 Start > Programs > Oracle Database 10g Express Edition > Go To Database Home Page。使用安装 Oracle 数据库 XE 时提供的口令,以 SYSTEM 身份登录,单击 Administration > Database Users > HR,输入 HR 用户的口令两次,选择 Unlocked 并单击 Alter User

图 6
图-6

现在,您可以在 Eclipse 中配置数据库连接。单击 Window > Show View > Other...,选择 Data Management > Data Source Explorer 并单击 OK。右键单击 Database Connections,单击 New,选择 Oracle Database Connection,输入连接名 hr,然后单击 Next

图 7
图-7

选择 Oracle Database 10g Driver Default,如果需要,则更改 jdbc:oracle:thin:@localhost:1521:xe URL 中的服务器名称,输入用户名 hr 及其口令,单击 Test Connection 验证所有内容都正确,然后单击 Finish

图 8
图-8

右键单击 hr 模式,如果尚未连接,则单击 Connect,展开 hr > orcl > Schemas,右键单击 HR,然后单击 Show in Schema Viewer

图 9
图-9

您还必须在 WebLogic 中配置 hr 数据源以便可以在应用程序中使用。在 Web 浏览器中打开 http://localhost:7001/console/,登录并单击 JDBC > Data Sources。单击 New,在 name 域中输入 hr,在 JNDI name 域中输入 hr,选择 Oracle 数据库类型,选择 Oracle's Driver (Thin) Versions:9.0.1, 9.2.0, 10, 11,然后单击 Next。保留 Transaction Options 不变,单击 Next。输入数据库名称 xe、您的数据库主机名、端口号 1521、用户名 hr、口令,然后单击 Next。验证 URL(例如 jdbc:oracle:thin:@localhost:1521:xe),然后单击 Next。在最后一个屏幕中,选中 AdminServer 并单击 Finish

重要事项! 在 WebLogic Server Administration Console 中单击 Log Out,以便从 Eclipse 中部署应用程序。如果您在 Eclipse 中看到以下错误,应转至 WebLogic 控制台并注销。

图 10
图-10

创建 JPA 项目

单击 File > New > Project...New Project 窗口中,展开 JPA 节点并选择 JPA Project。然后单击 Next

图 11
图-11

输入 HRModel 作为名称,保持 Oracle WebLogic Server v10.3 目标运行时不变,使用 Utility JPA project with Java 5.0 配置,选择 Add project to an EAR 复选框,在 EAR Project Name 的文本域中输入 HRApp,然后单击 Next

图 12
图-12

默认的 JPA 平台为 Generic,这意味着您仅能使用标准的 JPA 1.0 功能。如果要使用将添加到 JPA 2.0 的特性或希望配置特定于 EclipseLink JPA 实施的属性,如 Persistence Unit Customization、Caching、Logging、Session Options 和 Schema Generation,选择 EclipseLink 平台。选择 hr 连接,保留其余设置不变并单击 Finish

图 13
图-13

当询问您是否要打开 JPA 透视图时,单击 Yes

图 14
图-14

创建并修改实体

在本部分中,您将学习如何从现有表或 Java 类生成 JPA 实体、如何在 JPA Entity Editor 中查看其关联、如何在 JPA Structure 和 JPA Details 视图中修改您的实体以及如何使用 JPA 配置编辑器。OEPE 11g 提供了以上所有向导。

从表创建实体

接下来,您将从 HR 模式的 DEPARTMENTSEMPLOYEES 表生成两个实体类。下面包括了这些表的 CREATE 语句。由于表已经存在,您不必运行这些语句。注意看一下外键,因为我们将在后文中对其进行讨论。

CREATE TABLE  "DEPARTMENTS"         ("DEPARTMENT_ID" NUMBER(4,0),          "DEPARTMENT_NAME" VARCHAR2(30) CONSTRAINT  "DEPT_NAME_NN" NOT NULL ENABLE,          "MANAGER_ID" NUMBER(6,0),          "LOCATION_ID" NUMBER(4,0),           CONSTRAINT "DEPT_ID_PK" PRIMARY KEY  ("DEPARTMENT_ID") ENABLE,           CONSTRAINT "DEPT_LOC_FK" FOREIGN KEY ("LOCATION_ID")           REFERENCES  "LOCATIONS"  ("LOCATION_ID") ENABLE,           CONSTRAINT "DEPT_MGR_FK" FOREIGN KEY ("MANAGER_ID")           REFERENCES  "EMPLOYEES"  ("EMPLOYEE_ID") ENABLE        )  
CREATE TABLE "EMPLOYEES" ("EMPLOYEE_ID" NUMBER(6,0), "FIRST_NAME" VARCHAR2(20), "LAST_NAME" VARCHAR2(25) CONSTRAINT "EMP_LAST_NAME_NN" NOT NULL ENABLE, "EMAIL" VARCHAR2(25) CONSTRAINT "EMP_EMAIL_NN" NOT NULL ENABLE, "PHONE_NUMBER" VARCHAR2(20), "HIRE_DATE" DATE CONSTRAINT "EMP_HIRE_DATE_NN" NOT NULL ENABLE, "JOB_ID" VARCHAR2(10) CONSTRAINT "EMP_JOB_NN" NOT NULL ENABLE, "SALARY" NUMBER(8,2), "COMMISSION_PCT" NUMBER(2,2), "MANAGER_ID" NUMBER(6,0), "DEPARTMENT_ID" NUMBER(4,0), CONSTRAINT "EMP_SALARY_MIN" CHECK (salary > 0) ENABLE, CONSTRAINT "EMP_EMAIL_UK" UNIQUE ("EMAIL") ENABLE, CONSTRAINT "EMP_EMP_ID_PK" PRIMARY KEY ("EMPLOYEE_ID") ENABLE, CONSTRAINT "EMP_DEPT_FK" FOREIGN KEY ("DEPARTMENT_ID") REFERENCES "DEPARTMENTS" ("DEPARTMENT_ID") ENABLE, CONSTRAINT "EMP_JOB_FK" FOREIGN KEY ("JOB_ID") REFERENCES "JOBS" ("JOB_ID") ENABLE, CONSTRAINT "EMP_MANAGER_FK" FOREIGN KEY ("MANAGER_ID") REFERENCES "EMPLOYEES" ("EMPLOYEE_ID") ENABLE )

右键单击新创建的 HRModel 项目,单击 JPA > Generate Custom JPA Entities...,确保已选择 hr 连接,然后单击 Connect 图标(如果该图标处于启用状态。如果您已经连接,则该按钮处于禁用状态。)选择 DEPARTMENTSEMPLOYEES 表,然后单击 Next

图 15
图-15

在实际的应用程序中,通常,您将生成该模式的所有表的实体。但是出于学习目的,表越少越简单。JPA 向导将分析外键,为该示例所选的两个表提出三个表关联建议。

图 16
图-16

在大多数情况下,仅凭该模式所包含的信息,向导还不足以确定您到底需要什么。因此,您通常需要编辑关联。单击第一个关联,位于 DEPARTMENTSEMPLOYEES 之间。将 employee 属性重命名为 manager,然后取消选中 Generate a reference to a collection of DEPARTMENTS in EMPLOYEES

图 17
图-17

单击第二个关联,使每个部门与其员工相对应。此处未作更改。

图 18
图-18

单击第三个关联,使每个员工与其主管相对应。该信息也可通过前面的关联获得。因此,第三个关联是多余的,可以删除。取消选中 Generate this association 并单击 Next

图 19
图-19

使用以下屏幕中的默认选项,输入 hr.model 作为 Package 名称,然后单击 Next

图 20
图-20

通过最后一个屏幕,您可以更改实体名称及其属性的名称和类型。在本例中,不必进行更改。单击 Finish 生成 Java 类型。

图 21
图-21

右键单击 HRModel 项目并单击 JPA > Show in Entity Editor,查看包含您刚刚创建的实体及其之间关系的图表。

图 22
图-22

以下是向导针对 Department 实体生成的源代码:

package hr.model;    import java.io.Serializable;    import javax.persistence.*;
@Entity() @Table(name="DEPARTMENTS") public class Department  implements Serializable {     private static final long serialVersionUID = 1L;
    @Id()     @Column(name="DEPARTMENT_ID")     private long departmentId;
    @Column(name="DEPARTMENT_NAME")     private String departmentName;
    @Column(name="LOCATION_ID")     private java.math.BigDecimal locationId;
    //uni-directional many-to-one association to Employee     @ManyToOne(fetch=FetchType.EAGER)     @JoinColumn(name="MANAGER_ID", referencedColumnName="EMPLOYEE_ID")     private Employee manager;
    //bi-directional many-to-one association to Employee     @OneToMany(mappedBy="department", fetch=FetchType.EAGER)     private java.util.Set<Employee> employees;
    public Department() {     }       public long getDepartmentId() {         return this.departmentId;     }
    public void setDepartmentId(long departmentId) {         this.departmentId = departmentId;     }
    ...
    public Employee getManager() {         return this.manager;     }
    public void setManager(Employee manager) {         this.manager = manager;     }         public java.util.Set<Employee> getEmployees() {         return this.employees;     }
    public void setEmployees(java.util.Set<Employee> employees) {         this.employees = employees;     }     }

向导还生成了 Employee 类:

package hr.model;    import java.io.Serializable;    import javax.persistence.*;
@Entity() @Table(name="EMPLOYEES") public class Employee  implements Serializable {     private static final long serialVersionUID = 1L;
    @Id()     @Column(name="EMPLOYEE_ID")     private long employeeId;
    @Column(name="FIRST_NAME")     private String firstName;
    @Column(name="LAST_NAME")     private String lastName;
    private String email;
    @Column(name="PHONE_NUMBER")     private String phoneNumber;
    @Column(name="HIRE_DATE")     private java.sql.Date hireDate;
    @Column(name="JOB_ID")     private String jobId;
    private java.math.BigDecimal salary;
    @Column(name="COMMISSION_PCT")     private java.math.BigDecimal commissionPct;
    //bi-directional many-to-one association to Department     @ManyToOne(fetch=FetchType.EAGER)     @JoinColumn(name="DEPARTMENT_ID", referencedColumnName="DEPARTMENT_ID")     private Department department;
    public Employee() {     }
    public long getEmployeeId() {         return this.employeeId;     }
    public void setEmployeeId(long employeeId) {         this.employeeId = employeeId;     }
    ...
    public Department getDepartment() {         return this.department;     }
    public void setDepartment(Department department) {         this.department = department;     }     }

在本示例中,由于数据库模式具有关于外键的信息,因此 JPA 向导能够建议关联。但是,有时外键不是由模式显式定义的,您没有权限更改表以添加外键。在这种情况下,您仍然可以使用向导定义表关联。

重要事项!如果模式包含外键,您不必按照该部分其余步骤操作。

假设 HR 示例模式没有外键。在这种情况下,Generate Custom Entities 向导的 Table Associations 列表将为空,如以下屏幕所示。

图 23
图-23

要添加关联,您可以单击 + (New Association) 按钮启动 Create New Association 子向导。例如,如果要在此处使用 DEPARTMENT_ID 列定义 EMPLOYEESDEPARTMENTS 之间的关系,按以下屏幕所示选择这两个表并单击 Next

图 24
图-24

然后,单击 Add,选择两个表的 DEPARTMENT_ID 列,然后单击 Next

图 25
图-25

在子向导的 Association Cardinality 屏幕中,选择 Many to one 并单击 Finish

图 26
图-26

之后,可以在主向导中查看该关联。

图 27
图-27

总之,通过 Generate Custom Entities 向导,您可以修改建议的关联并将模式中未指定的新关联添加为外键。该方法可以在创建实体时使用。稍后在本文中您将看到,在创建实体后也可以使用 JPA StructureJPA Details 视图定义和修改关联。

从 Java 类创建实体

本文的示例应用程序借助现有数据库启动,该数据库用于生成实体。也可以首先创建 Java 类,然后使用 JPA > Generate DDL... 创建表。第三种方法是将现有类映射到现有表。在本部分中,我们将从 Java 类构建一个新实体,该类将映射到 JOBS 表,其 CREATE 语句如下所示:

CREATE TABLE  "JOBS"       ("JOB_ID" VARCHAR2(10),        "JOB_TITLE" VARCHAR2(35) CONSTRAINT "JOB_TITLE_NN"  NOT NULL ENABLE,        "MIN_SALARY" NUMBER(6,0),        "MAX_SALARY" NUMBER(6,0),         CONSTRAINT "JOB_ID_PK" PRIMARY KEY ("JOB_ID") ENABLE      )  

hr.model 包中创建一个新类 Job,并粘贴以下代码:

package  hr.model;    import  java.io.Serializable;    import  java.math.BigDecimal;
public class Job implements Serializable {     private static final long serialVersionUID = 1L;     private String jobId;     private String jobTitle;     private BigDecimal minSalary;     private BigDecimal maxSalary;
    public Job() {         super();     }
    public String getJobId() {         return this.jobId;     }
    public void setJobId(String jobId) {         this.jobId = jobId;     }
    public String getJobTitle() {         return this.jobTitle;     }
    public void setJobTitle(String jobTitle) {         this.jobTitle = jobTitle;     }
    public BigDecimal getMinSalary() {         return this.minSalary;     }
    public void setMinSalary(BigDecimal minSalary) {         this.minSalary = minSalary;     }
    public BigDecimal getMaxSalary() {         return this.maxSalary;     }
    public void setMaxSalary(BigDecimal maxSalary) {         this.maxSalary = maxSalary;     }
}

右键单击 HRModel 项目并单击 JPA > Generate Entity from Java Class...单击 Browse 图标,选择 hr.model.Job 类,然后单击 Next

图 28
图-28

确保选择了 hr 连接和 HR 模式,选择 JOBS 表,保留 Primary key propertyjobId 选择,然后单击 Next

图 29
图-29

验证属性已正确映射到 JOBS 表的列,然后单击 Finish

图 30
图-30

该向导将向 Job 类中添加以下批注。

@Entity()    @Table(name="JOBS",  schema="HR")    public  class Job implements Serializable {        private static final long serialVersionUID  = 1L;
    @Id()     @Column(name="JOB_ID", unique=true, nullable=false, length=10)     private String jobId;
    @Basic()     @Column(name="JOB_TITLE", nullable=false, length=35)     private String jobTitle;
    @Basic()     @Column(name="MIN_SALARY", precision=10)     private BigDecimal minSalary;
    @Basic()     @Column(name="MAX_SALARY", precision=10)     private BigDecimal maxSalary;
    ... }

使用 JPA Structure 和 JPA Details

打开 Employee 实体,将 String jobId 字段替换为 Job job。还需要删除 @Column(name="JOB_ID") 批注,将 getJobId()setJobId() 方法替换为 getJob()setJob()

public  class Employee  implements Serializable  {        ...        private Job job;        ...        public Job getJob() {            return this.job;        }
    public void setJob(Job job) {         this.job = job;     }     ... }

Eclipse 将报告错误:Column "job" cannot be resolved。转至右上角的 JPA Structure 视图,右键单击 job 并单击 Map As > Many to One。向导将添加 @ManyToOne 批注。

图 31
图-31

您应该在右下角看到 JPA Detail 视图。验证 job 属性仍然正确,在 Fetch 列表中选择 Eager,选中 Join Columns 部分中的 Override Default,单击 Edit 按钮。

图 32
图-32

Name 域中的 job_JOB_ID 替换为 JOB_ID。单击 OK 之后,您应在 job 属性上方看到 @JoinColumn(name="JOB_ID", referencedColumnName = "JOB_ID") 批注。这将修复上面提示的错误。保存 Job.java 文件。

图 33
图-33

右键单击 HRModel 项目并单击 JPA > Show in Entity Editor,查看包含三个实体的已更新图表。

图 34
图-34

编辑 XML 配置文件

展开 HRModel 项目的 JPA Content 文件夹,然后双击 persistence.xml。通过配置编辑器,您可以设置该文件的属性。选择 Connection 选项卡,输入 hr 作为数据源。

图 35
图-35

然后,按 Ctrl+S 保存包含以下内容的 persistence.xml 文件。

<?xml  version="1.0" encoding="UTF-8"?>    <persistence  version="1.0"  xmlns="http://java.sun.com/xml/ns/persistence"             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence  ...">        <persistence-unit  name="HRModel">            <jta-data-source>hr</jta-data-source>            <class>hr.model.Department</class>            <class>hr.model.Employee</class>            <class>hr.model.Job</class>        </persistence-unit>    </persistence>  

测试实体

在本部分中,您将使用更多的 OEPE 11g 向导创建无状态会话 bean 和 servlet 来测试先前创建的实体。您还将了解如何在 WebLogic 上部署整个应用程序以及如何从 Eclipse 运行 servlet。

创建会话 Bean

单击 File > New > Project...New Project 窗口中,展开 EJB 节点,选择 EJB Project,然后单击 Next

图 36
图-36

输入 HREJB 作为名称,保持 Oracle WebLogic Server v10.3 目标运行时不变,使用 3.0 EJB 版本和 Default Configuration for Oracle WebLogic Server v10.3,选择 Add project to an EAR 复选框,选择 HRApp,然后单击 Next

图 37
图-37

在以下屏幕中,保持默认选项不变,然后单击 Finish

图 38
图-38

右键单击 HREJB 项目并单击 New > Session Bean,输入 hr.ejb 作为 Package 名称,输入 HRBean 作为类名称,使用 Stateless 类型,保留接口的名称 hr.ejb.HRBeanLocal 不变,然后单击 Next

图 39
图-39

不要修改以下屏幕中的默认设置,单击 Finish

图 40
图-40

打开 HREJBClient 项目的 hr.ejb.HRBeanLocal 接口,添加以下方法。

public Employee findEmployee(Integer empId);  

您将收到编译错误:Employee cannot be resolved to a type。要修复该错误,将鼠标移到 Employee 上,单击 Fix Project Setup...

图 41
图-41

选择 Add project 'HRModel' to build path of HREJBClient 并单击 OK,然后保存该文件。

图 42
图-42

返回 HRBean.java 文件,将鼠标移到类名称(应标有红色下划线)上,然后单击 Add unimplemented methods…

图 43
图-43

将鼠标移到 findEmployee() 方法的 Employee 返回类型上,单击 Fix Project Setup...,选择 Add project 'HRModel' to build path of HREJB,然后单击 OK。然后,在 HRBean 类的开头添加以下代码行:

@PersistenceContext  private  EntityManager em;  

将鼠标移到 @PersistenceContext 上,单击 Import 'PersistenceContext' (javax.persistence)。将鼠标移到 EntityManager 上,单击 Import 'EntityManager' (javax.persistence)。接下来,将 return null; 替换为 findEmployee() 方法中的以下代码,并保存 HRBean 类。

return  em.find(Employee.class, empId);

保存文件之后,您应该在 Problems 视图中看到没有错误。以下是 HRBean 类的完整源代码。

package  hr.ejb;  import  hr.model.Employee;
import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext;
@Stateless public class HRBean implements HRBeanLocal {
    @PersistenceContext     private EntityManager em;
        public HRBean() {         // TODO Auto-generated constructor stub     }
    @Override     public Employee findEmployee(Integer empId) {         return em.find(Employee.class, empId);     }
}

创建测试 Servlet

单击 File > New > Project...New Project 窗口中,展开 Web 节点,选择 Dynamic Web Project,然后单击 Next

图 44
图-44

输入 HRTest 作为 Web 项目的名称,选择 Add project to an EAR 复选框,选择 HRApp,然后单击 Next

图 45
图-45

在以下屏幕中,保持默认选项不变,然后单击 Finish

图 46
图-46

右键单击 HRTest 项目并单击 New > Servlet,输入 hr.test 作为 Package 名称,输入 HRServlet 作为类名称,然后单击 Finish

图 47
图-47

HRServlet 类的开头添加以下两行代码。

@EJB(name="HRBean")  private  HRBeanLocal hrBean;  

将鼠标移到 @EJB 上,单击 Import 'EJB' (javax.ejb)。将鼠标移到 HRBeanLocal 上,单击 Fix Project Setup...,选择 Add project 'HREJBClient' to build path of HRTest,单击 OK,然后保存文件。然后,在 HRServletdoGet() 方法中添加以下代码。

protected  void doGet(            HttpServletRequest request,  HttpServletResponse response)             throws ServletException, IOException {        response.setContentType("text/plain");        int empId = 100;        String empParam =  request.getParameter("emp");        if (empParam != null)            empId = Integer.parseInt(empParam);        PrintWriter out = response.getWriter();        Employee emp = hrBean.findEmployee(empId);        out.println("" + empId + ":  "             + emp.getFirstName() + " " +  emp.getLastName());        out.println("working in " +  emp.getDepartment().getDepartmentName()             + " department");        out.println("as " + emp.getJob().getJobTitle());        out.println("has " +  (emp.getDepartment().getEmployees().size()-1)             + " colleagues");    }  

将鼠标移到 PrintWriter 上,单击 Import 'PrintWriter' (java.io)。将鼠标移到 Employee 上,单击 Fix Project Setup...,选择 Add project 'HRModel' to build path of HRTest,单击 OK,然后保存 HRServlet.java 文件。

展开 HRTest > Java Resources > src > hr.test,右键单击 HRServlet.java 并单击 Run As > Run on Server,然后单击 Next

图 48
图-48

查看部署的应用程序,然后单击 Finish

图 49
图-49

您应该看到以下屏幕。

图 50
图-50

在 Eclipse 中 URL 的结尾添加 ?emp=101,然后按 Enter 键。您将看到下面的屏幕。

图 51
图-51

总结

在本文中,您了解了如何使用 Oracle Enterprise Pack for Eclipse (OEPE) 和 WebLogic 构建、部署和测试 Java EE 应用程序。我们主要讨论了 JPA 相关特性和向导,通过这些特性和向导,您可以从表或 Java 类中创建实体,然后在易于使用的编辑器和属性表中修改它们。


Andrei Cioroianu 是 Devsphere 的创始人,该公司主要提供 Java EE 开发和 Web 2.0/Ajax 咨询服务。他自 1997 年开始使用 Java 和 Web 技术,有着 10 多年的解决复杂技术问题和全程管理商业产品、定制应用程序和开源框架的专业经验。您可以通过

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值