您好,登錄后才能下訂單哦!
本篇文章為大家展示了Spring JPA repository怎樣自定義數(shù)據(jù)converter,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。
我們都知道在使用jpaRepository 里邊的方法時,返回的數(shù)據(jù)格式要么是和數(shù)據(jù)庫表映射的entity,要么是 Projection 接口,或者map,或者基本數(shù)據(jù)類型。如果想要自定義一個類來接收數(shù)據(jù)的話,就會拋出類型轉(zhuǎn)換錯誤。有了需求就有了動力。
最近在做項目的時候,想復(fù)用vo類來接收 Repository的返回數(shù)據(jù),可是spirngjpa不認(rèn),于是在百度一通無果后,開始debug執(zhí)行過程。功夫不負(fù)有心人,找到了數(shù)據(jù)轉(zhuǎn)換的方法。一切奧妙都在這個類里邊 DefaultConversionService ,如下部分截圖
也就說如果我自定義一個converter 并且把它注冊到這個ConversionService 里邊,那我就可以在我自己的convert里邊'猥瑣'欲為..
首先看截圖的第一個方法,顧名思義 可以獲取到他的共享的實例!這就很明顯了,就是給我們開的一扇窗呀。話不多說,下面就是使用方法 和 我自定義的convert
//springboot 啟動類 public static void main(String[] args) { SpringApplication.run(Application.class, args); ((DefaultConversionService) DefaultConversionService.getSharedInstance()) .addConverter(new MyConverter()); } //MyConverter.java import lombok.extern.slf4j.Slf4j; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.GenericConverter; import org.springframework.util.ConcurrentReferenceHashMap; import sun.reflect.misc.MethodUtil; import java.lang.reflect.Method; import java.math.BigInteger; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.stream.Stream; /** * .自定義 對象轉(zhuǎn)換器 * */ @Slf4j public class RdeConverter implements GenericConverter { private final Map<String, CacheMethod> methodCache = new ConcurrentReferenceHashMap<>(2 >> 6); private final CacheMethod NO_MATCH = new CacheMethod(null); @Override public Set<ConvertiblePair> getConvertibleTypes() { ConvertiblePair pair = new ConvertiblePair(Map.class, RdeConvertible.class); Set<ConvertiblePair> set = new HashSet<>(); set.add(pair); return set; } @Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { try { log.debug("***begin convert {} to {}", sourceType, targetType); Map map = (Map) source; Object o = targetType.getType().newInstance(); for (Object fieldName : map.keySet()) { String name = getMethodName(fieldName.toString()); String mName = o.getClass().getName().concat(".").concat(name); CacheMethod cacheMethod = methodCache.get(mName); if (cacheMethod == null) { //FIXME 如果存在方法重載 ,可能會存在異常 Method method = Stream.of(MethodUtil.getPublicMethods(targetType.getType())) .filter(m -> m.getName().equalsIgnoreCase(name)) .findFirst().orElse(null); cacheMethod = method == null ? NO_MATCH : new CacheMethod(method); methodCache.put(mName, cacheMethod); } if (cacheMethod != NO_MATCH) { try { Method method = cacheMethod.get(); method.invoke(o, caseParam(map.get(fieldName), method.getParameterTypes()[0])); } catch (Exception e) { log.error(e.getMessage(), e); } } } return o; } catch (Exception e) { log.error(e.getMessage(), e); } return null; } private Object caseParam(Object param, Class paramType) { if (param instanceof BigInteger) { if (param.getClass() == paramType) { return param; } if (paramType == Integer.class) { return ((BigInteger) param).intValue(); } if (paramType == Long.class) { return ((BigInteger) param).longValue(); } return param; } return param; } private String getMethodName(String fieldName) { String[] s = fieldName.trim().split("_"); if (s.length > 1) { String m = Stream.of(s).reduce((a, b) -> firstToUp(a) + firstToUp(b)).get(); return "set".concat(m); } return "set".concat(firstToUp(s[0])); } private String firstToUp(String s) { if (s.length() > 1) { return s.substring(0, 1).toUpperCase().concat(s.substring(1)); } return s.toUpperCase(); } class CacheMethod { private Method method; CacheMethod(Method method) { this.method = method; } Method get() { return this.method; } } } //RdeConvertible.java /** * .轉(zhuǎn)換類型標(biāo)記 * */ public interface RdeConvertible { }
使用截圖:
上述內(nèi)容就是Spring JPA repository怎樣自定義數(shù)據(jù)converter,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲備,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。