jpa eclipse搭建过程和注意事项

来源:互联网 发布:爱情公寓 知乎 编辑:程序博客网 时间:2024/05/21 06:18

环境:Eclipse Jpa2.0 jdk1.7 tomcat7

 

1、在eclipse中 一个jpa项目

创建完成后,可以看到建好的项目

Persistence.xml是jpa项目的全局配置文件

 

2、添加项目需要的jar包

antlr-2.7.7.jar
dom4j-1.6.1.jar
ehcache-core-2.4.3.jar
hibernate-commons-annotations-4.0.2.Final.jar
hibernate-core-4.2.4.Final.jar
hibernate-ehcache-4.2.4.Final.jar
hibernate-entitymanager-4.2.4.Final.jar
hibernate-jpa-2.0-api-1.0.1.Final.jar
javassist-3.15.0-GA.jar
jboss-logging-3.1.0.GA.jar
jboss-transaction-api_1.1_spec-1.0.1.Final.jar
mysql-connector-java-5.1.7-bin.jar
ojdbc6.jar
slf4j-api-1.6.1.jar

这里添加了两个数据库的驱动包,不是必须的,根据自己连接的数据库来添加不同的驱动包

 

3、在src目录下创建bean目录,用于存放于数据库关联的实体类(本案例创建了三个实体类做演示,分别是:Account、Emp4、Dept6)

         实体类可以手动创建,也可以通过工具生成

         如果jpa项目,可以通过在项目右键,选择JPA Tools选项,里面可以反向生成实体类

右侧红线框中,第一个是根据实体构建表,下面那个是根据表构建实体类

         实体类注意事项:

如果单表操作无所谓,但是一旦涉及到多表操作,就会出现很多问题:

1)      数据类型要用Integer这种包装类型,不要用基本数据类型(不然会出现在数据库中生成关联对象列)

2)      所有注解不要放在属性上,要放在get方法上(不然也会出现在数据库中生成关联对象列)

3)      如果是自己新建的实体类,添加@Entity注解后,会出错,需要在persistence.xml中引用此类才行(引用方式在下面会的persistence.xml文件中会介绍);并且还要加上@ID注解,不然也会编译错误

 

4、配置persistence.xml,完整的xml配置如下:

         

<?xmlversion="1.0"encoding="UTF-8"?><persistenceversion="2.0"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/persistencehttp://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">    <persistence-unitname="jpa_test1">        <!--        配置使用什么 ORM产品来作为 JPA的实现        1. 实际上配置的是 javax.persistence.spi.PersistenceProvider接口的实现类        2. 若 JPA项目中只有一个 JPA的实现产品,则也可以不配置该节点.        -->        <provider>org.hibernate.ejb.HibernatePersistence</provider>               <!-- 加入持久化类 -->        <class>jpa_test1.Account</class>        <class>jpa_test1.Emp4</class>        <class>jpa_test1.Dept6</class>               <!--        配置二级缓存的策略(不是必须)        ALL:所有的实体类都被缓存        NONE:所有的实体类都不被缓存.        ENABLE_SELECTIVE:标识 @Cacheable(true)注解的实体类将被缓存        DISABLE_SELECTIVE:缓存除标识 @Cacheable(false)以外的所有实体类        UNSPECIFIED:默认值,JPA产品默认值将被使用        -->        <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>               <properties>            <!-- 连接数据库的基本信息 -->            <propertyname="javax.persistence.jdbc.driver"value="oracle.jdbc.OracleDriver"/>            <propertyname="javax.persistence.jdbc.url"value="jdbc:oracle:thin:@localhost:1521:orcl"/>            <propertyname="javax.persistence.jdbc.user"value="scott"/>            <propertyname="javax.persistence.jdbc.password"value="tiger"/>                       <!-- 配置 JPA实现产品的基本属性.配置 hibernate的基本属性(不是必须) -->            <propertyname="hibernate.format_sql"value="true"/>            <propertyname="hibernate.show_sql"value="true"/>            <propertyname="hibernate.hbm2ddl.auto"value="update"/>                       <!-- 二级缓存相关(不是必须) -->            <propertyname="hibernate.cache.use_second_level_cache"value="true"/>            <propertyname="hibernate.cache.region.factory_class"value="org.hibernate.cache.ehcache.EhCacheRegionFactory"/>            <propertyname="hibernate.cache.use_query_cache"value="true"/>        </properties>    </persistence-unit></persistence>

 

5、创建一个test包,包中创建一个测试类,测试单表操作,代码如下:

public class MyTest {     public static void main(String[] args) {        String pname="jpa_test1";               //1、EntityManagerFactory相当于hibernate的sessionFactory        //有两种创建方法,第一种是直接传到persistence.xml中persistence-unit标签的名称        EntityManagerFactory facotry=Persistence.createEntityManagerFactory(pname);               //另一种是不管可以传递名字,还可以传递一些参数,如下面show_sql的参数来设置连接的配置        /*Map map=new HashMap();        map.put("hibernate.show_sql", false);        EntityManagerFactory facotry=Persistence.createEntityManagerFactory(pname);*/               //2、EntityManager相当于hibernate的session        EntityManager manager=facotry.createEntityManager();               //3、开启事务        EntityTransaction tran=manager.getTransaction();        tran.begin();               //4、进行持久化操作        //插入,相当于hibernate的save(和hibernate的 save方法的不同之处:若对象有 id, 则不能执行 insert操作,而会抛出异常. )        /*Account acc=newAccount();        acc.setUsername("jpatest1");        acc.setPassword("123");               manager.persist(acc);        //保存完后可以获取保存成功的ID        System.out.println(acc.getAid());        */               //find查询,相当于hibernate的get方法        /*Account acc=manager.find(Account.class,1);        System.out.println(acc.getUsername());*/               //getReference,相当于hibernate的load方法(getReference只有使用查询出来的对象才会发送SQL,而get执行查询就立即发送SQL查询)        Account acc=manager.getReference(Account.class, 1);        System.out.println(acc.getUsername());               //5、提交事务        tran.commit();               //6、关闭EntityManager        manager.close();               //7、关闭EntityManagerFactory        facotry.close();    }}


 

-------------到此为止单表的jpa操作完毕------------

6、单向多对一

