JAVA JPA - 示例用法

JPA(Java Persistence API)是JSR(Java Specification Requests)的一部分,定义了一系列对象持久化的标准,目前实现这一规范的产品有Hibernate、TopLink等。

下面的示例程序是在jboss quickStart的基础上修改而来的

 

1、实体Bean:Member类

JAVA JPA - 示例用法JAVA JPA - 示例用法
 1 package org.jboss.as.quickstart.hibernate4.model;
 2 
 3 import java.io.Serializable;
 4 
 5 import javax.persistence.Column;
 6 import javax.persistence.Entity;
 7 import javax.persistence.GeneratedValue;
 8 import javax.persistence.GenerationType;
 9 import javax.persistence.Id;
10 import javax.persistence.SequenceGenerator;
11 import javax.persistence.Table;
12 import javax.validation.constraints.Digits;
13 import javax.validation.constraints.NotNull;
14 import javax.validation.constraints.Pattern;
15 import javax.validation.constraints.Size;
16 import javax.xml.bind.annotation.XmlRootElement;
17 import org.hibernate.validator.constraints.Email;
18 import org.hibernate.validator.constraints.NotEmpty;
19 
20 @Entity
21 @XmlRootElement
22 @Table(name = "MemberHibernate4Demo")
23 public class Member implements Serializable {
24 
25     private static final long serialVersionUID = 3862416351900991824L;
26 
27     @Id
28     @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_ID_GENERATOR")
29     @SequenceGenerator(name = "MEMBER_ID_GENERATOR", sequenceName = "SEQ_MEMBER", allocationSize = 1)
30     private Long id;
31 
32     @NotNull
33     @Size(min = 1, max = 25)
34     @Pattern(regexp = "[A-Za-z ]*", message = "must contain only letters and spaces")
35     private String name;
36 
37     @NotNull
38     @NotEmpty
39     @Email
40     private String email;
41 
42     @NotNull
43     @Size(min = 9, max = 12)
44     @Digits(fraction = 0, integer = 12)
45     @Column(name = "phone_number")
46     private String phoneNumber;
47 
48     private String address;
49 
50     public Long getId() {
51         return id;
52     }
53 
54     public void setId(Long id) {
55         this.id = id;
56     }
57 
58     public String getName() {
59         return name;
60     }
61 
62     public void setName(String name) {
63         this.name = name;
64     }
65 
66     public String getEmail() {
67         return email;
68     }
69 
70     public void setEmail(String email) {
71         this.email = email;
72     }
73 
74     public String getPhoneNumber() {
75         return phoneNumber;
76     }
77 
78     public void setPhoneNumber(String phoneNumber) {
79         this.phoneNumber = phoneNumber;
80     }
81 
82     public String getAddress() {
83         return address;
84     }
85 
86     public void setAddress(String address) {
87         this.address = address;
88     }
89 
90     public String toString() {
91 
92         return "id:" + id + ",name:" + name + ",email:" + email
93                 + ",phoneNumber:" + phoneNumber + ",address:" + address;
94     }
95 }
Member

注意:私有成员id上的注解@SequenceGenerator、@GeneratedValue演示Oracle中序列(Sequence)的用法。

 

2、服务接口 MemberService

JAVA JPA - 示例用法JAVA JPA - 示例用法
 1 package org.jboss.as.quickstart.hibernate4.service;
 2 
 3 import java.util.List;
 4 
 5 import org.jboss.as.quickstart.hibernate4.model.Member;
 6 
 7 public interface MemberService {
 8 
 9     void addMember(Member member) throws Exception;
10 
11     void updateMember(Member member) throws Exception;
12 
13     void deleteMember(long id) throws Exception;
14 
15     Member findMember(long id) throws Exception;
16 
17     List<Member> getMembers() throws Exception;
18 
19 }
MemberService

 

3、服务实现 MemberServiceImpl

JAVA JPA - 示例用法JAVA JPA - 示例用法
 1 package org.jboss.as.quickstart.hibernate4.service;
 2 
 3 import java.util.logging.Logger;
 4 import java.util.List;
 5 import javax.ejb.Stateless;
 6 import javax.enterprise.event.Event;
 7 import javax.inject.Inject;
 8 import javax.persistence.EntityManager;
 9 import javax.persistence.PersistenceContext;
