之前一直在用EJB3,但现在想在J2SE里面使用JPA,因为不大喜欢Hibernate的XML文件配置。
而使用DB4O的时候,出现了一些莫名其妙的问题,一直没解决,就暂时搁下了。
使用myeclipse 6开发jpa如下:
1.创建web project
2.添加jpa capabilities,选择toplink,把自动创建数据库的和更新persistence.xml的勾上
3.切换成database explorer视图,选择表,jpa逆向工程。
4.测试
生成的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">
<persistence-unit name="JPAWebPU"
transaction-type="RESOURCE_LOCAL">
<provider>
oracle.toplink.essentials.PersistenceProvider
</provider>
<class>com.persia.entity.Consumer</class>
<properties>
<property name="toplink.jdbc.driver"
value="com.mysql.jdbc.Driver" />
<property name="toplink.jdbc.url"
value="jdbc:mysql://localhost:3306/ejb3" />
<property name="toplink.jdbc.user" value="root" />
<property name="toplink.jdbc.password" value="root" />
<property name="toplink.ddl-generation"
value="create-tables" />
</properties>
</persistence-unit>
</persistence>
生成的几个类如下:
实体类:
package com.persia.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Consumer entity.
*
* @author MyEclipse Persistence Tools
*/
@Entity
@Table(name = "consumer", catalog = "ejb3", uniqueConstraints = {})
public class Consumer implements java.io.Serializable {
// Fields
private Integer id;
private String name;
private String password;
// Constructors
/** default constructor */
public Consumer() {
}
/** full constructor */
public Consumer(Integer id, String name, String password) {
this.id = id;
this.name = name;
this.password = password;
}
// Property accessors
@Id
@Column(name = "id", unique = true, nullable = false, insertable = true, updatable = true)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name = "name", unique = false, nullable = false, insertable = true, updatable = true, length = 45)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Column(name = "password", unique = false, nullable = false, insertable = true, updatable = true, length = 45)
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
}
DAO接口
package com.persia.entity;
import java.util.List;
/**
* Interface for ConsumerDAO.
*
* @author MyEclipse Persistence Tools
*/
public interface IConsumerDAO {
/**
* Perform an initial save of a previously unsaved Consumer entity. All
* subsequent persist actions of this entity should use the #update()
* method. This operation must be performed within the a database
* transaction context for the entity's data to be permanently saved to the
* persistence store, i.e., database. This method uses the
* {@link javax.persistence.EntityManager#persist(Object) EntityManager#persist}
* operation.
*
* <pre>
* EntityManagerHelper.beginTransaction();
* IConsumerDAO.save(entity);
* EntityManagerHelper.commit();
* </pre>
*
* @param entity
* Consumer entity to persist
* @throws RuntimeException
* when the operation fails
*/
public void save(Consumer entity);
/**
* Delete a persistent Consumer entity. This operation must be performed
* within the a database transaction context for the entity's data to be
* permanently deleted from the persistence store, i.e., database. This
* method uses the
* {@link javax.persistence.EntityManager#remove(Object) EntityManager#delete}
* operation.
*
* <pre>
* EntityManagerHelper.beginTransaction();
* IConsumerDAO.delete(entity);
* EntityManagerHelper.commit();
* entity = null;
* </pre>
*
* @param entity
* Consumer entity to delete
* @throws RuntimeException
* when the operation fails
*/
public void delete(Consumer entity);
/**
* Persist a previously saved Consumer entity and return it or a copy of it
* to the sender. A copy of the Consumer entity parameter is returned when
* the JPA persistence mechanism has not previously been tracking the
* updated entity. This operation must be performed within the a database
* transaction context for the entity's data to be permanently saved to the
* persistence store, i.e., database. This method uses the
* {@link javax.persistence.EntityManager#merge(Object) EntityManager#merge}
* operation.
*
* <pre>
* EntityManagerHelper.beginTransaction();
* entity = IConsumerDAO.update(entity);
* EntityManagerHelper.commit();
* </pre>
*
* @param entity
* Consumer entity to update
* @returns Consumer the persisted Consumer entity instance, may not be the
* same
* @throws RuntimeException
* if the operation fails
*/
public Consumer update(Consumer entity);
public Consumer findById(Integer id);
/**
* Find all Consumer entities with a specific property value.
*
* @param propertyName
* the name of the Consumer property to query
* @param value
* the property value to match
* @return List<Consumer> found by query
*/
public List<Consumer> findByProperty(String propertyName, Object value);
public List<Consumer> findByName(Object name);
public List<Consumer> findByPassword(Object password);
/**
* Find all Consumer entities.
*
* @return List<Consumer> all Consumer entities
*/
public List<Consumer> findAll();
}
DAO类
package com.persia.entity;
import java.util.List;
import java.util.logging.Level;
import javax.persistence.EntityManager;
import javax.persistence.Query;
/**
* A data access object (DAO) providing persistence and search support for
* Consumer entities. Transaction control of the save(), update() and delete()
* operations must be handled externally by senders of these methods or must be
* manually added to each of these methods for data to be persisted to the JPA
* datastore.
*
* @see com.persia.entity.Consumer
* @author MyEclipse Persistence Tools
*/
public class ConsumerDAO implements IConsumerDAO {
// property constants
public static final String NAME = "name";
public static final String PASSWORD = "password";
private EntityManager getEntityManager() {
return EntityManagerHelper.getEntityManager();
}
/**
* Perform an initial save of a previously unsaved Consumer entity. All
* subsequent persist actions of this entity should use the #update()
* method. This operation must be performed within the a database
* transaction context for the entity's data to be permanently saved to the
* persistence store, i.e., database. This method uses the
* {@link javax.persistence.EntityManager#persist(Object) EntityManager#persist}
* operation.
*
* <pre>
* EntityManagerHelper.beginTransaction();
* ConsumerDAO.save(entity);
* EntityManagerHelper.commit();
* </pre>
*
* @param entity
* Consumer entity to persist
* @throws RuntimeException
* when the operation fails
*/
public void save(Consumer entity) {
EntityManagerHelper.log("saving Consumer instance", Level.INFO, null);
try {
getEntityManager().persist(entity);
EntityManagerHelper.log("save successful", Level.INFO, null);
} catch (RuntimeException re) {
EntityManagerHelper.log("save failed", Level.SEVERE, re);
throw re;
}
}
/**
* Delete a persistent Consumer entity. This operation must be performed
* within the a database transaction context for the entity's data to be
* permanently deleted from the persistence store, i.e., database. This
* method uses the
* {@link javax.persistence.EntityManager#remove(Object) EntityManager#delete}
* operation.
*
* <pre>
* EntityManagerHelper.beginTransaction();
* ConsumerDAO.delete(entity);
* EntityManagerHelper.commit();
* entity = null;
* </pre>
*
* @param entity
* Consumer entity to delete
* @throws RuntimeException
* when the operation fails
*/
public void delete(Consumer entity) {
EntityManagerHelper.log("deleting Consumer instance", Level.INFO, null);
try {
entity = getEntityManager().getReference(Consumer.class,
entity.getId());
getEntityManager().remove(entity);
EntityManagerHelper.log("delete successful", Level.INFO, null);
} catch (RuntimeException re) {
EntityManagerHelper.log("delete failed", Level.SEVERE, re);
throw re;
}
}
/**
* Persist a previously saved Consumer entity and return it or a copy of it
* to the sender. A copy of the Consumer entity parameter is returned when
* the JPA persistence mechanism has not previously been tracking the
* updated entity. This operation must be performed within the a database
* transaction context for the entity's data to be permanently saved to the
* persistence store, i.e., database. This method uses the
* {@link javax.persistence.EntityManager#merge(Object) EntityManager#merge}
* operation.
*
* <pre>
* EntityManagerHelper.beginTransaction();
* entity = ConsumerDAO.update(entity);
* EntityManagerHelper.commit();
* </pre>
*
* @param entity
* Consumer entity to update
* @returns Consumer the persisted Consumer entity instance, may not be the
* same
* @throws RuntimeException
* if the operation fails
*/
public Consumer update(Consumer entity) {
EntityManagerHelper.log("updating Consumer instance", Level.INFO, null);
try {
Consumer result = getEntityManager().merge(entity);
EntityManagerHelper.log("update successful", Level.INFO, null);
return result;
} catch (RuntimeException re) {
EntityManagerHelper.log("update failed", Level.SEVERE, re);
throw re;
}
}
public Consumer findById(Integer id) {
EntityManagerHelper.log("finding Consumer instance with id: " + id,
Level.INFO, null);
try {
Consumer instance = getEntityManager().find(Consumer.class, id);
return instance;
} catch (RuntimeException re) {
EntityManagerHelper.log("find failed", Level.SEVERE, re);
throw re;
}
}
/**
* Find all Consumer entities with a specific property value.
*
* @param propertyName
* the name of the Consumer property to query
* @param value
* the property value to match
* @return List<Consumer> found by query
*/
@SuppressWarnings("unchecked")
public List<Consumer> findByProperty(String propertyName, final Object value) {
EntityManagerHelper.log("finding Consumer instance with property: "
+ propertyName + ", value: " + value, Level.INFO, null);
try {
final String queryString = "select model from Consumer model where model."
+ propertyName + "= :propertyValue";
Query query = getEntityManager().createQuery(queryString);
query.setParameter("propertyValue", value);
return query.getResultList();
} catch (RuntimeException re) {
EntityManagerHelper.log("find by property name failed",
Level.SEVERE, re);
throw re;
}
}
public List<Consumer> findByName(Object name) {
return findByProperty(NAME, name);
}
public List<Consumer> findByPassword(Object password) {
return findByProperty(PASSWORD, password);
}
/**
* Find all Consumer entities.
*
* @return List<Consumer> all Consumer entities
*/
@SuppressWarnings("unchecked")
public List<Consumer> findAll() {
EntityManagerHelper.log("finding all Consumer instances", Level.INFO,
null);
try {
final String queryString = "select model from Consumer model";
Query query = getEntityManager().createQuery(queryString);
return query.getResultList();
} catch (RuntimeException re) {
EntityManagerHelper.log("find all failed", Level.SEVERE, re);
throw re;
}
}
}
还有一个非常有用的helper
package com.persia.entity;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
/**
* @author MyEclipse Persistence Tools
*/
public class EntityManagerHelper {
private static final EntityManagerFactory emf;
private static final ThreadLocal<EntityManager> threadLocal;
private static final Logger logger;
static {
emf = Persistence.createEntityManagerFactory("JPAWebPU");
threadLocal = new ThreadLocal<EntityManager>();
logger = Logger.getLogger("JPAWebPU");
logger.setLevel(Level.ALL);
}
public static EntityManager getEntityManager() {
EntityManager manager = threadLocal.get();
if (manager == null || !manager.isOpen()) {
manager = emf.createEntityManager();
threadLocal.set(manager);
}
return manager;
}
public static void closeEntityManager() {
EntityManager em = threadLocal.get();
threadLocal.set(null);
if (em != null) em.close();
}
public static void beginTransaction() {
getEntityManager().getTransaction().begin();
}
public static void commit() {
getEntityManager().getTransaction().commit();
}
public static void rollback() {
getEntityManager().getTransaction().rollback();
}
public static Query createQuery(String query) {
return getEntityManager().createQuery(query);
}
public static void log(String info, Level level, Throwable ex) {
logger.log(level, info, ex);
}
}
然后使用helper和dao进行测试
package com.jpa.test;
import java.util.List;
import com.persia.entity.Consumer;
import com.persia.entity.ConsumerDAO;
import com.persia.entity.EntityManagerHelper;
public class JPATest {
/**
* @param args
*/
public static void main(String[] args) {
// 1.创建 DAO
ConsumerDAO dao = new ConsumerDAO();
// 2.创建实体类
Consumer c = new Consumer();
c.setName("jpa01");
c.setPassword("jianchi");
// 开始事务
EntityManagerHelper.beginTransaction();
// 3. 保存
dao.save(c);
// 提交事务真正保存实体到数据库
EntityManagerHelper.commit();
// 4. 列出数据库中所有对象
List<Consumer> result = dao.findAll();
for(Consumer o : result) {
System.out.println(o.getId());
System.out.println(o.getName());
}
}
}
测试实例如下:
package test;
import java.util.List;
import dao.*;
public class JPATest {
public static void main(String[] args) {
// 1.创建 DAO
StudentDAO dao = new StudentDAO();
// 2.创建实体类
Student user = new Student();
user.setUsername("hellojpa test");
user.setPassword("jpa password");
user.setAge(20);
// 开始事务
EntityManagerHelper.beginTransaction();
// 3. 保存
dao.save(user);
// 提交事务真正保存实体到数据库
EntityManagerHelper.commit();
// 4. 列出数据库中所有对象
List<Student> result = dao.findAll();
for(Student o : result) {
System.out.println(o.getId());
System.out.println(o.getUsername());
}
// 5. 更改用户名
user.setUsername("测试JPA");
// 开始事务
EntityManagerHelper.beginTransaction();
// 保存(JPA会自动更新变动过的字段)
dao.update(user);
// 提交事务真正保存实体到数据库
EntityManagerHelper.commit();
// 6. 查找所有年龄为20的用户,从第1个开始获取(第0个是第一条记录)
result = dao.findByAge(20, 1);
for(Student o : result) {
System.out.println(o.getId());
System.out.println(o.getUsername());
}
// 7. 根据 ID 查找
user = dao.findById(2);
System.out.println(user.getUsername());
// 8. 删除
// 开始事务
EntityManagerHelper.beginTransaction();
// 保存(JPA会自动更新变动过的字段)
dao.delete(user);
// 提交事务真正保存实体到数据库
EntityManagerHelper.commit();
}
}
若部署到tomcat,没有什么问题,也不要额外添加什么。