JPA(Java Persistence API)是JSR(Java Specification Requests)的一部分,定义了一系列对象持久化的标准,目前实现这一规范的产品有Hibernate、TopLink等。
下面的示例程序是在jboss quickStart的基础上修改而来的
1、实体Bean:Member类
1 packageorg.jboss.as.quickstart.hibernate4.model;2
3 importjava.io.Serializable;4
5 importjavax.persistence.Column;6 importjavax.persistence.Entity;7 importjavax.persistence.GeneratedValue;8 importjavax.persistence.GenerationType;9 importjavax.persistence.Id;10 importjavax.persistence.SequenceGenerator;11 importjavax.persistence.Table;12 importjavax.validation.constraints.Digits;13 importjavax.validation.constraints.NotNull;14 importjavax.validation.constraints.Pattern;15 importjavax.validation.constraints.Size;16 importjavax.xml.bind.annotation.XmlRootElement;17 importorg.hibernate.validator.constraints.Email;18 importorg.hibernate.validator.constraints.NotEmpty;19
20 @Entity21 @XmlRootElement22 @Table(name = "MemberHibernate4Demo")23 public class Member implementsSerializable {24
25 private static final long serialVersionUID = 3862416351900991824L;26
27 @Id28 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_ID_GENERATOR")29 @SequenceGenerator(name = "MEMBER_ID_GENERATOR", sequenceName = "SEQ_MEMBER", allocationSize = 1)30 privateLong id;31
32 @NotNull33 @Size(min = 1, max = 25)34 @Pattern(regexp = "[A-Za-z ]*", message = "must contain only letters and spaces")35 privateString name;36
37 @NotNull38 @NotEmpty39 @Email40 privateString email;41
42 @NotNull43 @Size(min = 9, max = 12)44 @Digits(fraction = 0, integer = 12)45 @Column(name = "phone_number")46 privateString phoneNumber;47
48 privateString address;49
50 publicLong getId() {51 returnid;52 }53
54 public voidsetId(Long id) {55 this.id =id;56 }57
58 publicString getName() {59 returnname;60 }61
62 public voidsetName(String name) {63 this.name =name;64 }65
66 publicString getEmail() {67 returnemail;68 }69
70 public voidsetEmail(String email) {71 this.email =email;72 }73
74 publicString getPhoneNumber() {75 returnphoneNumber;76 }77
78 public voidsetPhoneNumber(String phoneNumber) {79 this.phoneNumber =phoneNumber;80 }81
82 publicString getAddress() {83 returnaddress;84 }85
86 public voidsetAddress(String address) {87 this.address =address;88 }89
90 publicString toString() {91
92 return "id:" + id + ",name:" + name + ",email:" +email93 + ",phoneNumber:" + phoneNumber + ",address:" +address;94 }95 }
Member
注意:私有成员id上的注解@SequenceGenerator、@GeneratedValue演示Oracle中序列(Sequence)的用法。
2、服务接口 MemberService
1 packageorg.jboss.as.quickstart.hibernate4.service;2
3 importjava.util.List;4
5 importorg.jboss.as.quickstart.hibernate4.model.Member;6
7 public interfaceMemberService {8
9 void addMember(Member member) throwsException;10
11 void updateMember(Member member) throwsException;12
13 void deleteMember(long id) throwsException;14
15 Member findMember(long id) throwsException;16
17 List getMembers() throwsException;18
19 }
MemberService
3、服务实现 MemberServiceImpl
1 packageorg.jboss.as.quickstart.hibernate4.service;2
3 importjava.util.logging.Logger;4 importjava.util.List;5 importjavax.ejb.Stateless;6 importjavax.enterprise.event.Event;7 importjavax.inject.Inject;8 importjavax.persistence.EntityManager;9 importjavax.persistence.PersistenceContext;10 importorg.jboss.as.quickstart.hibernate4.model.Member;11
12 @Stateless13 public class MemberServiceImpl implementsMemberService {14
15 @PersistenceContext16 privateEntityManager em;17
18 @Inject19 privateLogger log;20
21 @Inject22 private EventmemberEventSrc;23
24 @Override25 public void addMember(Member member) throwsException {26 log.info("addMember => " +member.toString());27 member.setId(null);28 em.persist(member);29 memberEventSrc.fire(member);30 }31
32 @Override33 public void updateMember(Member member) throwsException {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 @Override48 public void deleteMember(long id) throwsException {49 log.info("deleteMember => " +id);50 Member member =findMember(id);51 em.remove(member);52 memberEventSrc.fire(member);53
54 }55
56 @Override57 public List getMembers() throwsException {58 @SuppressWarnings("unchecked")59 List members = em.createQuery("from Member").getResultList();60 returnmembers;61
62 }63
64 @Override65 public Member findMember(long id) throwsException {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
1 packageorg.jboss.as.quickstart.hibernate4.util;2
3 importjava.util.Map;4 importjava.util.logging.Logger;5 importjavax.enterprise.context.RequestScoped;6 importjavax.enterprise.inject.Produces;7 importjavax.enterprise.inject.spi.InjectionPoint;8 importjavax.faces.context.FacesContext;9
10 public classResources {11
12 @Produces13 publicLogger produceLog(InjectionPoint injectionPoint) {14 returnLogger.getLogger(injectionPoint.getMember().getDeclaringClass()15 .getName());16 }17
18 @Produces19 @RequestScoped20 publicFacesContext produceFacesContext() {21 returnFacesContext.getCurrentInstance();22 }23
24 @Produces25 @RequestScoped26 public MapgetRequestParameterMap(){27 returnFacesContext.getCurrentInstance().getExternalContext()28 .getRequestParameterMap();29 }30
31
32 }
Resources
注:该类主要用@Produces提供了CDI注入对象的实例化方法。
5、web层的Controller:MemberController
1 packageorg.jboss.as.quickstart.hibernate4.controller;2
3 importjava.util.List;4 importjava.util.Map;5
6 importjavax.annotation.PostConstruct;7 importjavax.enterprise.inject.Model;8 importjavax.enterprise.inject.Produces;9 importjavax.faces.application.FacesMessage;10 importjavax.faces.context.FacesContext;11 importjavax.inject.Inject;12 importjavax.inject.Named;13
14 importorg.jboss.as.quickstart.hibernate4.model.Member;15 importorg.jboss.as.quickstart.hibernate4.service.MemberService;16
17 @Model18 public classMemberController {19
20 @Inject21 MemberService service;22
23 @Inject24 privateFacesContext facesContext;25
26 @Inject27 private MaprequestMap;28
29 privateMember newMember;30
31 @Produces32 @Named33 publicMember getNewMember() {34 returnnewMember;35 }36
37 @Produces38 @Named39 public ListgetMembers() {40 List members = null;41 try{42 members =service.getMembers();43
44 } catch(Exception e) {45 String errorMessage =getRootErrorMessage(e);46 facesContext.addMessage(null, newFacesMessage(47 FacesMessage.SEVERITY_ERROR, errorMessage,48 "Delete unsuccessful"));49 }50 returnmembers;51 }52
53 public voiddeleteMemberById() {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, newFacesMessage(61 FacesMessage.SEVERITY_ERROR, errorMessage,62 "Delete unsuccessful"));63 }64
65 }66
67 public voidfindMemberById() {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, newFacesMessage(74 FacesMessage.SEVERITY_ERROR, errorMessage,75 "Find Member unsuccessful"));76 }77
78 }79
80 public voidregister() {81 try{82 if (newMember.getId() > 0) {83 service.updateMember(newMember);84 facesContext.addMessage(null, newFacesMessage(85 FacesMessage.SEVERITY_INFO, "Updated!",86 "Update successful"));87 } else{88 service.addMember(newMember);89 facesContext.addMessage(null, newFacesMessage(90 FacesMessage.SEVERITY_INFO, "Registered!",91 "Registration successful"));92 }93 initNewMember();94 } catch(Exception e) {95 String errorMessage =getRootErrorMessage(e);96 facesContext.addMessage(null, newFacesMessage(97 FacesMessage.SEVERITY_ERROR, errorMessage,98 "Save unsuccessful"));99 }100 }101
102 @PostConstruct103 public voidinitNewMember() {104 newMember = newMember();105 }106
107 privateString getRootErrorMessage(Exception e) {108 String errorMessage = "Registration failed. See server log for more information";109 if (e == null) {110 returnerrorMessage;111 }112
113 Throwable t =e;114 while (t != null) {115
116 errorMessage =t.getLocalizedMessage();117 t =t.getCause();118 }119
120 returnerrorMessage;121 }122
123 }
MemberController
6、UI界面index.xhtml
1 <?xml version="1.0" encoding="UTF-8"?>
2
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
8
9
Member Registration
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 value="Register"styleClass="register" />
34
35 infoClass="valid"warnClass="warning"globalOnly="true" />
36
37
38
39
Members
40
41 No registered members.
42
43
44 rendered="#{not empty members}"styleClass="simpletablestyle">
45
46 Id
47 #{_member.id}48
49
50 Name
51 #{_member.name}52
53
54 Email
55 #{_member.email}56
57
58 Phone #
59 #{_member.phoneNumber}60
61
62 Address
63 #{_member.address}64
65
66 Operation
67
68
69 value="delete">
70
71 |72
73 value="update">
74
75
76
77
78
79
80
index.xhtml
7、persistence.xml 配置文件
1 <?xml version="1.0" encoding="UTF-8"?>
2
3
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/persistence7 http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
8
9 java:/XE
10 META-INF/orm.xml
11
12
13
14
15
16
17
18
persistence.xml
注:该文件位于src/main/resources/META-INF/目录下。java:/XE 是Jboss上配置好的一个数据源JNDI字符串。hibernate.hbm2ddl.auto属性值为create-drop,表明webapp启动时,会自动在db中创建表、序列对象,webapp停止时这些对象会自动drop
8、db初始化脚本 import.sql (测试的时候十分有用)
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
运行截图: