转载

拥抱JPA规范

前言

在上文Hibernate使用中曾经提到过Hibernate是JPA实现的一个超集,但当时使用的都是原生Hibernate,在本文中我们将拥抱JPA规范,重构持久化层。

JPA+HIbernate配置

下面是ApplicationContxt文件

XML<bean id="entityManagerFactory"   class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">   <property name="dataSource" ref="dataSource" />   <property name="packagesToScan" value="sbeat.model" />   <property name="jpaVendorAdapter">    <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />   </property>   <property name="jpaProperties">    <props>     <prop key="hibernate.hbm2ddl.auto">update</prop>     <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>     <prop key="hibernate.show_sql">true</prop>    </props>   </property>  </bean>  <bean id="hibernateJpaVendorAdapter"   class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">   <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />  </bean>  <tx:annotation-driven />  <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">     <property name="entityManagerFactory" ref="entityManagerFactory"/>    <property name="dataSource" ref="dataSource" />   </bean>    

JPA动态查询

javaCriteriaBuilder cb=entityManager.getCriteriaBuilder(); CriteriaQuery<T> query=cb.createQuery(clazz); //clazz是你想要转换的类型,就是你的Entity.claa,如果你查的是count,就是Long.claa Root<T> root=query.from(clazz); query.select(root);//选取实体  //选择的条件 List<Predicate> predicates=new ArrayList<Predicate>(); predicates.add(cb.equal(..)); predicates.add(..); ... query.where(cb.and(predicates.toArray(new Predicate[predicates.size()]))); 

上面通过数组来组合与条件,还有一种方式:

javaPredicate predicate=cb.conjunction();//交集 predicate=cb.and(predicate,cb.equal(root.get("sex"),condition.get("sex")));  Predicate predicate=cb.disjunction();//并集 predicate=cb.or(predicate,cb.equal(root.get("sex"),condition.get("sex"))); 

JPA里面对类型控制比较严格,如下所示:

java//比较大小 cb.gt(root.<Integer>get("degree"),(Integer) condition.get("degree"));  //like cb.like(root.get("user").<String> get("nickName"),keyword)  //in 条件 root.get("tags").in(condition.get("tag")) 

对于关联映射,如果是ToOne,你可以连写get

root.get("user").get("account"); 

对于ToMany的,你可以使用Join

javaCriteriaQuery<Parent> criteria = cb.createQuery((Class<Parent>) Parent.class); Root<Parent> parent = criteria.from(Parent.class);  criteria.select((Selection<T>) parent); SetJoin<Parent, Children> children = parent.joinSet("children", JoinType.LEFT);  Predicate sexPredicate = cb.equal(children.get("sex"), "MALE"); parent.fetch(children); //parent.fetch("children");//try also this  criteria.where(sexPredicate); 

JPA分页

取分页内容

javaTypedQuery<T> typedQuery=entityManager.createQuery(query); typedQuery.setFirstResult((pageNum-1)*PAGE_SIZE); typedQuery.setMaxResults(PAGE_SIZE);  

取查询数目

javaCriteriaBuilder cb=entityManager.getCriteriaBuilder(); CriteriaQuery<Long> query=cb.createQuery(Long.class); query.select(cb.count(query.from(clazz)));//选取实体 return entityManager.createQuery(query).getSingleResult(); 

JPA 动态更新

javaCriteriaBuilder cb=entityManager.getCriteriaBuilder(); CriteriaUpdate<T> op=cb.createCriteriaUpdate(clazz); Root<T> root=op.from(clazz); op.set(fieldName, value); op.where(cb.equal(root.get(keyName), delta.get(keyName))); entityManager.createQuery(op).executeUpdate(); 

JPQL

JPA的JPQL语句和Hibernate的HQL语句十分类似

javaQuery query=entityManager.createQuery("SELECT r FROM Resume r WHERE r.user.id=:userId"); query.setParameter("id", userId); return (Resume) query.getSingleResult(); 

JPA CRUD

