jpa入门之环境搭建和CRUD基本操作
hibernate虽然好用但编写映射文件还是比较麻烦,虽然可以借助插件但是后期的维护还是比较麻烦,jpa的全称是Java Persistence API,实现该规范的产品很多像hibernate就是其中比较出名的一个,原则上应该尽量不要使用hibernate,可惜jpa只是一个接口规范,自 己按照规范写一套也不现实,只能通过hibernate间接的使用jpa.
1 使用hibernate的jpa实现需要的jar包如下
我用的是hibernate3.6的版本,如果是低版本的hibernate则还需要hibernate-commons-annotations.jar、hibernate-annotations.jar
2 persistence.xml的相关配置
jpa和hibernate类似需要一个类似hibernate.cfg.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="myPersistUnit" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.hbm2ddl.auto" value="update" /> <!-- 数据库的相关配置 --> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" /> <property name="hibernate.connection.url" value = "jdbc:mysql://127.0.0.1:3306/exercise?useUnicode=true&characterEncoding=UTF-8"/> <property name="hibernate.connection.username" value="root" /> <property name="hibernate.connection.password" value="123456" /> <!-- 指定方言 --> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> <property name="hibernate.show_sql" value="false" /> <property name="hibernate.format_sql" value="true" /> </properties> </persistence-unit> </persistence>
相信学过hibernate应该能看懂这个配置文件,需要注意的是persistence-unit节点的name属性,这个名称后面将会用到,另外这个 文件的名称只能是persistence.xml不能是别的名称且必须放在src下面的META-INF文件夹下面,如果不存在可以手动创建。
3 编写实体类
实体是jpa中比较重要的一部分,它承担着POJO和类似hibernate映射文件的功能,算得上是jpa的核心文件,下面这个是其中一个例子
package org.lxh.info; import java.util.Date; import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @Entity @Table(name = "m_users") public class User { private int id; private String name; private Date birthday; private Sex sex; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } @Column(length=20,nullable=false) public String getName() { return name; } public void setName(String name) { this.name = name; } @Temporal(TemporalType.DATE) public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Enumerated(EnumType.STRING) @Column(length=5,nullable=false) public Sex getSex() { return sex; } public void setSex(Sex sex) { this.sex = sex; } }
@Entity 这个注解表明这个java类是一个实体对象
@Table 该注解用来指定实体对应的表,默认情况下表名和实体类的名称相同
@Id 该注解用来指定主键
@GeneratedValue 该注解配置的是主键的生成策略
@Column 该注解用于指定数据库表对于的列名、唯一约束、非空约束等
@Temporal 主要用于日期属性上面,可以指定日期的类型
@Lob 指定映射到数据库的字段为大文本数据或者字节数组
@Enumerated 指定对于的属性为枚举
4 编写简单的JPA工具类
package org.lxh.util; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; public final class JpaUtil { private static EntityManagerFactory em; static{ em=Persistence.createEntityManagerFactory("myPersistUnit"); } public static EntityManager getEntityManager(){ return em.createEntityManager(); } }
5 JPA的crud基本操作
package org.lxh.test; import static org.junit.Assert.*; import java.util.*; import javax.persistence.EntityManager; import javax.persistence.EntityTransaction; import javax.persistence.Query; import org.lxh.info.Sex; import org.lxh.info.User; import org.lxh.util.JpaUtil; public class Test { @org.junit.Test public void testInsert() { EntityManager em=null; EntityTransaction tx=null; try{ em=JpaUtil.getEntityManager(); tx=em.getTransaction(); tx.begin(); User u=new User(); u.setBirthday(new Date()); u.setName("潘玮柏"); u.setSex(Sex.MAN); em.persist(u); tx.commit(); }catch(Exception e){ e.printStackTrace(); }finally{ if(em!=null){ em.close(); } } } @org.junit.Test public void testUpdate() { EntityManager em=null; EntityTransaction tx=null; try{ em=JpaUtil.getEntityManager(); tx=em.getTransaction(); tx.begin(); User u=new User(); u.setId(2); u.setName("周杰伦"); u.setSex(Sex.MAN); u.setBirthday(new Date()); em.merge(u); tx.commit(); }catch(Exception e){ e.printStackTrace(); }finally{ if(em!=null){ em.close(); } } } @org.junit.Test public void testDelete() { EntityManager em=null; EntityTransaction tx=null; try{ em=JpaUtil.getEntityManager(); tx=em.getTransaction(); tx.begin(); User u=em.find(User.class, 2); em.remove(u); tx.commit(); }catch(Exception e){ e.printStackTrace(); }finally{ if(em!=null){ em.close(); } } } /** * 最简单的查询 */ @org.junit.Test public void testJPLQuery() { EntityManager em=null; EntityTransaction tx=null; try{ em=JpaUtil.getEntityManager(); String jpl="select u from User u"; Query q=em.createQuery(jpl); List<User> all=q.getResultList(); Iterator<User> it=all.iterator(); while(it.hasNext()){ User user=it.next(); System.out.println(user.getName()+","+user.getBirthday()); } }catch(Exception e){ e.printStackTrace(); }finally{ if(em!=null){ em.close(); } } } /** * 使用命名参数的方式更新数据 */ @org.junit.Test public void testJPLUpdate() { EntityManager em=null; EntityTransaction tx=null; try{ em=JpaUtil.getEntityManager(); String jpl="update User u set u.name=:name where u.id=:id"; Query q=em.createQuery(jpl); q.setParameter("name", "加菲猫"); q.setParameter("id", 3); q.executeUpdate(); }catch(Exception e){ e.printStackTrace(); }finally{ if(em!=null){ em.close(); } } } }
最后来分析一下jpa的缺点:
1> 提供的主键生成策略较少
2>没有缓存机制
3> 实体类中注解和java代码混合在一起,可读性降低了
来自:http://blog.csdn.net/walkcode/article/details/39103277