本文详细介绍EJB+JPA实现Entity的CRUD基本操作。
目录
- 创建POJO:BlogVo
- 创建Entity:Blog
- 配置persistence.xml
- 定义Remote接口
- 创建SessionBean实现类
- 配置datasource数据源
- 部署EJB工程
- 创建客户端测试类
- 运行测试类
[一]、创建POJO:BlogVo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
package
com
.
micmiu
.
ejb
.
vo
;
import
java
.
io
.
Serializable
;
/**
* Blog vo对象
*
* @author <a href="http://www.micmiu.com">Michael</a>
* @time Create on 2013-9-25 下午3:02:17
* @version 1.0
*/
public
class
BlogVo
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
6384496304647072095L
;
private
Integer
id
;
private
String
title
;
private
String
url
;
private
String
author
;
public
Integer
getId
(
)
{
return
id
;
}
public
String
getTitle
(
)
{
return
title
;
}
public
String
getUrl
(
)
{
return
url
;
}
public
String
getAuthor
(
)
{
return
author
;
}
public
void
setId
(
Integer
id
)
{
this
.
id
=
id
;
}
public
void
setTitle
(
String
title
)
{
this
.
title
=
title
;
}
public
void
setUrl
(
String
url
)
{
this
.
url
=
url
;
}
public
void
setAuthor
(
String
author
)
{
this
.
author
=
author
;
}
@
Override
public
String
toString
(
)
{
return
"BlogVo [id="
+
id
+
", title="
+
title
+
", url="
+
url
+
", author="
+
author
+
"]"
;
}
}
|
[二]、创建Entity:Blog.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
package
com
.
micmiu
.
ejb
.
entity
;
import
java
.
io
.
Serializable
;
import
javax
.
persistence
.
Column
;
import
javax
.
persistence
.
Entity
;
import
javax
.
persistence
.
GeneratedValue
;
import
javax
.
persistence
.
Id
;
import
javax
.
persistence
.
NamedQueries
;
import
javax
.
persistence
.
NamedQuery
;
import
javax
.
persistence
.
Table
;
/**
* 实体类blog
*
* @author <a href="http://www.micmiu.com">Michael</a>
* @time Create on 2013-9-24 下午1:57:47
* @version 1.0
*/
@
Entity
@
Table
(
name
=
"DEMO_T_BLOG"
)
@
NamedQueries
(
{
@
NamedQuery
(
name
=
"queryAll"
,
query
=
"select t from Blog t "
)
}
)
public
class
Blog
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
1371929956020543775L
;
@
Id
@
GeneratedValue
@
Column
(
name
=
"ID"
)
private
Integer
id
;
@
Column
(
name
=
"TITLE"
,
length
=
128
)
private
String
title
;
@
Column
(
name
=
"URL"
,
length
=
1024
)
private
String
url
;
@
Column
(
name
=
"AUTHOR"
,
length
=
20
)
private
String
author
;
public
Integer
getId
(
)
{
return
id
;
}
public
String
getTitle
(
)
{
return
title
;
}
public
String
getUrl
(
)
{
return
url
;
}
public
String
getAuthor
(
)
{
return
author
;
}
public
void
setId
(
Integer
id
)
{
this
.
id
=
id
;
}
public
void
setTitle
(
String
title
)
{
this
.
title
=
title
;
}
public
void
setUrl
(
String
url
)
{
this
.
url
=
url
;
}
public
void
setAuthor
(
String
author
)
{
this
.
author
=
author
;
}
@
Override
public
String
toString
(
)
{
return
"Blog [id="
+
id
+
", title="
+
title
+
", url="
+
url
+
", author="
+
author
+
"]"
;
}
}
|
[三]、配置persistence.xml
修改配置文件 src: META-INF/persistence.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<persistence
version
=
"2.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
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
>
<!-- 为持久化单元取名=micmiuJPA,transaction-type=JTA 利用容器的事务管理 -->
<persistence-unit
name
=
"micmiuJPA"
transaction-type
=
"JTA"
>
<provider>
org.hibernate.ejb.HibernatePersistence
</provider>
<jta-data-source>
java:/micmiuOracleDS
</jta-data-source>
<!-- <class>com.micmiu.ejb.entity.Blog</class> -->
<!-- 声明是否扫描jar文件中标注了@Enity类.若不扫描,值为true 默认也是true -->
<exclude-unlisted-classes>
true
</exclude-unlisted-classes>
<properties>
<property
name
=
"hibernate.archive.autodetection"
value
=
"class,hbm"
/>
<!--配置Hibernate方言 -->
<property
name
=
"hibernate.dialect"
value
=
"org.hibernate.dialect.Oracle10gDialect"
/>
<!--自动输出schema创建DDL语句 -->
<property
name
=
"hibernate.hbm2ddl.auto"
value
=
"update"
/>
<!-- 输出SQL语句 -->
<property
name
=
"hibernate.show_sql"
value
=
"true"
/>
<!-- 格式化SQL语句 -->
<property
name
=
"hibernate.format_sql"
value
=
"true"
/>
</properties>
</persistence-unit>
</persistence>
|
ps:<jta-data-source></jta-data-source>配置的值“java:/micmiuOracleDS”需要和JBOSS_HOME/server/default/conf/tandardjbosscmp-jdbc.xml 中配置的<datasource></datasource>一致,详见 下面 第[六]部分 配置datasource数据源
[四]、定义Remote接口
BlogBeanRemote.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package
com
.
micmiu
.
ejb
;
import
java
.
util
.
List
;
import
javax
.
ejb
.
Remote
;
import
com
.
micmiu
.
ejb
.
vo
.
BlogVo
;
/**
* BlogBean remote
*
* @author <a href="http://www.micmiu.com">Michael</a>
* @time Create on 2013-9-25 下午3:05:42
* @version 1.0
*/
@
Remote
public
interface
BlogBeanRemote
{
BlogVo
create
(
BlogVo
blog
)
;
BlogVo
read
(
Integer
id
)
;
void
update
(
BlogVo
blog
)
;
void
delete
(
Integer
id
)
;
List
&
lt
;
BlogVo
&
gt
;
queryAll
(
)
;
List
&
lt
;
BlogVo
&
gt
;
queryByAuthor
(
String
author
)
;
}
|
[五]、创建SessionBean实现类
BlogBean.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
package
com
.
micmiu
.
ejb
;
import
java
.
util
.
ArrayList
;
import
java
.
util
.
List
;
import
javax
.
ejb
.
Stateless
;
import
javax
.
persistence
.
EntityManager
;
import
javax
.
persistence
.
PersistenceContext
;
import
javax
.
persistence
.
Query
;
import
com
.
micmiu
.
ejb
.
entity
.
Blog
;
import
com
.
micmiu
.
ejb
.
vo
.
BlogVo
;
/**
* Session Bean implementation class BlogBean
*
* @author <a href="http://www.micmiu.com">Michael</a>
* @time Create on 2013-9-25 上午9:20:36
* @version 1.0
*/
@
Stateless
public
class
BlogBean
implements
BlogBeanRemote
{
@
PersistenceContext
(
unitName
=
"micmiuJPA"
)
private
EntityManager
em
;
/**
* Default constructor.
*/
public
BlogBean
(
)
{
}
@
Override
public
BlogVo
create
(
BlogVo
vo
)
{
Blog
po
=
this
.
parseVo2Po
(
vo
)
;
em
.
persist
(
po
)
;
em
.
flush
(
)
;
return
this
.
parsePo2Vo
(
po
)
;
}
@
Override
public
BlogVo
read
(
Integer
id
)
{
Blog
po
=
em
.
find
(
Blog
.
class
,
id
)
;
return
this
.
parsePo2Vo
(
po
)
;
}
@
Override
public
void
update
(
BlogVo
vo
)
{
Blog
po
=
this
.
parseVo2Po
(
vo
)
;
em
.
merge
(
po
)
;
}
@
Override
public
void
delete
(
Integer
id
)
{
em
.
remove
(
em
.
getReference
(
Blog
.
class
,
id
)
)
;
}
@
SuppressWarnings
(
"unchecked"
)
@
Override
public
List
&
lt
;
BlogVo
&
gt
;
queryAll
(
)
{
List
&
lt
;
Blog
&
gt
;
list
=
em
.
createNamedQuery
(
"queryAll"
)
.
getResultList
(
)
;
List
&
lt
;
BlogVo
&
gt
;
volist
=
new
ArrayList
&
lt
;
BlogVo
&
gt
;
(
)
;
for
(
Blog
po
:
list
)
{
volist
.
add
(
this
.
parsePo2Vo
(
po
)
)
;
}
return
volist
;
}
@
SuppressWarnings
(
"unchecked"
)
@
Override
public
List
&
lt
;
BlogVo
&
gt
;
queryByAuthor
(
String
author
)
{
Query
query
=
em
.
createQuery
(
"select t from Blog t where t.author =:author"
)
.
setParameter
(
"author"
,
author
)
;
List
&
lt
;
Blog
&
gt
;
list
=
query
.
getResultList
(
)
;
List
&
lt
;
BlogVo
&
gt
;
volist
=
new
ArrayList
&
lt
;
BlogVo
&
gt
;
(
)
;
for
(
Blog
po
:
list
)
{
volist
.
add
(
this
.
parsePo2Vo
(
po
)
)
;
}
return
volist
;
}
private
Blog
parseVo2Po
(
BlogVo
vo
)
{
Blog
blog
=
new
Blog
(
)
;
blog
.
setAuthor
(
vo
.
getAuthor
(
)
)
;
blog
.
setId
(
vo
.
getId
(
)
)
;
blog
.
setTitle
(
vo
.
getTitle
(
)
)
;
blog
.
setUrl
(
vo
.
getUrl
(
)
)
;
return
blog
;
}
private
BlogVo
parsePo2Vo
(
Blog
po
)
{
BlogVo
vo
=
new
BlogVo
(
)
;
vo
.
setAuthor
(
po
.
getAuthor
(
)
)
;
vo
.
setId
(
po
.
getId
(
)
)
;
vo
.
setTitle
(
po
.
getTitle
(
)
)
;
vo
.
setUrl
(
po
.
getUrl
(
)
)
;
return
vo
;
}
}
|
ps:
- @PersistenceContext 用来注入 EntityManager
- unitName 的值”micmiuJPA” 和配置文件persistence.xml 中定义的名称一致
[六]、配置datasource数据源
数据源配置详见:
EJB部署在JBoss下的datasource配置
[七]、部署EJB工程
导出EJB工程打包,copy 到 JBOSS_HOME/server/default/deploy 默认发布配置下,启动JBOSS即可,能看的类似如下的日志信息:
09:39:43,291 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EJB-HelloWorld.jar,name=BlogBean,service=EJB3
09:39:43,298 INFO [EJBContainer] STARTED EJB: com.micmiu.ejb.BlogBean ejbName: BlogBean
09:39:43,306 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:BlogBean/remote – EJB3.x Default Remote Business Interface
BlogBean/remote-com.micmiu.ejb.BlogBeanRemote – EJB3.x Remote Business Interface
[八]、创建客户端测试类
把EJB工程中的Remote接口以及引用到的Vo类导出JAR包,copy到客户端工程中,然后创建客户端调用类:BlogBeanClientTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
package
com
.
micmiu
.
ejb
.
demo
;
import
java
.
util
.
List
;
import
java
.
util
.
Properties
;
import
javax
.
naming
.
InitialContext
;
import
javax
.
naming
.
NamingException
;
import
com
.
micmiu
.
ejb
.
BlogBeanRemote
;
import
com
.
micmiu
.
ejb
.
vo
.
BlogVo
;
/**
* 客户端调用测试类
*
* @author <a href="http://www.micmiu.com">Michael</a>
* @time Create on 2013-9-21 下午2:51:59
* @version 1.0
*/
public
class
BlogBeanClientTest
{
/**
* @param args
*/
public
static
void
main
(
String
[
]
args
)
{
try
{
Properties
props
=
new
Properties
(
)
;
props
.
setProperty
(
"java.naming.factory.initial"
,
"org.jnp.interfaces.NamingContextFactory"
)
;
props
.
setProperty
(
"java.naming.provider.url"
,
"localhost:1099"
)
;
props
.
setProperty
(
"java.naming.factory.url.pkgs"
,
"org.jboss.naming"
)
;
System
.
out
.
println
(
">>>> InitialContext "
)
;
InitialContext
ctx
=
new
InitialContext
(
props
)
;
System
.
out
.
println
(
">>>> lookup "
)
;
String
serviceName
=
"BlogBean/remote"
;
BlogBeanRemote
remote
=
(
BlogBeanRemote
)
ctx
.
lookup
(
serviceName
)
;
System
.
out
.
println
(
">>>> 操作之前 query michael's Blog"
)
;
List
&
lt
;
BlogVo
&
gt
;
list
=
remote
.
queryByAuthor
(
"michael"
)
;
System
.
out
.
println
(
"query result size = "
+
list
.
size
(
)
)
;
for
(
BlogVo
blog
:
list
)
{
System
.
out
.
println
(
blog
)
;
}
System
.
out
.
println
(
">>>> create new blog"
)
;
BlogVo
blog
=
new
BlogVo
(
)
;
blog
.
setAuthor
(
"michael"
)
;
blog
.
setTitle
(
"图文演示Eclipse+JBoss创建第一个EJB项目"
)
;
blog
.
setUrl
(
"http://www.micmiu.com/j2ee/ejb/eclipse-jboss-ejb-demo/"
)
;
BlogVo
createVo
=
remote
.
create
(
blog
)
;
System
.
out
.
println
(
createVo
)
;
System
.
out
.
println
(
">>>> read exit blog"
)
;
BlogVo
readVo
=
remote
.
read
(
1
)
;
System
.
out
.
println
(
readVo
)
;
System
.
out
.
println
(
">>>> update blog"
)
;
System
.
out
.
println
(
"update title "
+
readVo
.
getTitle
(
)
+
" to 大大&&小小 "
)
;
readVo
.
setTitle
(
"大大&&小小"
)
;
remote
.
update
(
readVo
)
;
System
.
out
.
println
(
">>>> 操作之后 query michael's Blog"
)
;
list
=
remote
.
queryByAuthor
(
"michael"
)
;
System
.
out
.
println
(
">>>> 结果 = "
+
list
.
size
(
)
)
;
for
(
BlogVo
vo
:
list
)
{
System
.
out
.
println
(
vo
)
;
}
}
catch
(
NamingException
e
)
{
e
.
printStackTrace
(
)
;
}
}
}
|
[九]、运行测试类
运行后日志信息如下:
>>>> InitialContext
>>>> lookup
>>>> 操作之前 query michael’s Blog
query result size = 1
BlogVo [id=1, title=Michael的博客, url=http://www.micmiu.com, author=michael]
>>>> create new blog
BlogVo [id=114, title=图文演示Eclipse+JBoss创建第一个EJB项目, url=http://www.micmiu.com/j2ee/ejb/eclipse-jboss-ejb-demo/, author=michael]
>>>> read exit blog
BlogVo [id=1, title=Michael的博客, url=http://www.micmiu.com, author=michael]
>>>> update blog
update title Michael的博客 to 大大&&小小
>>>> 操作之后 query michael’s Blog
>>>> 结果 = 2
BlogVo [id=1, title=大大&&小小, url=http://www.micmiu.com, author=michael]
BlogVo [id=114, title=图文演示Eclipse+JBoss创建第一个EJB项目, url=http://www.micmiu.com/j2ee/ejb/eclipse-jboss-ejb-demo/, author=michael]