javapublic interface GenericDAO<T> {  public void insert(T t);  public void update(T t);  public void simpleUpdate(Map<Object, Object> delta);  public void delete(T t);  public T load(Long id);  public void refresh(T t);  public List<T> list(int pageNum);  public Long count();  public List<T> findByCondition(Map<Object,Object> condition);  public Long countByCondition(Map<Object,Object> condition); } @SuppressWarnings("unchecked") public class GenericDAOImpl<T> implements GenericDAO<T> {  private Class<T> clazz;  @PersistenceContext  protected EntityManager entityManager;  protected Session getCurrentSession() {   return entityManager.unwrap(Session.class);  }  public GenericDAOImpl(){   //取得T的类型变量   ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();   clazz = (Class<T>) type.getActualTypeArguments()[0];  }  public void insert(T t) {   entityManager.persist(t);  }  public void update(T t) {   entityManager.merge(t);  }  public void simpleUpdate(Map<Object, Object> delta) {   Field[] fields=clazz.getDeclaredFields();   CriteriaBuilder cb=entityManager.getCriteriaBuilder();   CriteriaUpdate<T> op=cb.createCriteriaUpdate(clazz);   Root<T> root=op.from(clazz);   String keyName="id";//默认选择基准为Id   //调整选择域   if(delta.containsKey("keyName")) keyName=(String) delta.get("keyName");   for(Field field:fields){    String fieldName=field.getName();    if(fieldName==keyName) continue;    if(delta.containsKey(fieldName)){     op.set(fieldName, delta.get(fieldName));    }   }   op.where(cb.equal(root.get(keyName), delta.get(keyName)));   entityManager.createQuery(op).executeUpdate();  }  public void delete(T t) {   entityManager.remove(t);  }  public T load(Long id) {   return (T) entityManager.find(clazz, id);  }  public List<T> list(int pageNum) {   CriteriaBuilder cb=entityManager.getCriteriaBuilder();   CriteriaQuery<T> query=cb.createQuery(clazz);   Root<T> root=query.from(clazz);   query.select(root);//选取实体   query.orderBy(cb.desc(root.get("created")));//排序   TypedQuery<T> typedQuery=entityManager.createQuery(query);   if(pageNum>0){    typedQuery.setFirstResult((pageNum-1)*SbeatConfig.PAGE_SIZE);    typedQuery.setMaxResults(SbeatConfig.PAGE_SIZE);   }   return typedQuery.getResultList();  }  public void refresh(T t) {   entityManager.refresh(t);  }  public Long count() {   //返回数目   CriteriaBuilder cb=entityManager.getCriteriaBuilder();   CriteriaQuery<Long> query=cb.createQuery(Long.class);   query.select(cb.count(query.from(clazz)));//选取实体   return entityManager.createQuery(query).getSingleResult();  }  public List<T> findByCondition( Map<Object, Object> condition) {   Field[] fields=clazz.getDeclaredFields();   CriteriaBuilder cb=entityManager.getCriteriaBuilder();   CriteriaQuery<T> query=cb.createQuery(clazz);   Root<T> root=query.from(clazz);   query.select(root);//选取实体   //选择的条件   List<Predicate> predicates=new ArrayList<Predicate>();   for(Field field:fields){    String fieldName=field.getName();    if(condition.containsKey(fieldName)){     predicates.add(cb.equal(root.get(fieldName), condition.get(fieldName)));    }   }   query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));   query.orderBy(cb.desc(root.get("created")));   TypedQuery<T> typedQuery=entityManager.createQuery(query);   Integer pageNum=0;   if(condition.containsKey(pageNum)){    pageNum=(Integer) condition.get("pageNum");   }   if(pageNum>0){    typedQuery.setFirstResult((pageNum-1)*SbeatConfig.PAGE_SIZE);    typedQuery.setMaxResults(SbeatConfig.PAGE_SIZE);   }   return typedQuery.getResultList();  }  public Long countByCondition(Map<Object, Object> condition) {   Field[] fields=clazz.getDeclaredFields();   CriteriaBuilder cb=entityManager.getCriteriaBuilder();   CriteriaQuery<Long> query=cb.createQuery(Long.class);   Root<T> root=query.from(clazz);   query.select(cb.count(root));//选取实体   List<Predicate> predicates=new ArrayList<Predicate>();   for(Field field:fields){    String fieldName=field.getName();    if(condition.containsKey(fieldName)){     predicates.add(cb.equal(root.get(fieldName), condition.get(fieldName)));    }   }   query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));   return entityManager.createQuery(query).getSingleResult();  } }  
正文到此结束
Loading...