spring data jpa 操作JPA 2.0原生api

spring data jpa 虽然为我们提供了很多便利,但业务往往是复杂的,便利并不能随心所欲,另外,如果你对原生的sql比较熟悉,或许你可以用用jpa2.0的原生api

操作JPA2.0 api我们只需要按平常建一个dao类就可以了,然后把EntityManager实体管理器注进来,这里用@PersistenceContext进行注入

@Repository("taskDao")
public class TaskDao{

    @PersistenceContext private EntityManager em ;

}

所有的数据库操作都基于EntityManager ,例如常见的CRUD

@Repository("taskDao")
public class TaskDao{

    @PersistenceContext private EntityManager em ;

    /**
     * 保存
     * @param t
     * @return
     */
    public Task save(Task t){
        this.em.persist(t);
        return t ;
    }

    /**
     * 更新
     * @param t
     * @return
     */
    public Task update(Task t){

        return this.em.merge(t);

    }


    /**
     * 删除
     * @param id
     */
    public void delete(Long id){
        Task t = this.em.unwrap(Task.class);
        t.setId(id);
        this.em.remove(t);
    }


    /**
     * 查找
     * @param id
     * @return
     */
    public Task findOne(Long id){

        return this.em.find(Task.class,id);

    }
}

利用Query进行hql,sql查询

@Repository("taskDao")
public class TaskDao{

    @PersistenceContext private EntityManager em ;
    /**
     * 查询列表
     * @return
     */
    @SuppressWarnings("unchecked")
    public List findAll(){
        Query query = this.em.createQuery("select t from Task t ",Task.class);
        return query.getResultList();
    }


    /**
     * 通过原生sql查询某些字段
     * @return
     */
    public  List findTuple(){

        Query query = this.em.createNativeQuery("select t.id ,t.task_name from tb_task t ");

        return query.getResultList();
    }

    /**
     * 查询字段映射成map
     * @return
     */
    public  List> findMap(){

        Query query = this.em.createQuery("select t.id as id ,t.taskName as taskName ,t.createTime as createTime from Task t ");
        query.unwrap(org.hibernate.Query.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        return  query.getResultList();

    }
}

使用criteria 查询


@Repository("taskDao")
public class TaskDao{

    @PersistenceContext private EntityManager em ;
/**
     * 通过Criteria创建查询
     * @return
     */
    public List findByCriteria(){

        CriteriaBuilder cb = em.getCriteriaBuilder();   //创建查询工厂类

        CriteriaQuery c = cb.createQuery(Task.class); //创建一个查询实例

        Root p = c.from(Task.class);  //类似from task ,

        Path expression = p.get("taskName"); //获取属性路径

        Predicate condition = cb.like(expression, "%taskName%"); //创建where查询
        c.where(condition);

        TypedQuery q = em.createQuery(c);  //查询查新
        List result = q.getResultList();

        return result ;
    }
}

criteria的优势是禁止构造语法错误的查询,个人感觉没什么用,不怎么建议大家用criteria,语法麻烦,而且学习成本大。

好,这时候,我有这样子的需求,我是想直接操作JPA api,它给我最大灵活性,但我又想把常用的接口放到基类中,而spring data jpa 提供的一些接口,确实又很方便,直接用它的接口比我自己来封装是不是要强大得多

通过前一篇博客,介绍了全自定义全局接口Basedao,
http://blog.csdn.net/yingxiake/article/details/51017797,
我们发现spring data jpa通过SimpleJpaRepository来实现spring data jpa的一些实用的方法的,那么我们可不可以来继承SimpleJpaRepository,然后也就可以用spring data jpa一些有用的方法了,那我们定义一个通用的dao类,其他模块的dao就直接继承这个dao吧

public class GenericDao<T,ID extends Serializable> {

    private Class entityClass; 
    private EntityManager entityManager ;
    private SimpleJpaRepository simpleJpaRepository ;


    /**
     * 注入EntityManager,同时实例化SimpleJpaRepository
     * @param em
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    @PersistenceContext
        /**
     * 注入EntityManager,同时实例化SimpleJpaRepository
     * @param em
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        Type genType = getClass().getGenericSuperclass();  
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();  
        entityClass = (Class) params[0];  

        this.simpleJpaRepository = new SimpleJpaRepository(entityClass, entityManager);

        this.entityManager = entityManager;
    }

    /**
     * 获取EntityManager,操作jpa api的入口
     * @return
     */
    public EntityManager getEntityManager() {
        return entityManager;
    }

    /**
     * 给子类提供simpleJpaRepository实例,用来操作spring data jpa常用的接口
     * @return
     */
    public SimpleJpaRepository getSimpleJpaRepository() {
        return simpleJpaRepository;
    }




}

然后让我们的taskdao来继承这个GenericDao,这样就可以完成利用spring data jpa提供的接口了

@Repository("taskDao")
public class TaskDao extends GenericDao<Task, Long>{

    /**
     * 自定义查询
     * @return
     */
    public List> findMap() {
        Query query = this.getEntityManager().createQuery("select t.id as id ,t.taskName as taskName ,t.createTime as createTime from Task t ");
        query.unwrap(org.hibernate.Query.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        return  query.getResultList();
    }


    /**
     * 利用spring data jpa提供的接口进行查询
     * @param id
     * @return
     */
    public Task findOne(Long id){

        return this.getSimpleJpaRepository().findOne(id);
    }

}

ok,spring data jpa大概就介绍到这里吧,还有一些其他比较少用的用法,后面 有碰到过再看看

你可能感兴趣的:(spring,data,jpa)