SpringData JPA 使用SQLQuery原生

使用原生SQL

public interface UserRepository extends JpaRepository<User, Long> {

  @Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)
  User findByEmailAddress(String emailAddress);
}
给上nativeQuery=true就能很方便的使用原生sql了。


下面这些其实是走hibernate那边了,之前对jpa的理解还不是很深,现在懂了更好的方式。

1.用注解创建EntityManager:

/*unitName是用来选择特定的PersistenceContext,默认会选择主数据源,这个在创建数据源的bean的时候会通过   .persistenceUnit( "secondaryPersistenceUnit" ) 来创建,这个方法是在 EntityManagerFactoryBuilder的对象上的*/

@PersistenceContext(unitName = "secondaryPersistenceUnit")

EntityManager entityManager;  


2.创建SQLQuery:

  1. Session session = entityManager.unwrap(org.hibernate.Session.class);  
  2. SQLQuery query = session.createSQLQuery(sql);  
  3. List list=query.list();

3.需要注意的:

数据库操作需要添加事务注解   @Transactional

4.封装好的一个工具类:

[java]  view plain  copy
  print ?
  1. package com.dean.app.service.system;  
  2.   
  3. import java.beans.Introspector;  
  4. import java.beans.PropertyDescriptor;  
  5. import java.lang.reflect.Method;  
  6. import java.math.BigInteger;  
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9. import java.util.Map;  
  10.   
  11. import javax.persistence.EntityManager;  
  12. import javax.persistence.PersistenceContext;  
  13. import javax.persistence.Query;  
  14. import javax.transaction.Transactional;  
  15.   
  16. import org.apache.commons.beanutils.ConvertUtils;  
  17. import org.hibernate.SQLQuery;  
  18. import org.hibernate.Session;  
  19. import org.hibernate.transform.Transformers;  
  20. import org.springframework.stereotype.Repository;  
  21. import org.springframework.util.CollectionUtils;  
  22.   
  23. @Transactional  
  24. @Repository  
  25. public class CommonDao {  
  26.       
  27.     @PersistenceContext  
  28.     EntityManager entityManager;  
  29.       
  30.     /** 
  31.      * * 查询数据集合 
  32.      * @param sql 查询sql sql中的参数用:name格式  
  33.      * @param params 查询参数map格式,key对应参数中的:name 
  34.      * @param clazz 实体类型为空则直接转换为map格式 
  35.      * @return 
  36.      */  
  37.     @SuppressWarnings("unchecked")  
  38.     public List<?> queryListEntity(String sql,Map<String, Object> params, Class<?> clazz){  
  39.         Session session = entityManager.unwrap(org.hibernate.Session.class);  
  40.         SQLQuery query = session.createSQLQuery(sql);  
  41.         if (params != null) {  
  42.             for (String key : params.keySet()) {  
  43.                 query.setParameter(key, params.get(key));  
  44.             }  
  45.         }  
  46.         query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);  
  47.         List<Map<String, Object>> result =  query.list();  
  48.         if (clazz != null) {  
  49.             List<Object>  entityList = convert(clazz, result);  
  50.             return entityList;  
  51.         }  
  52.         return result;  
  53.     }  
  54.   
  55.     private List<Object> convert(Class<?> clazz, List<Map<String, Object>> list) {  
  56.         List<Object> result;  
  57.         if (CollectionUtils.isEmpty(list)) {  
  58.             return null;  
  59.         }  
  60.         result = new ArrayList<Object>();  
  61.         try {  
  62.              PropertyDescriptor[] props = Introspector.getBeanInfo(clazz).getPropertyDescriptors();  
  63.              for (Map<String, Object> map : list) {  
  64.                  Object obj = clazz.newInstance();  
  65.                  for (String key:map.keySet()) {  
  66.                      String attrName = key.toLowerCase();  
  67.                      for (PropertyDescriptor prop : props) {  
  68.                          attrName = removeUnderLine(attrName);  
  69.                          if (!attrName.equals(prop.getName())) {  
  70.                              continue;  
  71.                          }  
  72.                          Method method = prop.getWriteMethod();  
  73.                          Object value = map.get(key);  
  74.                          if (value != null) {  
  75.                              value = ConvertUtils.convert(value,prop.getPropertyType());  
  76.                          }  
  77.                          method.invoke(obj,value);  
  78.                      }  
  79.                  }  
  80.                  result.add(obj);  
  81.              }  
  82.         } catch (Exception e) {  
  83.             throw new RuntimeException("数据转换错误");  
  84.         }  
  85.         return result;  
  86.     }  
  87.   
  88.     private String removeUnderLine(String attrName) {  
  89.         //去掉数据库字段的下划线  
  90.          if(attrName.contains("_")) {  
  91.             String[] names = attrName.split("_");  
  92.             String firstPart = names[0];  
  93.             String otherPart = "";  
  94.             for (int i = 1; i < names.length; i++) {  
  95.                 String word = names[i].replaceFirst(names[i].substring(01), names[i].substring(01).toUpperCase());  
  96.                 otherPart += word;  
  97.             }  
  98.             attrName = firstPart + otherPart;  
  99.          }  
  100.         return attrName;  
  101.     }  
  102.       
  103.     /** 
  104.      * 获取记录条数 
  105.      * @param sql 
  106.      * @param params 
  107.      * @return 
  108.      */  
  109.     public Integer getCountBy(String sql,Map<String, Object> params){  
  110.         Query query =  entityManager.createNativeQuery(sql);  
  111.         if (params != null) {  
  112.             for (String key : params.keySet()) {  
  113.                 query.setParameter(key, params.get(key));  
  114.             }  
  115.         }  
  116.         BigInteger bigInteger  = (BigInteger) query.getSingleResult();  
  117.         return bigInteger.intValue();  
  118.     }  
  119.       
  120.     /** 
  121.      * 新增或者删除 
  122.      * @param sql 
  123.      * @param params 
  124.      * @return 
  125.      */  
  126.     public Integer deleteOrUpDate(String sql,Map<String, Object> params){  
  127.         Query query =  entityManager.createNativeQuery(sql);  
  128.         if (params != null) {  
  129.             for (String key : params.keySet()) {  
  130.                 query.setParameter(key, params.get(key));  
  131.             }  
  132.         }  
  133.         return query.executeUpdate();  
  134.     }  
  135. }  

1.上面代码中getCountBy()方法返回的integer,因为数据库返回的是BigInteger因此需要转化一下

2.还有数据中要是存在下划线的字段与实体对应时对应不上因此需要将下划线去掉并且下划线后面的字符串首字母需要转换为大写,比如数据库中字段为login_name而自己定义的实体对象为loginName,这里转换只是为了做到能够通用。不转化的时候只需要写SQL的时候取个别名和实体对应即可。

3.如果不需要转化成具体的实体可以直接使用List<Map<String,Object>>集合,也可以直接使用query.setResultTransformer(Transformers.toBean(clazz))转化为指定的实体,但是要是数据库中的某些字段为bigint(我使用的是MySQL数据库)那么自己定义的实体的对应属性需要用BigInterger类型,否则会报类型转换错误。其他数据库没有测试过,对照着改就可以了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值