拥抱JPA规范(转载)

来源:互联网 发布:免费淘宝号和密码大全 编辑:程序博客网 时间:2024/06/06 05:21

文章转载自拥抱JPA规范-segmentfault,若有侵权,请留言删除。


前言

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


JPA+HIbernate配置

下面是ApplicationContxt文件

<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动态查询

CriteriaBuilder cb=entityManager.getCriteriaBuilder();CriteriaQuery<T> query=cb.createQuery(clazz);//clazz是你想要转换的类型,就是你的Entity.claa,如果你查的是count,就是Long.claaRoot<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()])));



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

Predicate 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里面对类型控制比较严格,如下所示:

//比较大小cb.gt(root.<Integer>get("degree"),(Integer) condition.get("degree"));//likecb.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

CriteriaQuery<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 thiscriteria.where(sexPredicate);

JPA分页

取分页内容

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



取查询数目

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

JPA 动态更新

CriteriaBuilder 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语句十分类似

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

JPA CRUD

public 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();    }}
0 0