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<Task> findAll(){ Query query = this.em.createQuery("select t from Task t ",Task.class); return query.getResultList(); } /** * 通过原生sql查询某些字段 * @return */ public List<Object[]> findTuple(){ Query query = this.em.createNativeQuery("select t.id ,t.task_name from tb_task t "); return query.getResultList(); } /** * 查询字段映射成map * @return */ public List<Map<String, Object>> 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<Task> findByCriteria(){ CriteriaBuilder cb = em.getCriteriaBuilder(); //创建查询工厂类 CriteriaQuery<Task> c = cb.createQuery(Task.class); //创建一个查询实例 Root<Task> p = c.from(Task.class); //类似from task , Path<String> expression = p.get("taskName"); //获取属性路径 Predicate condition = cb.like(expression, "%taskName%"); //创建where查询 c.where(condition); TypedQuery<Task> q = em.createQuery(c); //查询查新 List<Task> 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<T> entityClass; private EntityManager entityManager ; private SimpleJpaRepository<T, ID> 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<T,ID>(entityClass, entityManager); this.entityManager = entityManager; } /** * 获取EntityManager,操作jpa api的入口 * @return */ public EntityManager getEntityManager() { return entityManager; } /** * 给子类提供simpleJpaRepository实例,用来操作spring data jpa常用的接口 * @return */ public SimpleJpaRepository<T, ID> getSimpleJpaRepository() { return simpleJpaRepository; }}
然后让我们的taskdao来继承这个GenericDao,这样就可以完成利用spring data jpa提供的接口了
@Repository("taskDao")public class TaskDao extends GenericDao<Task, Long>{ /** * 自定义查询 * @return */ public List<Map<String, Object>> 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大概就介绍到这里吧,还有一些其他比较少用的用法,后面 有碰到过再看看
联系客服