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大概就介绍到这里吧,还有一些其他比较少用的用法,后面 有碰到过再看看