hibernate的DAO層封裝-擴(kuò)展功能

1.說明

  • 以[hibernate的dao層封裝-基礎(chǔ)功能]所說明的方法為基礎(chǔ)
  • 某些需求不太確定,根據(jù)實(shí)際需要進(jìn)行調(diào)整.
  • 代碼不做詳細(xì)說明

2.根據(jù)實(shí)體id,刪除數(shù)據(jù)庫(kù)的數(shù)據(jù)

 /**
     * 刪除多個(gè)entity
     * @param clazz 要?jiǎng)h除的實(shí)體類
     * @param ids 被刪除的數(shù)據(jù)id數(shù)組
     * @return
     * @time 2018年11月13日 上午11:46:34
     * @author authstr
     */
    @Override
    public int removeIds(Class clazz, Serializable[] ids) {
        //從實(shí)體類獲取數(shù)據(jù)表名稱
        String tableName=ReflectionUtils.getEntityTableName(clazz);
        //如果沒有g(shù)et到值,拋出一個(gè)內(nèi)部異常
        Assert.isTrue(StringUtils.hasText(tableName),
                "該實(shí)體類["+clazz.getSimpleName()+"]沒有設(shè)置表映射!",true);
        return removeIds(tableName,ids);
    }
    /**
     * 刪除多個(gè)entity
     * @param tableName 要?jiǎng)h除的數(shù)據(jù)表名稱
     * @param ids 被刪除的數(shù)據(jù)id數(shù)組
     * @return
     * @time 2018年11月13日 上午11:46:34
     * @author authstr
     */
    public int removeIds(String tableName, Serializable[] ids) {
        StringBuffer sqlstring = new StringBuffer();
        sqlstring.append(" delete from " +tableName);
        sqlstring.append(" where id in (:ids) ");
        Map<String,Object> para=new HashMap<String,Object>();
        para.put("ids", ids);
        return this.executeSQl(sqlstring.toString(), para);
    }


    /**
     * 通過一個(gè)id刪除一個(gè)entiy
     * @time 2018年11月13日14:04:43
     * @author authstr
     */
    @Override
    public int remove(Class clazz, Serializable id) {
        return removeIds(clazz,new Serializable[]{id});
    }

3.快捷構(gòu)建簡(jiǎn)單sql語句進(jìn)行查詢

    /**
     * 根據(jù)相關(guān)參數(shù)構(gòu)建簡(jiǎn)單的sql語句進(jìn)行查詢(執(zhí)行方法)
     * @param tableName 要查詢的表名
     * @param fields    where限制的字段名稱
     * @param values where限制的字段值
     * @param sqlResult 查詢要返回的信息
     * @return list集合
     * @time 2018年9月17日18:00:44
     * @author authstr
     */
    public  List queryByEntity(String tableName,String[] fields,Object[] values,String sqlResult,Class returnType){
        StringBuffer sql =new StringBuffer();
        sql.append("select  "+sqlResult+"  from "+tableName+" a  where 1=1");
        for(int i=0;i<fields.length;i++){
            sql.append(" and "+fields[i]+" =  :"+fields[i]);
        }
        return getBySQL(sql.toString(),fields,values,returnType);
    }
  /**
     * 根據(jù)實(shí)體和字段參數(shù)構(gòu)建簡(jiǎn)單的sql語句進(jìn)行查詢(執(zhí)行方法)
     * @param entity 要查詢的實(shí)體
     * @param fields    where限制的字段名稱
     * @param values where限制的字段值
     * @return list集合
     * @time 2018年9月17日18:02:49
     * @author authstr
     */
    public <T> List<T> queryByEntity(T entity,String[] fields,Object[] values){
        String tableName=ReflectionUtils.getEntityTableName(entity);//獲取實(shí)體對(duì)應(yīng)的表名
        //沒獲取到表名,拋出一個(gè)內(nèi)部異常
        Assert.isTrue(StringUtils.hasText(tableName),
                "該實(shí)體類["+entity.getClass().getSimpleName()+"]沒有設(shè)置表映射!",true);
        return queryByEntity(tableName,fields,values,"*",entity.getClass());
    }
  • 還有一些擴(kuò)展的方法,不過不一定會(huì)用上,代碼中沒有保留,這里只是備份一下

    /**
     * 根據(jù)實(shí)體查詢一條數(shù)據(jù)
     * @see #queryOneByEntity(Object, String[])
     * @param entity entity 要解析的實(shí)體類
     * @param fields 要作為where限制條件的屬性名稱,屬性值自動(dòng)從實(shí)體中獲取
     * @return 查詢結(jié)果
     * @time 2018年9月17日22:37:52
     * @author authstr
     */
    @Override
    public <T> T queryOneByEntity(T entity,String fields){
        return queryOneByEntity(entity,new String[]{fields});
    }

    /**
     * 根據(jù)實(shí)體查詢一條數(shù)據(jù)
     * @see #queryByEntity(Object, String[])
     * @see #queryByEntity(Object)
     * @param entity 要解析的實(shí)體類
     * @param fields 要作為where限制條件的屬性名稱,屬性值自動(dòng)從實(shí)體中獲取
     * @return 查詢結(jié)果
     * @time 2018年9月17日22:31:25
     * @author authstr
     */
    @Override
    public <T> T queryOneByEntity(T entity,String[] fields){
        List<T> res=queryByEntity(entity,fields);
        if(res==null||res.size()==0)return null;
        return res.get(0);
    }

    /**
     * 根據(jù)一個(gè)實(shí)體類構(gòu)建簡(jiǎn)單的sql查詢語句;     表名為該實(shí)體類映射的表,where限制字段為實(shí)體里值非空的屬性,where限制的值為實(shí)體該屬性的值,查詢返回為"*";
     * 注意! 如果實(shí)體內(nèi)有short,char,boolean類型的屬性,會(huì)被加到限制條件中
     * @param entity 要解析的實(shí)體類
     * @return 查詢結(jié)果
     * @time 2018年9月17日18:09:25
     * @author authstr
     */
    @Override
    public <T> List<T> queryByEntity(T entity){
        Map<String,Object> pv=ReflectionUtils.getFieldAndValue(entity);//獲取實(shí)體類中已經(jīng)存在的屬性值
        return queryByEntity(entity,pv);
    }

    /**
     *  根據(jù)一個(gè)實(shí)體類和一些屬性名稱構(gòu)建簡(jiǎn)單的sql查詢語句;
     * @param entity 要解析的實(shí)體類
     * @param fields 要作為where限制條件的屬性名稱,屬性值自動(dòng)從實(shí)體中獲取
     * @return 查詢結(jié)果list
     * @time 2018年9月17日20:37:01
     * @author authstr
     */
    @Override
    public <T> List<T> queryByEntity(T entity,String[] fields){
        Map<String,Object> pv =new HashMap<String, Object>();
        for(int i=0;i<fields.length;i++){//遍歷,從實(shí)體中取出對(duì)應(yīng)屬性的值
            //執(zhí)行對(duì)應(yīng)屬性的get方法
            Object val=ReflectionUtils.executeGetMethod(entity, fields[i]);
            //如果沒有g(shù)et到值,拋出一個(gè)內(nèi)部異常
            Assert.isTrue(val!=null,
                    "指定的屬性["+fields[i]+"],未能在["+entity.getClass().getName()+"]類型中g(shù)et到值!",true);
            pv.put(fields[i], val);//將值保存
        }
        return queryByEntity(entity,pv);
    }

    public <T> List<T> queryByEntity(T entity,Map<String,Object> pv){
        String[] fields=new String[pv.size()];
        Object[] values=new Object[pv.size()];
        int i=0;
        for (Entry<String, Object> entry : pv.entrySet()) {//遍歷
            fields[i]= entry.getKey();
            values[i]= entry.getValue();
        }
        return queryByEntity(entity,fields,values);
    }

4.通過id獲取實(shí)體對(duì)象


    /**
     * 通過id查詢一個(gè)對(duì)象
     * @param clazz
     * @param id
     * @return
     * @time 2018年11月4日 下午4:19:01
     * @author authstr
     */
    @Override
    public <T> T get(Class<T> clazz, Serializable id) {
        return this.get(clazz, id, null);
    }

    /**
     * 根據(jù)id查詢一個(gè)對(duì)象的指定字段
     * @param clazz
     * @param id
     * @param fields
     * @return
     * @time 2018年11月4日 下午4:18:30
     * @author authstr
     */
    @Override
    public <T> T get(Class<T> clazz, Serializable id, String[] fields) {
        //非空驗(yàn)證
        if (id == null || StringUtils.notText(id.toString())){
            return null;
        }
        //查詢一個(gè)對(duì)象
        if (fields == null || fields.length <= 0){
            return this.getSession().get(clazz, id);
        }
        //拼接sql,查詢指定字段
        StringBuffer sqlstring = new StringBuffer();
        sqlstring.append(" select  ");
        sqlstring.append(StringUtils.arrayToString(fields));
        sqlstring.append(" from " + clazz.getName());
        sqlstring.append(" where id=?");
        List<T> li= getByValuesSql(sqlstring.toString(),new Object[]{id},clazz);
        return CollectionUtils.listGetOneData(li);
    }

5.判斷一個(gè)對(duì)象里一些屬性的值是否具有唯一性

    /**
     * 判斷一個(gè)對(duì)象里一些屬性的值是否具有唯一性(參數(shù)重寫)
     * @param model
     * @param field
     * @return
     * @time 2018年11月1日 上午11:26:41
     * @author authstr
     */
    @Override
    public <T extends AbstractModel> boolean isUnique(T model,String...field){
        String tableName=ReflectionUtils.getEntityTableName(model);
        //沒獲取到表名,拋出一個(gè)內(nèi)部異常
        Assert.isTrue(StringUtils.hasText(tableName),
                "該實(shí)體類["+model.getClass().getSimpleName()+"]沒有設(shè)置表映射!",true);
        return isUnique(model,tableName,field);
    }
    
    /**
     * 判斷一個(gè)對(duì)象里一些屬性的值是否具有唯一性
     * @param model 要判斷的model對(duì)象
     * @param tableName  表名
     * @param field 字段名稱
     * @return
     * @time 2018年11月1日 上午11:23:56
     * @author authstr
     */
    public <T extends AbstractModel> boolean isUnique(T model,String tableName,String...field){
        StringBuffer sqlstring= new StringBuffer();
        List<Object> values =new ArrayList<>();//參數(shù)值集合
        //構(gòu)建查詢語句
        sqlstring.append("select count(*) num from " + tableName + " a where 1=1 ");
        for(int i=0;i<field.length;i++){//遍歷字段,拼接查詢條件
            String fieldName=field[i].trim();
            if(StringUtils.hasText(fieldName)){
                 //獲取屬性值
                  Object propertyValue = ReflectionUtils.getProperty(model,fieldName);
                  sqlstring.append(" and a." + fieldName + "=?");
                  //記錄屬性值
                  values.add(propertyValue);
            }
        }
        //判斷是否存在id
        if(model.getId()!=null){
            //id不等于當(dāng)前id
            sqlstring.append(" and a.id <> ?");
            //記錄屬性值
            values.add(model.getId());
        }
        //執(zhí)行查詢
        List<Map>  list=getByValuesSql(sqlstring.toString(), values.toArray(), Map.class);
        Integer num= NumberUtils.toInteger(list.get(0).get("num"));
        if(num!=null&&num==0){
            return true;
        }
        return false;
    }

6.提供支持的反射工具類

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.Table;
import org.apache.commons.beanutils.PropertyUtils;

/**
 * 反射操作的相關(guān)工具類
 * @author authstr
 *
 */
public class ReflectionUtils {
    
