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 {
@Resource
private UserDao userDao;
public void testPost() {
User user = new User();
user.setUsername("ir");
user.setPassword("ir");
List roles = new ArrayList();
roles.add(User.ROLE_STUDENT);
roles.add(User.ROLE_TEACHER);
user.setRoles(roles);
userDao.post(user);
}
@Test
public void testGet() throws Exception {
testPost();// 存储一个名叫"ir"的用户
User user = userDao.get("ir");// 取出一个名叫"ir"的用户
log.debug(BeanUtils.describe(user));
/**
* 结果为:{id=1, username=ir, roles=ROLE_STUDENT, class=class
* org.jerrymouse.User, password=ir}
*/
log.debug(user.getRoles());// 结果为:[ROLE_STUDENT, ROLE_TEACHER]
}
}
里面只有一个用例testGet,一存一取,一看就明白。那个User和UserDao是怎么回事呢?
@Entity
public class User implements CopyAble {
public static String ROLE_STUDENT = "ROLE_STUDENT";
public static String ROLE_TEACHER = "ROLE_TEACHER";
@Id
@Column(nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;//主键
private String password;
@ElementCollection(fetch = FetchType.EAGER)
private List roles;//一对多集合
@Column(unique = true)
private String username;
//get and set
}
如果是JPA1.0必须再写一个Role类。
@Component
public class UserDao extends DatabaseSupport {
private static Log log = LogFactory.getLog(UserDao.class);
public User get(String username) {
User user = null;
EntityManager em = null;
try {
em = getEntityManager();
/**
* 构造一个Query
*/
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery query = cb.createQuery(User.class);
Root emp = query.from(User.class);
query = query.select(emp).where(
cb.equal(emp.get("username"), username));
/**
* 运行之
*/
user = em.createQuery(query).getSingleResult();
} catch (NoResultException e) {
return null;
} finally {
em.close();
}
return user;
}
@Override
public Class getType() {
return User.class;
}
终于可以不写一行SQL就能实现数据库查询了,这一点看似寻常其实很重要,它可以在重构时大大减少错误的数量。
JPA2.0的Criteria功能远远不限于此,文档中有介绍。
对了,推荐一本非常好的JPA读物