   1) 在Emp6中,新建一个private Dept6 dept; 并且提供get/set和注解,配置如下:

@ManyToOne(fetch=FetchType.EAGER)       @JoinColumn(name="deptid")       publicDept6 getDept() {              returndept;       }        publicvoid setDept(Dept6 dept) {              this.dept= dept;       }


2) 在测试类中进行测试

             

 Dept6 dept=new Dept6();        dept.setDeptname("jpa1");        dept.setLoc("1111");               Emp4 emp1=newEmp4();        emp1.setEname("11");        emp1.setDept(dept);               Emp4 emp2=new Emp4();        emp2.setEname("222");        emp2.setDept(dept);               manager.persist(dept);//先保存一方(如果数据库已经有一方数据,需要做多对一的添加,也可以直接创建一个部门对象,设置一个id值,不一定非要先保存dept,才能让员工获得一方dept对象,比如可以像横线下面那段代码写法)        manager.persist(emp1);//再保存多方    manager.persist(emp2); Dept6 dept=new Dept6();        dept.setId(5650);               Emp4 emp1=new Emp4();        emp1.setEname("11");        emp1.setDept(dept);               Emp4 emp2=new Emp4();        emp2.setEname("222");        emp2.setDept(dept);               manager.persist(emp1);    manager.persist(emp2);

 

6、单向一对多

   1) 在Dept6中,添加如下集合,存放关联的员工:

private Set<Emp4> emps=new HashSet<Emp4>();并生成get/set和注解,配置如下://注意: 若在 1 的一端的 @OneToMany 中使用 mappedBy 属性, 则 @OneToMany 端就不能再使用 @JoinColumn 属性了.@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL)        @JoinColumn(name="deptid")        public Set<Emp4>getEmps() {            returnemps;        }         public voidsetEmps(Set<Emp4> emps) {            this.emps =emps;}      注意: 定义的set集合需要new,并且需要指定泛型


 

2) 在测试类中进行测试,代码如下:

                  

 Dept6 dept=new Dept6();        dept.setDeptname("xxx");               Emp4 emp1=new Emp4();        emp1.setEname("11");               Emp4 emp2=new Emp4();        emp2.setEname("222");               dept.getEmps().add(emp1);        dept.getEmps().add(emp2);           manager.persist(dept);

 

6、JPQL查询

   1) 基础jpql

String jpql = "FROM Customer c WHERE c.age > ?";        Query query= entityManager.createQuery(jpql);               //占位符的索引是从 1 开始        query.setParameter(1,1);        List<Customer>customers = query.getResultList();        System.out.println(customers.size());


 

2) 如果只想查询部分列,那么集合将会存放数组

如果查询部分列,不想集合存放数组,那么需要给实体提供一个对应的构造函数,并如下查询:

Stringjpql = "SELECT new Customer(c.lastName, c.age) FROM Customer c WHERE c.id> ?";        List result=entityManager.createQuery(jpql).setParameter(1, 1).getResultList();               System.out.println(result);


 

3)  也可以通过createNamedQuery查询实体类中已经写好的jpql

@NamedQuery(name="testNamedQuery", query="FROM Customer cWHERE c.id = ?")//这里eclipse可能会显示错误,但是不影响运行,也可以写成select c FROM Customer c WHERE c.id = ?@Table(name="JPA_CUTOMERS")@Entitypublicclass Customer { Queryquery =entityManager.createNamedQuery("testNamedQuery").setParameter(1,3);    Customercustomer = (Customer) query.getSingleResult();           System.out.println(customer);


 

4)  也可以使用sql语句查询:

String sql = "SELECT age FROM jpa_cutomers WHERE id = ?";        Query query= entityManager.createNativeQuery(sql).setParameter(1, 3);               Objectresult = query.getSingleResult();        System.out.println(result);


 

5)  使用 hibernate 的查询缓存

在每次查询后面跟上.setHint(QueryHints.HINT_CACHEABLE, true);

如:

第一次查询:Query query =

entityManager.createQuery(jpql)

.setHint(QueryHints.HINT_CACHEABLE, true);

第二次查询:query =

entityManager.createQuery(jpql)

.setHint(QueryHints.HINT_CACHEABLE, true);

 

6)  查询时也可以使用OrderBy、GroupBy、关联查询、子查询,如:

OrderBy:

String jpql = "FROM Customer c WHERE c.age > ? ORDER BY c.ageDESC";

GroupBy:

String jpql = "SELECT o.customer FROM Order o "

                +"GROUP BY o.customer "

                +"HAVING count(o.id) >= 2";

关联查询:

Stringjpql = "FROM Customer c LEFT OUTER JOIN FETCH c.orders WHERE c.id = ?";

子查询:

String jpql = "SELECT o FROM Order o "

+ "WHERE o.customer = (SELECT c FROM Customer c WHERE c.lastName =?)";

7)  使用 jpql 自带的函数

String jpql = "SELECT lower(c.email) FROM Customer c";

 

8)  可以使用 JPQL 完成 UPDATE 和 DELETE 操作

String jpql = "UPDATE Customer c SET c.lastName = ? WHERE c.id =?";

  

 

原创粉丝点击