读书人

EJB6: EntityBean事例

发布时间: 2012-11-05 09:35:12 作者: rapoo

EJB6: EntityBean例子

????? 本例子描述向EJB容器(JBoss)部署http://kylinsoong.iteye.com/blog/824676中描述的例子的全过程,链接博客中描述的例子包含7个实体:User、Event、Friend、Property、Pet、UserCard、Wife,其中:User和Event,User和Friend,Event和Property,Wife和Pet,Pet和Property关系为一对多关系;而User和UserCard,Friend和UserCard,Wife和UserCard,User和Wife之间的关系是一对一关系;

下面开始部署http://kylinsoong.iteye.com/blog/824676中描述的例子:

?

1 JBoss数据源的配置

????? 数据源的备份文件可以在JBOSS_Home\docs\examples\jca下找到,我用的是Oracle10g所以我用到的JBoss数据源的配置JBOSS_Home\docs\examples\jca下的oracle-ds.xml,将oracle-ds.xml做一下修改,修改完拷贝到JBOSS_Home\server\production\deploy下,修改完的oracle-ds.xml的内容如下:

<?xml version="1.0" encoding="UTF-8"?><datasources>  <local-tx-datasource>    <jndi-name>OracleDS</jndi-name>    <connection-url>jdbc:oracle:thin:@192.168.68.120:1521:orcl</connection-url>    <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>    <user-name>***</user-name>    <password>***</password>    <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>      <metadata>         <type-mapping>Oracle10g</type-mapping>      </metadata>  </local-tx-datasource></datasources>

?其中说明了JBoss数据源的jndi-name:OracleDS,jndi-name必须唯一;

?????????????????????????????????????????连接URL:jdbc:oracle:thin:@192.168.68.120:1521:orcl

?????????????????????????????????? 连接驱动名称:oracle.jdbc.driver.OracleDriver

以及数据库名称及密码,数据库类型;

拷贝完成后启动JBoss,http://localhost:8080/jmx-console/HtmlAdaptor?action=displayMBeans下jboss.jca可以看到刚才添加数据源的配置信息:


EJB6: EntityBean事例
?

2 Bean开发

首先修改之前POJO实体,让其手实现java.io.Serializable接口,

其次用一个无状态Session Bean来控制Entity Bean

贴出Remote接口UserService和无状态SessionBean:UserServiceBean

public interface UserService {public void insertUser(User user);public void updateName(String newname, Long id);public void mergeUser(User user);public void deleteUser(Long id);public User getUserByID(Long id);public List<User> getUserList();}

?

@Stateless@Remote(UserService.class)public class UserServiceBean implements UserService {@PersistenceContext(unitName="com.tibco.hibernate.po") protected EntityManager em;public void insertUser(User user) {em.persist(user);}public void updateName(String name, Long id) {User user = em.find(User.class, id);if(user != null){user.setName(name);}}public void mergeUser(User user) {em.merge(user);}public void deleteUser(Long id) {User user = em.find(User.class, id);if(user != null){em.remove(user);}}public User getUserByID(Long id) {return em.find(User.class, id);}public List<User> getUserList() {Query query = em.createQuery("select u from User as u");return query.getResultList();}}

????? 如上:Remote接口UserService提供了一套对User的增删改查方法,无状态SessionBean类UserServiceBean分别提供了这些方法的一个实现。

@PersistenceContext(unitName="com.tibco.hibernate.po") 指定了Persistence unit的名字,容器通过这个名字可以找到相应的实体类和数据源等

?

3. persistence.xml编写

????? 我们知道Persistence unit 是在persistence.xml中定义的,实体类型之所以能被EntityManager控制是因为提供了Persistence unit,根据持久化规范的要求,该描述文件是必须提供的,如果不提供这一文件,则Persistence unit也
?将不存在,因此应用也不能够获得和使用EntityManager,下面是persistence.xml内容:

<?xml version="1.0"?><persistence 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_1_0.xsd" version="1.0">  <persistence-unit name="com.tibco.hibernate.po">    <jta-data-source>java:/OracleDS</jta-data-source>    <properties>     <property name="hibernate.hbm2ddl.auto" value="create-drop"/>     <!-- 调整JDBC抓取数量的大小: Statement.setFetchSize() -->     <property name="hibernate.jdbc.fetch_size" value="18"/>     <!-- 调整JDBC批量更新数量 -->     <property name="hibernate.jdbc.batch_size" value="10"/>     <!-- 显示最终执行的SQL -->     <property name="hibernate.show_sql" value="true"/>     <!-- 格式化显示的SQL -->     <property name="hibernate.format_sql" value="true"/>    </properties>  </persistence-unit></persistence>