10 import org.jboss.as.quickstart.hibernate4.model.Member;
11 
12 @Stateless
13 public class MemberServiceImpl implements MemberService {
14 
15     @PersistenceContext  
16     private EntityManager em;
17 
18     @Inject
19     private Logger log;
20 
21     @Inject
22     private Event<Member> memberEventSrc;
23 
24     @Override
25     public void addMember(Member member) throws Exception {
26         log.info("addMember => " + member.toString());
27         member.setId(null);
28         em.persist(member);
29         memberEventSrc.fire(member);
30     }
31 
32     @Override
33     public void updateMember(Member member) throws Exception {
34         log.info("updateMember => " + member.getName());
35         if (member.getId() > 0) {
36             Member updateObj = findMember(member.getId());
37             updateObj.setAddress(member.getAddress());
38             updateObj.setEmail(member.getEmail());
39             updateObj.setName(member.getName());
40             updateObj.setPhoneNumber(member.getPhoneNumber());
41             em.merge(updateObj);
42             memberEventSrc.fire(updateObj);
43         }
44 
45     }
46 
47     @Override
48     public void deleteMember(long id) throws Exception {
49         log.info("deleteMember => " + id);
50         Member member = findMember(id);
51         em.remove(member);
52         memberEventSrc.fire(member);
53 
54     }
55 
56     @Override
57     public List<Member> getMembers() throws Exception {
58         @SuppressWarnings("unchecked")
59         List<Member> members = em.createQuery("from Member").getResultList();
60         return members;
61 
62     }
63 
64     @Override
65     public Member findMember(long id) throws Exception {
66         log.info("findMember => " + id);
67         return em.find(Member.class, id);
68     }
69 
70 }
MemberService

