一. 介绍:
持久化是位于JDBC 之上的一个更高层抽象。持久层将对象映射到数据库,以便在查询、装载、更新,或删除对象的时候,无须使用像JDBC 那样繁琐的API。在EJB 的早期版本中,持久化是EJB 平台的一部分。从EJB 3.0开始,持久化已经自成规范,被称为Java Persistence API。Java Persistence API 定义了一种方法,可以将常规的普通Java 对象(有时被称作POJO)映射到数据库。这些普通Java 对象被称作entity bean
二.实例:
1.建persistence.xml:
一个实体Bean 应用由实体类和persistence.xml 文件组成。persistence.xml 文件在Jar 文件的META-INF 目录。persistence.xml 文件指定实体Bean 使用的数据源及EntityManager 对象的默认行为。persistence.xml 文件的配置说
明如下:
<persistence>
<persistence-unit name="test">
<jta-data-source>java:/ MySqlDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
</properties>
</persistence-unit>
</persistence>
persistence-unit 节点可以有一个或多个,每个persistence-unit 节点定义了持久化内容名称、使用的数据源及持久化产品专有属性。name 属性定义持久化名称。jta-data-source 节点指定实体Bean 使用的数据源JNDI 名称,如果应用发布在jboss 下数据源名称必须带有java:/前缀,数据源名称大小写敏感。properties 节点用作指定持久化产品的各项属性,各个应用服务器使用的持久化产品都不一样如Jboss 使用Hibernate,weblogic10 使用Kodo,glassfish/sun application server/Oralce 使用Toplink。因为jboss 采用Hibernate,Hibernate 有一项属性hibernate.hbm2ddl.auto,该属性指定实体Bean 发布时是否同步数据库结构,如
果hibernate.hbm2ddl.auto 的值设为create-drop,在实体Bean 发布及卸载时将自动创建及删除相应数据库表(注意:Jboss 服务器启动或关闭时也会引发实体Bean 的发布及卸载)。
2.编写实体类
@SuppressWarnings("serial")
@Entity
@Table(name = "Person")
public class Person implements Serializable {
private Integer personid;
private String name;
private boolean sex;
private Short age;
private Date birthday;
@Id
@GeneratedValue(strategy = GenerationType.AUTO) //主键自动生成方式
public Integer getPersonid() {
return personid;
}
public void setPersonid(Integer personid) {
this.personid = personid;
}
@Column(nullable = false, length = 32)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(nullable = false)
public boolean getSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
@Column(nullable = false)
public Short getAge() {
return age;
}
public void setAge(Short age) {
this.age = age;
}
@Temporal(value = TemporalType.DATE)
//@Temporal 注释用来指定java.util.Date 或java.util.Calendar 属性与数据库类型date,time 或timestamp 中的那一种
//类型进行映射,DATE, //代表date 类型;TIME, //代表时间类型;TIMESTAMP //代表时间戳类型
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
3.Session Bean 作为实体Bean的使用者
@Stateless
@Remote(PersonDAO.class)
public class PersonDAOBean implements PersonDAO {
@PersistenceContext
protected EntityManager em;
//EntityManager 是由EJB 容器自动地管理和配置的,不需要用户自己创建,他用作操作实体Bean。
//容器在实例化SessionBean后,就通过@PersistenceContext 注释动态注入EntityManager 对象。
public String getPersonNameByID(int personid) {
Person person = em.find(Person.class, Integer.valueOf(personid));
return person.getName();
}
public boolean insertPerson(String name, boolean sex, short age,Date birthday) {
try {
Person person = new Person();
person.setName(name);
person.setSex(sex);
person.setAge(Short.valueOf(age));
person.setBirthday(birthday);
em.persist(person);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
public Person getPersonByID(int personid) {
return em.find(Person.class, personid);
}
public boolean updatePerson(Person person) {
try {
em.merge(person);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
public List getPersonList() {
Query query = em.createQuery("from Person order by personid asc");
List list = query.getResultList();
return list;
}
}
4.测试:
import com.dao.PersonDAO;
public class PersonDAOTest extends TestCase {
private PersonDAO personDAO;
protected void setUp() throws Exception {
personDAO=(PersonDAO) EJBFactory.getEJB("PersonDAOBean/remote");
}
public void testInsertPerson() throws ParseException, UnsupportedEncodingException{
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
assertTrue(personDAO.insertPerson("测试", true, (short)26,formatter.parse("
1980-9-30
")));//添加一个
}
public void testGetPersonList(){
assertEquals(4,personDAO.getPersonList().size());
}
}
5.其他注意点
@Transient 注释进行标注,则相应属性将不会被持久化成数据库字段
find()方法会返回null,而getReference()方法会抛出javax.persistence.EntityNotFoundException
getDelegate( )方法,你可以获取EntityManager 持久化实现者的引用,如Jboss EJB3 的持久化产品采用Hibernate
6.问题解决
a.问题:插入的中文为乱码
解决:1.数据库级设置: create database `test` DEFAULT CHARSET=gbk
2.表级设置: gbk
3. URL: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=gbk
b.问题:java.lang.NoClassDefFoundError: antlr/RecognitionException
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.getDeclaredMethod(Unknown Source)
at java.io.ObjectStreamClass.getPrivateMethod(Unknown Source)
at java.io.ObjectStreamClass.access$1700(Unknown Source)