?配置文件说明我们用的JPA的实现是Hibernate,“hibernate.hbm2ddl.auto”值得容器启动时创建表,容器关闭时删除表,"hibernate.show_sql"在容器Console口打印SQL语句,"hibernate.format_sql"说明在容器Console显示的SQL语句是格式化的;

?

4 将过程打包部署到JBOSS_Home\server\production\deploy下

我们用Ant实现,关于Ant参考http://kylinsoong.iteye.com/admin/blogs/787097这里直接给出build.xml

<?xml version="1.0"?><project name="com.tibco.hibernate" default="deploy" basedir=".."><property environment="env" /><property name="app.dir" value="${basedir}\com.tibco.hibernate" /><property name="src.dir" value="${app.dir}\src" /><property name="jboss.home" value="${env.JBOSS_HOME}" /><property name="jboss.server.config" value="production" /><property name="build.dir" value="${app.dir}\build" /><property name="build.classes.dir" value="${build.dir}\classes" /><!-- Build classpath --><path id="build.classpath"><fileset dir="${jboss.home}\client"><include name="*.jar" /></fileset><fileset dir="${jboss.home}\client\userService"><include name="*.jar" /></fileset><pathelement location="${build.classes.dir}" /></path><target name="prepare" depends="clean"><mkdir dir="${build.dir}" /><mkdir dir="${build.classes.dir}" /></target><target name="compile" depends="prepare" description="compile"><javac srcdir="${src.dir}" destdir="${build.classes.dir}" debug="on" deprecation="on" optimize="off" includes="com/**"><classpath refid="build.classpath" /></javac></target><target name="ejbjar" depends="compile" description="ejbjar"><jar jarfile="${app.dir}\UserBean.jar"><fileset dir="${build.classes.dir}"><include name="com/tibco/hibernate/po/*.class" /><include name="com/tibco/hibernate/po/bean/*.class" /></fileset><metainf dir="${src.dir}\META-INF"><include name="persistence.xml" /></metainf></jar></target><target name="deploy" depends="ejbjar"><copy file="${app.dir}\UserBean.jar" todir="${jboss.home}\server\${jboss.server.config}\deploy" /></target><!-- =================================================================== --><!-- Cleans up generated stuff                                           --><!-- =================================================================== --><target name="clean"><delete dir="${build.dir}" /><delete file="${jboss.home}\server\${jboss.server.config}\deploy\UserBean.jar" /></target></project>

?运行Ant,文件部署成功

?

5 测试

运行这段代码可以插入一条数据并查询:

public static void main(String[] args) throws NamingException {Properties properties = new Properties();properties.setProperty(Context.INITIAL_CONTEXT_FACTORY , "org.jnp.interfaces.NamingContextFactory");        properties.setProperty(Context.PROVIDER_URL, "jnp://localhost");        Context ctx = new InitialContext(properties);        UserService userService = (UserService) ctx.lookup("UserServiceBean/remote");        User user = JPAClient.getUser();userService.insertUser(user);                for(User u : userService.getUserList()) {        System.out.println("id:" + u.getId() + " name:" + u.getName());        }}

?

当然我们也可以运用反射修改刚才插入的user:

public static void main(String[] args) throws NamingException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {Properties properties = new Properties();properties.setProperty(Context.INITIAL_CONTEXT_FACTORY , "org.jnp.interfaces.NamingContextFactory");        properties.setProperty(Context.PROVIDER_URL, "jnp://localhost");        Context ctx = new InitialContext(properties);        Object obj = ctx.lookup("UserServiceBean/remote");        for(Method m : obj.getClass().getMethods()) {        if(m.getName().compareTo("updateName") == 0){        m.invoke(obj, new Object[]{"Kobe Bryant", new Long(1)});        }        }        for(Method m : obj.getClass().getMethods()) {        if(m.getName().compareTo("getUserByID") == 0) {        User user = (User) m.invoke(obj, new Object[]{new Long(1)});        System.out.println(user.getName());        }        }}

?

?

读书人网 >软件架构设计

热点推荐