ejb3 第10讲 --开发单表映射的实体bean

 

 

 

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

 

 

你可能感兴趣的:(Hibernate,bean,jboss,ant,单元测试)