资讯专栏INFORMATION COLUMN

拥抱JPA规范

pubdreamcc / 3190人阅读

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

前言

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

JPA+HIbernate配置

下面是ApplicationContxt文件

XML
        
        
        
            
        
        
            
                update
                org.hibernate.dialect.MySQLDialect
                true
            
        
    

    
        
    


    

      
         
         
      
JPA动态查询
javaCriteriaBuilder cb=entityManager.getCriteriaBuilder();
CriteriaQuery query=cb.createQuery(clazz);
//clazz是你想要转换的类型,就是你的Entity.claa,如果你查的是count,就是Long.claa
Root root=query.from(clazz);
query.select(root);//选取实体

//选择的条件
List predicates=new ArrayList();
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.get("degree"),(Integer) condition.get("degree"));

//like
cb.like(root.get("user"). get("nickName"),keyword)

//in 条件
root.get("tags").in(condition.get("tag"))

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

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

对于ToMany的,你可以使用Join

javaCriteriaQuery criteria = cb.createQuery((Class) Parent.class);
Root parent = criteria.from(Parent.class);

criteria.select((Selection) parent);
SetJoin 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 typedQuery=entityManager.createQuery(query);
typedQuery.setFirstResult((pageNum-1)*PAGE_SIZE);
typedQuery.setMaxResults(PAGE_SIZE);

取查询数目

javaCriteriaBuilder cb=entityManager.getCriteriaBuilder();
CriteriaQuery query=cb.createQuery(Long.class);
query.select(cb.count(query.from(clazz)));//选取实体
return entityManager.createQuery(query).getSingleResult();
JPA 动态更新
javaCriteriaBuilder cb=entityManager.getCriteriaBuilder();
CriteriaUpdate op=cb.createCriteriaUpdate(clazz);
Root 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 {
    public void insert(T t);

    public void update(T t);

    public void simpleUpdate(Map delta);

    public void delete(T t);

    public T load(Long id);

    public void refresh(T t);

    public List list(int pageNum);

    public Long count();

    public List findByCondition(Map condition);

    public Long countByCondition(Map condition);
}

@SuppressWarnings("unchecked")
public class GenericDAOImpl implements GenericDAO {

    private Class clazz;

    @PersistenceContext
    protected EntityManager entityManager;



    protected Session getCurrentSession() {
        return entityManager.unwrap(Session.class);
    }

    public GenericDAOImpl(){
        //取得T的类型变量
        ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
        clazz = (Class) type.getActualTypeArguments()[0];
    }

    public void insert(T t) {
        entityManager.persist(t);
    }

    public void update(T t) {
        entityManager.merge(t);
    }

    public void simpleUpdate(Map delta) {
        Field[] fields=clazz.getDeclaredFields();
        CriteriaBuilder cb=entityManager.getCriteriaBuilder();
        CriteriaUpdate op=cb.createCriteriaUpdate(clazz);
        Root 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 list(int pageNum) {
        CriteriaBuilder cb=entityManager.getCriteriaBuilder();
        CriteriaQuery query=cb.createQuery(clazz);
        Root root=query.from(clazz);
        query.select(root);//选取实体
        query.orderBy(cb.desc(root.get("created")));//排序
        TypedQuery 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 query=cb.createQuery(Long.class);
        query.select(cb.count(query.from(clazz)));//选取实体
        return entityManager.createQuery(query).getSingleResult();
    }




    public List findByCondition( Map condition) {
        Field[] fields=clazz.getDeclaredFields();
        CriteriaBuilder cb=entityManager.getCriteriaBuilder();
        CriteriaQuery query=cb.createQuery(clazz);
        Root root=query.from(clazz);
        query.select(root);//选取实体

        //选择的条件
        List predicates=new ArrayList();
        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 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 condition) {
        Field[] fields=clazz.getDeclaredFields();
        CriteriaBuilder cb=entityManager.getCriteriaBuilder();
        CriteriaQuery query=cb.createQuery(Long.class);
        Root root=query.from(clazz);
        query.select(cb.count(root));//选取实体

        List predicates=new ArrayList();
        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();
    }

}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64396.html

相关文章

  • SpringBoot 实战 (八) | 使用 Spring Data JPA 访问 Mysql 数据

    摘要:是一个基于映射的标准协议目前最新版本是。的主要实现由和等完成,我们只要使用来开发,无论是哪一个开发方式都是一样的。是的一个子项目,它通过基于的极大地减少了作为数据访问方案的代码量。源码下载后语以上为使用访问数据库的教程。 微信公众号:一个优秀的废人如有问题或建议,请后台留言,我会尽力解决你的问题。 前言 如题,今天介绍 Spring Data JPA 的使用。 什么是 Spring D...

    hedzr 评论0 收藏0
  • Spring Boot 的简单教程(四)数据库连接之Spring Data JPA的使用

    摘要:以前都是用进行数据库的开发,最近学习之后发现显得更友好,所以我们就一起来了解一下的原理吧。简单介绍持久性是的一个规范。它用于在对象和关系数据库之间保存数据。充当面向对象的领域模型和关系数据库系统之间的桥梁。是标识出主键是指定主键的自增方式。 以前都是用Mybatis进行数据库的开发,最近学习Spring Boot之后发现JPA显得更友好,所以我们就一起来了解一下JPA的原理吧。 Spr...

    yuxue 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<