目的:使用ejb3 的实体bean,来完成数据库的增删改查
步骤:
1.建立一个空的java 项目,把JBoss client目录下的jar文件加入到环境变量里面
2.建立MATE-INF 目录(在src下),在其中建立 persistence.xml 持久化配置文件
<?xml version="1.0" encoding="UTF-8"?> <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"> <!--JTA 全局事务(默认) 定义持久化单元 persistence-unit,可以有多个持久化单元,持久化单元通俗的讲就是一 堆实体类的集合 --> <persistence-unit name="xinli" transaction-type="JTA"> <jta-data-source>jdbc/MySqlDS</jta-data-source> <!-- Jboss JPA规范的实现产品时 Hibernate,因此可以再这里配置hibernate的一些属性信息 --> <properties> <!-- validate 加载hibernate时,验证创建数据库表结构 create 每次加载hibernate,重新创建数据库表结构 create-drop 加载hibernate时创建,退出是删除表结构 update 加载hibernate自动更新数据库结构 none 不做操作 --> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> </properties> </persistence-unit> </persistence>
3.建立和数据库映射的javabean,完成元数据和数据库字段的映射关系,有两两种方式 XML方式好 注解方式,注解方式开发效率高
package cn.com.xinli.bean;
import java.io.Serializable;
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table;
@Entity @Table(name="person") /*必须时间序列化接口*/ public class Person implements Serializable { /*必须有@ID 标识 * GenerationType.AUTO 在mysql 中是主键的AUTO_INCREMENT * 在oracle中是使用触发器和序列完成主键的自增,也就是它会根据 * 不同的数据库选择不同的策略 * * */ @Id @Column(name="id",length=11,nullable=false) @GeneratedValue(strategy=GenerationType.AUTO) private Integer id; @Column(name="name",length=20,nullable=false) private String name; /*必须有无参数的构造函数*/ public Person() { } public Person(String name) { this.name=name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } /** * 重写hashCode equals 方法,只比较Id */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; final Person other = (Person) obj; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; return true; } }
4.建立增删改查的业务接口
package cn.com.xinli.service; import java.util.List; import cn.com.xinli.bean.Person; public interface PersonService { public void add(Person person); public void delete(int id); public void update(Person person); public Person getPerson(int id); public List<Person> getPersons(); }
5.定义接口的实现类 无状态的会话bean
package cn.com.xinli.service.impl; import java.util.List; import javax.ejb.Remote; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import cn.com.xinli.bean.Person; import cn.com.xinli.service.PersonService; /*无状态的会话bean,远程接口*/ @Stateless @Remote(PersonService.class) public class PersonServiceBean implements PersonService { /*如果只有一个持久化单元可以不写unitName,超过一个必须写 * 需要使用的实体管理器(EntityManager)完成增删改查 * * */ @PersistenceContext(unitName="xinli") EntityManager em; public void add(Person person) { em.persist(person); } public void delete(int id) { /*getReference 方法如果你不调用get方法的时候他是不会 *完成数据的装载的,返回代理对象,性能高,我们仅仅要删除 *删除数据没必要加载数据 */ em.remove(em.getReference(Person.class, id)); } public Person getPerson(int id) { return em.find(Person.class, id); } public List<Person> getPersons() { /*面向对象的语句,不是Sql语句*/ return em.createQuery("select p from Person p").getResultList(); } public void update(Person person) { /*merge方法调用的前提是bean处于游离状态 * 如果对象处于托管状态 直接吊set方法 * */ em.merge(person); } }
6. 建立ant 的builder.xml 文件,方便打包,和部署
<?xml version="1.0" encoding="UTF-8"?> <project name="EntityBean" basedir="."> <property name="src.dir" value="${basedir}"/> <property environment="env"/> <property name="jboss.home" value="${env.JBOSS_HOME}"/> <property name="jboss.server.config" value="default"/> <property name="build.dir" value="${basedir}\build"/> <path id="master-classpath" description="设置编译路径"> <fileset file="${jboss.home}\client\*.jar"/> </path> <target name="prepare" description="创建class文件目录"> <delete dir="${build.dir}"/> <mkdir dir="${build.dir}"/> </target> <target name="compile" depends="prepare" description="编译"> <!--只编译以cn开头的--> <javac srcdir="${src.dir}" destdir="${build.dir}" includes="cn/**"> <classpath refid="master-classpath"/> </javac> </target> <target name="ejbjar" description="创建ejb发布包" depends="compile"> <jar jarfile="${basedir}\${ant.project.name}.jar"> <fileset dir="${build.dir}"/> <include name="**/*.class"/> <metainf dir="${src.dir}\META-INF"></metainf> </jar> </target> <target name="deploy" description="发布"> <copy file="${basedir}\${ant.project.name}.jar" todir="${jboss.home}\server\${jboss.server.config}\deploy"/> </target> <target name="undeploy" description="卸载ejb"> <delete file="${basedir}\${ant.project.name}.jar" todir="${jboss.home}\server\${jboss.server.config}\deploy"/> </target> </project>
7. 完成单元测试用例,在业务接口上右键-->新建--> 单元测试用例(是junit4)
package junit.test; import static org.junit.Assert.*; import java.util.List; import javax.naming.InitialContext; import org.junit.BeforeClass; import org.junit.Test; import cn.com.xinli.bean.Person; import cn.com.xinli.service.PersonService; public class PersonServiceTest { private static PersonService personService; @BeforeClass public static void setUpBeforeClass() throws Exception { try { InitialContext ctx=new InitialContext(); /*remote必须是小写,大写会报错*/ personService=(PersonService) ctx.lookup("PersonServiceBean/remote"); } catch(Exception e) { e.printStackTrace(); } } @Test public void testAdd() { personService.add(new Person("我的老婆")); personService.add(new Person("我的老婆")); } @Test public void testDelete() { /* 设置表的自增字段重新从1开始 alter table person AUTO_INCREMENT=1;*/ personService.delete(1); } @Test public void testUpdate() { Person person=new Person(); person.setId(1); person.setName("小亮亮"); personService.update(person); } @Test public void testGetPerson() { Person person=personService.getPerson(2); System.out.println(person.getId()); System.out.println(person.getName()); } @Test public void testGetPersons() { List<Person> persons=personService.getPersons(); for(Person person:persons) { System.out.println(person.getId()); System.out.println(person.getName()); } } }
8. 使用ant 打包部署后,运行单元测试用例,打开mysql数据库,观察结果,一切ok,如果数据库有乱码现象,请修改sql连接字符串 加上useUnicode\=true&characterEncoding\=UTF-8