目的:使用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