    /**
     * 獲取一個(gè)實(shí)體對(duì)象所映射的表名,該對(duì)象需要使用了@Table注解
     * @param obj 要獲取的對(duì)象
     * @return 返回映射的表名,如果無法獲取,返回null
     * @time 2018年9月17日14:58:52
     * @author authstr
     */
    public static String getEntityTableName(Object obj){
        return getEntityTableName(obj.getClass());
    }
    /**
     * 獲取一個(gè)實(shí)體對(duì)象所映射的表名,該對(duì)象需要使用了@Table注解
     * @param clazz 要獲取的類型
     * @return 返回映射的表名,如果無法獲取,返回null
     * @time 2018年9月17日14:58:52
     * @author authstr
     */
    public static String getEntityTableName(Class clazz){
        try {
            return ((Table)clazz.getAnnotation(Table.class)).name();
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     *  <p> 通過get方法獲取對(duì)象的所有 屬性值不為null的  屬性和屬性值 </p>
     * <p><b> 注意!</b> </p>
     * <p> 對(duì)于基本數(shù)據(jù)類型,int,long,float,double,short如果屬性值為0,視為值不存在,不會(huì)返回 </p>
     *  <p>short,char,boolean會(huì)返回實(shí)際的值         </p>       
     * @param obj 要操作的對(duì)象
     * @return Map,key為屬性名稱,value為屬性的值
     * @time 2018年9月17日15:59:46
     * @author authstr
     */
    public static Map<String,Object>  getFieldAndValue(Object obj){
        Class<? extends Object> clazz=obj.getClass();
        Field[] field= clazz.getDeclaredFields();//獲取所有屬性
        Map<String,Object> res=new HashMap<String, Object>();
        for(int i=0;i<field.length;i++){
            Object getResult=executeGetMethod(obj,field[i].getName());//獲取該屬性的get方法執(zhí)行結(jié)果
            if(getResult instanceof Integer&&(int)getResult==0)getResult=null;//如果該結(jié)果是int,且值0,說明這個(gè)屬性的值是初始值,實(shí)際沒有賦值的,置為null
            if(getResult instanceof Long&&(long)getResult==0L)getResult=null;//類同上
            if(getResult instanceof Float&&(float)getResult==0f)getResult=null;//類同上
            if(getResult instanceof Double&&(double)getResult==0d)getResult=null;//類同上
            if(getResult instanceof Short&&(short)getResult==(short)0)getResult=null;//類同上
            if(getResult!=null)res.put(field[i].getName(), getResult);//如果通過這個(gè)屬性拿到了結(jié)果,保存
        }
        return res;
    }
    
    /**
     * 方法是否存在(僅判斷公共方法)
     * @param clazz 要判斷的類
     * @param methodName 要判斷的方法名稱
     * @return true 存在 false 不存在
     * @time 2018年10月8日14:03:21
     * @author authstr
     */
    public static boolean isMethodExist(Class clazz,String methodName){
          Method[] method = clazz.getDeclaredMethods();//獲取所有方法
          for(int i=0;i<method.length;i++){
              if(methodName.equals(method[i].getName())){
                  return true;//名字一樣,返回true;
              }
          }
          return false;
    }   
    
    /**
     * 屬性是否存在
     * @param clazz 要判斷的類
     * @param fieldName 要判斷的字段名稱
     * @return true 存在
     * @time 2018年10月8日14:12:45
     * @author authstr
     */
    public static boolean isFieldExist(Class clazz,String fieldName){
        //獲取所有屬性
        Field[] field= clazz.getDeclaredFields();
        for(int i=0;i<field.length;i++){
            //名字一樣,返回true;
            if(fieldName.equals(field[i].getName())){
                return true;
            }
        }
        return false;
    }
    
    /**
     * 獲取對(duì)象里指定屬性的值,獲取失敗返回null
     * @param target 要獲取的對(duì)象
     * @param name  屬性名稱
     * @return
     * @time 2018年11月1日 上午10:30:47
     * @author authstr
     */
    public static Object getProperty(Object target, String name) {
        try {
            return PropertyUtils.getProperty(target, name);
        }
        catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 調(diào)用對(duì)象中一個(gè)屬性的get方法
     * @param obj 要操作的對(duì)象
     * @param fieldName 屬性名稱
     * @return 該get方法的執(zhí)行結(jié)果
     * @time 2018年9月17日15:27:43
     * @author authstr
     */
    public static Object executeGetMethod(Object obj,String fieldName){
        fieldName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); // 將屬性的首字符大寫拾稳,方便構(gòu)造get咒吐,set方法
        Method m=null;
        try {
            //獲取get方法
            m = obj.getClass().getMethod("get" + fieldName);
            return m.invoke(obj);//執(zhí)行
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }       
    }
    
    /**
     * 調(diào)用對(duì)象中一個(gè)屬性的set方法
     * @param obj 要操作的對(duì)象
     * @param fieldName 屬性名稱
     * @param value 要set的值
     * @throws Exception  異常信息
     * @time 2018年10月8日14:27:27
     * @author authstr
     */
    public static <T> void executeSetMethod(Object obj,String fieldName,T value) throws Exception {
        // 將屬性的首字符大寫蛔钙,方便構(gòu)造get条篷,set方法
        fieldName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
        Method m=null;
         try {
            //獲取set方法
            m = obj.getClass().getMethod("set" + fieldName,value.getClass());
            m.invoke(obj,value);//執(zhí)行
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            throw new Exception("未發(fā)現(xiàn)字段["+fieldName+"]的set方法");
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("無法執(zhí)行["+fieldName+"]的set方法");
        }
    }
    
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末衰抑,一起剝皮案震驚了整個(gè)濱河市蚕愤,隨后出現(xiàn)的幾起案子琐馆,更是在濱河造成了極大的恐慌,老刑警劉巖魔熏,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衷咽,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蒜绽,警方通過查閱死者的電腦和手機(jī)镶骗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來滓窍,“玉大人卖词,你說我怎么就攤上這事巩那±艉唬” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵即横,是天一觀的道長(zhǎng)噪生。 經(jīng)常有香客問我,道長(zhǎng)东囚,這世上最難降的妖魔是什么跺嗽? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮页藻,結(jié)果婚禮上桨嫁,老公的妹妹穿的比我還像新娘。我一直安慰自己份帐,他們只是感情好璃吧,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著废境,像睡著了一般畜挨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上噩凹,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天巴元,我揣著相機(jī)與錄音,去河邊找鬼驮宴。 笑死逮刨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的堵泽。 我是一名探鬼主播禀忆,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼臊旭,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了箩退?” 一聲冷哼從身側(cè)響起离熏,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎戴涝,沒想到半個(gè)月后滋戳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡啥刻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年奸鸯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片可帽。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡娄涩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出映跟,到底是詐尸還是另有隱情蓄拣,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布努隙,位于F島的核電站球恤,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏荸镊。R本人自食惡果不足惜咽斧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望躬存。 院中可真熱鬧张惹,春花似錦、人聲如沸岭洲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钦椭。三九已至拧额,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間彪腔,已是汗流浹背侥锦。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留德挣,地道東北人恭垦。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親番挺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子唠帝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 我是日記星球238號(hào)星寶寶,我正在參加日記星球第六期21天蛻變之旅玄柏,這是我的第38篇原創(chuàng)日記襟衰,我相信堅(jiān)持的力量! ...
    Ms娟子閱讀 178評(píng)論 2 2
  • 昨天是減肥的第一天粪摘,剛開始飲食稍微控制的不錯(cuò)瀑晒!我相信自己能堅(jiān)持下去! 第二件大事就是學(xué)習(xí)徘意,...
    2cc39defd179閱讀 151評(píng)論 0 2
  • 想要擁有一個(gè)好看的自拍 首先就是要自信 其次就是B612 —— 一定要具備? 如果覺得自己同一時(shí)間拍了很多張照片苔悦,...
    芥末怪咖閱讀 414評(píng)論 0 0