注意:此外大量使用了CDI来实现对象的依赖注入,@PersistenceContext 用于在EJB容器中自动注入"实体管理器"(所以类上要使用@Stateless表示,这是一个无状态的EJB),上面这段代码演示了数据的基础CRUD(Create、Retrieve、Update、Delete)操作,另外为了配合CDI的@Inject注入,还需要一些@Produces的辅助工具类。(对CDI不熟悉的,可以先看看这里 http://www.cnblogs.com/yjmyzz/p/j2ee-cdi-inject.html )

 

4、辅助类 Resouces 

JAVA JPA - 示例用法JAVA JPA - 示例用法
 1 package org.jboss.as.quickstart.hibernate4.util;
 2 
 3 import java.util.Map;
 4 import java.util.logging.Logger;
 5 import javax.enterprise.context.RequestScoped;
 6 import javax.enterprise.inject.Produces;
 7 import javax.enterprise.inject.spi.InjectionPoint;
 8 import javax.faces.context.FacesContext;
 9 
10 public class Resources {
11 
12     @Produces
13     public Logger produceLog(InjectionPoint injectionPoint) {
14         return Logger.getLogger(injectionPoint.getMember().getDeclaringClass()
15                 .getName());
16     }
17 
18     @Produces
19     @RequestScoped
20     public FacesContext produceFacesContext() {
21         return FacesContext.getCurrentInstance();
22     }
23     
24     @Produces
25     @RequestScoped
26     public Map<String, String> getRequestParameterMap(){
27         return FacesContext.getCurrentInstance().getExternalContext()
28                 .getRequestParameterMap();
29     } 
30     
31 
32 }
Resources

注:该类主要用@Produces提供了CDI注入对象的实例化方法。

 

5、web层的Controller:MemberController

JAVA JPA - 示例用法JAVA JPA - 示例用法
  1 package org.jboss.as.quickstart.hibernate4.controller;
  2 
  3 import java.util.List;
  4 import java.util.Map;
  5 
  6 import javax.annotation.PostConstruct;
  7 import javax.enterprise.inject.Model;
  8 import javax.enterprise.inject.Produces;
  9 import javax.faces.application.FacesMessage;
 10 import javax.faces.context.FacesContext;
 11 import javax.inject.Inject;
 12 import javax.inject.Named;
 13 
 14 import org.jboss.as.quickstart.hibernate4.model.Member;
 15 import org.jboss.as.quickstart.hibernate4.service.MemberService;
 16 
 17 @Model
 18 public class MemberController {
 19 
 20     @Inject
 21     MemberService service;
 22 
 23     @Inject
 24     private FacesContext facesContext;
 25 
 26     @Inject
 27     private Map<String, String> requestMap;
 28 
 29     private Member newMember;
 30 
 31     @Produces
 32     @Named
 33     public Member getNewMember() {
 34         return newMember;
 35     }
 36 
 37     @Produces
 38     @Named
 39     public List<Member> getMembers() {
 40         List<Member> members = null;
 41         try {
 42             members = service.getMembers();
 43 
 44         } catch (Exception e) {
 45             String errorMessage = getRootErrorMessage(e);
 46             facesContext.addMessage(null, new FacesMessage(
 47                     FacesMessage.SEVERITY_ERROR, errorMessage,
 48                     "Delete unsuccessful"));
 49         }
 50         return members;
 51     }
 52 
 53     public void deleteMemberById() {
 54         try {
 55             String id = requestMap.get("id");
 56             service.deleteMember(Long.parseLong(id));
 57 
 58         } catch (Exception e) {
 59             String errorMessage = getRootErrorMessage(e);
 60             facesContext.addMessage(null, new FacesMessage(
 61                     FacesMessage.SEVERITY_ERROR, errorMessage,
 62                     "Delete unsuccessful"));
 63         }
 64 
 65     }
 66 
 67     public void findMemberById() {
 68         try {
 69             String id = requestMap.get("id");
 70             newMember = service.findMember(Long.parseLong(id));
 71         } catch (Exception e) {
 72             String errorMessage = getRootErrorMessage(e);
 73             facesContext.addMessage(null, new FacesMessage(
 74                     FacesMessage.SEVERITY_ERROR, errorMessage,
 75                     "Find Member unsuccessful"));
 76         }
 77 
 78     }
 79 
 80     public void register() {
 81         try {
 82             if (newMember.getId() > 0) {
 83                 service.updateMember(newMember);
 84                 facesContext.addMessage(null, new FacesMessage(
 85                         FacesMessage.SEVERITY_INFO, "Updated!",
 86                         "Update successful"));
 87             } else {
 88                 service.addMember(newMember);
 89                 facesContext.addMessage(null, new FacesMessage(
 90                         FacesMessage.SEVERITY_INFO, "Registered!",
 91                         "Registration successful"));
 92             }
 93             initNewMember();
 94         } catch (Exception e) {
 95             String errorMessage = getRootErrorMessage(e);
 96             facesContext.addMessage(null, new FacesMessage(
 97                     FacesMessage.SEVERITY_ERROR, errorMessage,
 98                     "Save unsuccessful"));
 99         }
100     }
101 
102     @PostConstruct
103     public void initNewMember() {
104         newMember = new Member();
105     }
106 
107     private String getRootErrorMessage(Exception e) {
108         String errorMessage = "Registration failed. See server log for more information";
109         if (e == null) {
110             return errorMessage;
111         }
112 
113         Throwable t = e;
114         while (t != null) {
115 
116             errorMessage = t.getLocalizedMessage();
117             t = t.getCause();
118         }
119 
120         return errorMessage;
121     }
122 
123 }
MemberController

 

6、UI界面index.xhtml

JAVA JPA - 示例用法JAVA JPA - 示例用法
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <ui:composition xmlns="http://www.w3.org/1999/xhtml"
 3     xmlns:ui="http://java.sun.com/jsf/facelets"
 4     xmlns:f="http://java.sun.com/jsf/core"
 5     xmlns:h="http://java.sun.com/jsf/html"
 6     template="/WEB-INF/templates/default.xhtml">
 7     <ui:define name="content">
 8         <h:form id="reg">
 9             <h2>Member Registration</h2>
10 
11             <h:panelGrid columns="3" width="100%" columnClasses="titleCell">
12                 <h:inputHidden value="#{newMember.id}" id="id" />
13                 <h:outputLabel for="name" value="Name:" />
14                 <h:inputText id="name" value="#{newMember.name}" />
15                 <h:message for="name" errorClass="invalid" />
16 
17                 <h:outputLabel for="email" value="Email:" />
18                 <h:inputText id="email" value="#{newMember.email}" />
19                 <h:message for="email" errorClass="invalid" />
20 
21                 <h:outputLabel for="phoneNumber" value="Phone #:" />
22                 <h:inputText id="phoneNumber" value="#{newMember.phoneNumber}" />
23                 <h:message for="phoneNumber" errorClass="invalid" />
24 
25                 <h:outputLabel for="address" value="Address:" />
26                 <h:inputText id="address" value="#{newMember.address}" />
27                 <h:message for="address" errorClass="invalid" />
28             </h:panelGrid>
29 
30 
31             <h:panelGrid columns="2">
32                 <h:commandButton id="register" action="#{memberController.register}"
33                     value="Register" styleClass="register" />
34                 <h:messages styleClass="messages" errorClass="invalid"
35                     infoClass="valid" warnClass="warning" globalOnly="true" />
36             </h:panelGrid>
37 
38         </h:form>
39         <h2>Members</h2>
40         <h:panelGroup rendered="#{empty members}">
41             <em>No registered members.</em>
42         </h:panelGroup>
43         <h:dataTable var="_member" value="#{members}"
44             rendered="#{not empty members}" styleClass="simpletablestyle">
45             <h:column>
46                 <f:facet name="header">Id</f:facet>
47                 #{_member.id}
48             </h:column>
49             <h:column>
50                 <f:facet name="header">Name</f:facet>
51                 #{_member.name}
52             </h:column>
53             <h:column>
54                 <f:facet name="header">Email</f:facet>
55                 #{_member.email}
56             </h:column>
57             <h:column>
58                 <f:facet name="header">Phone #</f:facet>
59                 #{_member.phoneNumber}
60             </h:column>
61             <h:column>
62                 <f:facet name="header">Address</f:facet>
63                 #{_member.address}
64             </h:column>
65             <h:column>
66                 <f:facet name="header">Operation</f:facet>
67                 <h:form style="border:none">
68                     <h:commandLink action="#{memberController.deleteMemberById}"
69                         value="delete">
70                         <f:param name="id" value="#{_member.id}"></f:param>
71                     </h:commandLink>|
72                 <h:commandLink action="#{memberController.findMemberById}"
73                         value="update">
74                         <f:param name="id" value="#{_member.id}"></f:param>
75                     </h:commandLink>
76                 </h:form>
77             </h:column>
78         </h:dataTable>
79     </ui:define>
80 </ui:composition>
index.xhtml

 

7、persistence.xml 配置文件

JAVA JPA - 示例用法JAVA JPA - 示例用法
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 
 3 <persistence version="2.0"
 4     xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5     xsi:schemaLocation="
 6         http://java.sun.com/xml/ns/persistence
 7         http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
 8     <persistence-unit name="primary">
 9         <jta-data-source>java:/XE</jta-data-source>
10         <mapping-file>META-INF/orm.xml</mapping-file>
11         <properties>
12             <property name="hibernate.hbm2ddl.auto" value="create-drop" />
13             <property name="hibernate.show_sql" value="true" />
14             <property name="hibernate.format_sql" value="true" />
15             <property name="hibernate.use_sql_comments" value="true"/>            
16         </properties>
17     </persistence-unit>
18 </persistence>
persistence.xml

注:该文件位于src/main/resources/META-INF/目录下。java:/XE 是Jboss上配置好的一个数据源JNDI字符串。hibernate.hbm2ddl.auto属性值为create-drop,表明webapp启动时,会自动在db中创建表、序列对象,webapp停止时这些对象会自动drop

 

8、db初始化脚本 import.sql (测试的时候十分有用)

JAVA JPA - 示例用法JAVA JPA - 示例用法
1 insert into MemberHibernate4Demo (id, name, email, phone_number, address) values (SEQ_MEMBER.NEXTVAL, 'John Smith', 'john.smith@mailinator.com', '2125551212', 'Boston NY') 
2 insert into MemberHibernate4Demo (id, name, email, phone_number, address) values (SEQ_MEMBER.NEXTVAL, 'Madhumita Sadhukhan', 'msadhukh@gmail.com', '2135551214', 'Brno CZ')
import.sql

注:该文件位于src/main/resources目录下,webapp启用时将自动执行该文件中的db 脚本 

 

9、其它运行准备:
9.1 要有Oracle Database环境,比如本机可以安装一个Express版本

9.2 Jboss中要配置一个java:/XE的数据源,步骤:

a) 先部署ojdbc6.jar (这是oracle驱动,安装oracle XE或client后,本机安装目录下就能找到)

b) 添加oracle 数据源,数据库驱动选择ojdbc6.jar,连接串参考 jdbc:oracle:thin:@localhost:1521:XE

 

示例程序下载:http://files.cnblogs.com/yjmyzz/jboss-jpa-sample.zip

运行截图:

JAVA JPA - 示例用法 

上一篇:centos7 安装 apache 并做 负载均衡


下一篇:修改Oracle默认监听端口