JPA开发(一)
之前一直在用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,没有什么问题,也不要额外添加什么。