标签存档: JPA2.0

JPA2初试

JPA是Java Persistence API的简称。JPA通过注解描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。可以JPA1.0是Java5的标准,JPA2.0是Java6的标准。JPA2.0在2009-12-10正式发布,他只是标准,所以只有接口没有实现。目前,感觉比较正规的实现是EclipseLink,Hibernate即将支持。
JPA1.0简直是玩具,简洁是很简洁,但是功能实在有点少,看了JPA2.0的改进你就知道了,我想要的他都有了。
JPA2.0的改进:

  • 支持通过使用 @ElementCollection 标注来增强 collections, maps 和 lists( 这里不是指实体之间的关联关系 ) 集合,支持 map 的单向 one-to-many 关联 (JPA1.0 只允许双向 one-to-many 关联 )
  • 增加了 Criteria API
  • 增加二级缓存支持

这是我认为最有用的三个。

废话不说了,看具体的,我是用还没有正式发布的Hibernate3.5实现的。有Maven构建的。下载

先看看测试:

public class UserDaoTest extends TestCaseBase {
  1.  @Resource
  2.  private UserDao userDao;
  3.  
  4.  public void testPost() {
  5.   User user = new User();
  6.   user.setUsername("ir");
  7.   user.setPassword("ir");
  8.   List roles = new ArrayList();
  9.   roles.add(User.ROLE_STUDENT);
  10.   roles.add(User.ROLE_TEACHER);
  11.   user.setRoles(roles);
  12.   userDao.post(user);
  13.  }
  14.  
  15.  @Test
  16.  public void testGet() throws Exception {
  17.   testPost();// 存储一个名叫"ir"的用户
  18.   User user = userDao.get("ir");// 取出一个名叫"ir"的用户
  19.   log.debug(BeanUtils.describe(user));
  20.   /**
  21.    * 结果为:{id=1, username=ir, roles=ROLE_STUDENT, class=class
  22.    * org.jerrymouse.User, password=ir}
  23.    */
  24.   log.debug(user.getRoles());// 结果为:[ROLE_STUDENT, ROLE_TEACHER]
  25.  }
  26. }

里面只有一个用例testGet,一存一取,一看就明白。那个User和UserDao是怎么回事呢?

@Entity
  1. public class User implements CopyAble {
  2.  public static String ROLE_STUDENT = "ROLE_STUDENT";
  3.  public static String ROLE_TEACHER = "ROLE_TEACHER";
  4.  
  5.  @Id
  6.  @Column(nullable = false)
  7.  @GeneratedValue(strategy = GenerationType.AUTO)
  8.  private Integer id;//主键
  9.  
  10.  private String password;
  11.  
  12.  @ElementCollection(fetch = FetchType.EAGER)
  13.  private List roles;//一对多集合
  14.  
  15.  @Column(unique = true)
  16.  private String username;
  17.  
  18. //get and set
  19. }

如果是JPA1.0必须再写一个Role类。

@Component
  1. public class UserDao extends DatabaseSupport {
  2.  private static Log log = LogFactory.getLog(UserDao.class);
  3.  
  4.  public User get(String username) {
  5.   User user = null;
  6.   EntityManager em = null;
  7.   try {
  8.    em = getEntityManager();
  9.    /**
  10.     * 构造一个Query
  11.     */
  12.    CriteriaBuilder cb = em.getCriteriaBuilder();
  13.    CriteriaQuery query = cb.createQuery(User.class);
  14.    Root emp = query.from(User.class);
  15.    query = query.select(emp).where(
  16.      cb.equal(emp.get("username"), username));
  17.    /**
  18.     * 运行之
  19.     */
  20.    user = em.createQuery(query).getSingleResult();
  21.   } catch (NoResultException e) {
  22.    return null;
  23.   } finally {
  24.    em.close();
  25.   }
  26.   return user;
  27.  }
  28.  
  29.  @Override
  30.  public Class getType() {
  31.   return User.class;
  32.  }

终于可以不写一行SQL就能实现数据库查询了,这一点看似寻常其实很重要,它可以在重构时大大减少错误的数量。
JPA2.0的Criteria功能远远不限于此,文档中有介绍。

对了,推荐一本非常好的JPA读物

Pro JPA 2: Mastering the Java Persistence API

Pro JPA 2: Mastering the Java Persistence API