In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-21 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article introduces the knowledge of "what is the most concise way for Spring Data Jpa native SQL to return custom objects". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
The most concise way for Spring Data Jpa native SQL to return custom objects
This article only discusses two ways to query, using the jpa keyword query and custom sql
/ / Mode 11. List findByName (String name); / / Mode 22. @ Query (value = "select name from t_users where name =?", nativeQuery = true) List findByName2 (String name); use the API to receive
That is, by defining an interface interface UserName, both methods are supported by defining an interface to accept returns, and JPA natively supports
Public interface UserName {String getNname ();} Custom object receive
Method 1: JAP natively supports custom objects, but only if there is only one constructor, and some utility classes need to use the default constructor, which is inconvenient
Mode 2: JAP does not support custom objects and returns an array of Object [] objects.
Solution
The example is only the second solution. If you need to solve the problem of method-constructor, you can use it for reference. The following example implements itself and we define an interface ReabamDTO.
Public interface ReabamDTO {} GenericConverter implementation class
The content is map to ReabamDTO.
Public final class JpaConvert implements GenericConverter {@ Override public Set getConvertibleTypes () {return Collections.singleton (new ConvertiblePair (Map.class, ReabamDTO.class));} @ Override public Object convert (Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {return map2Pojo (source, targetType.getObjectType ()) } public static T map2Pojo (Object entity, Class tClass) {CopyOptions copyOptions = CopyOptions.create () .setIgnoreCase (true) .setIgnoreError (true) .setIgnoreNullValue (true) .setFieldNameEditor (StrUtil::toUnderlineCase); return BeanUtil.toBean (entity, tClass, copyOptions);}}
Add a custom convert to GenericConversionService
@ Configurationpublic class JpaConfig {@ PostConstruct public void init () {GenericConversionService genericConversionService = ((GenericConversionService) DefaultConversionService.getSharedInstance ()); genericConversionService.addConverter (new JpaConvert ());}} Test public interface UsersRepository extends JpaRepository {List findByName (String name); @ Query (value = "select name from t_users where name =?", nativeQuery = true) List findByName2 (String name);} @ Data@ToString@NoArgsConstructorpublic class UserName implements ReabamDTO {private String name } @ RunWith (SpringJUnit4ClassRunner.class) @ SpringBootTest (classes = DemoApplication.class, properties = {"spring.profiles.active=local"}) class DemoApplicationTests {@ Autowired private UsersRepository usersRepository; @ Test void contextLoads () {Users users = new Users (); users.setName ("A"); users.setAge (1); users.setAddress ("AA"); usersRepository.save (users) } / * * non-custom sql can return custom object * / @ Test void T2 () {List a = usersRepository.findByName ("A"); System.out.println (a);} / * Custom sql custom object * / @ Test void T3 () {List a = usersRepository.findByName2 ("A"); System.out.println (a) }} principle can choose to watch
Check the error message, and no converter exception can be found, then you only need to add the corresponding installer.
Org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [com.architeture.demo.UserName] at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound (GenericConversionService.java:322) at org.springframework.core.convert.support.GenericConversionService.convert (GenericConversionService.java:195) at org.springframework.core.convert.support.GenericConversionService.convert (GenericConversionService.java:175) at org.springframework.data.repository.query.ResultProcessor$ProjectingConverter. Convert (ResultProcessor.java:309) at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and$0 (ResultProcessor.java:225) at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert (ResultProcessor.java:236) at org.springframework.data.repository.query.ResultProcessor.processResult (ResultProcessor.java:156) at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute (AbstractJpaQuery.java:158) at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute (AbstractJpaQuery.java:143)
Get the location org.springframework.core.convert.support.GenericConversionService#getConverter of the converter by looking at the source code
@ Nullableprotected GenericConverter getConverter (TypeDescriptor sourceType, TypeDescriptor targetType) {ConverterCacheKey key = new ConverterCacheKey (sourceType, targetType); GenericConverter converter = this.converterCache.get (key); if (converter! = null) {return (converter! = NO_MATCH? Converter: null);} converter = this.converters.find (sourceType, targetType); if (converter = = null) {converter = getDefaultConverter (sourceType, targetType);} if (converter! = null) {this.converterCache.put (key, converter); return converter;} this.converterCache.put (key, NO_MATCH); return null;}
Continue to look at the source code to find the location where you can join the converter converter = this.converters.find (sourceType, targetType)
@ Nullablepublic GenericConverter find (TypeDescriptor sourceType, TypeDescriptor targetType) {/ / Search the full type hierarchy / / get List > targetCandidates = getClassHierarchy (targetType.getType ()); for (Class sourceCandidate: sourceCandidates) {for (Class targetCandidate: targetCandidates) {ConvertiblePair convertiblePair = new ConvertiblePair (sourceCandidate, targetCandidate); GenericConverter converter = getRegisteredConverter (sourceType, targetType, convertiblePair); if (converter! = null) {return converter } return null;}
This method combines the source object TupBackedMap parent class or interface with the UserName parent class or interface to get the corresponding converter
Parent class or interface of TupBackedMap
Org.springframework.core.convert.support.GenericConversionService#addConverter (org.springframework.core.convert.converter.GenericConverter)
@ Nullableprivate GenericConverter getRegisteredConverter (TypeDescriptor sourceType, TypeDescriptor targetType, ConvertiblePair convertiblePair) {/ / Check specifically registered converters ConvertersForPair convertersForPair = this.converters.get (convertiblePair); if (convertersForPair! = null) {GenericConverter converter = convertersForPair.getConverter (sourceType, targetType); if (converter! = null) {return converter }} / / Check ConditionalConverters for a dynamic match for (GenericConverter globalConverter: this.globalConverters) {if (ConditionalConverter) globalConverter) .sourceType, targetType) {return globalConverter;}} return null;}
You can see that in ConvertersForPair convertersForPair = this.converters.get (convertiblePair); add a converter in convertes
Org.springframework.core.convert.support.GenericConversionService.Converters
Private static class Converters {private final Map converters = new LinkedHashMap (36); public void add (GenericConverter converter) {}}
Check the location of the call to the add method, where org.springframework.core.convert.support.GenericConversionService#addConverter (org.springframework.core.convert.converter.GenericConverter) is finally located
That's all for "what's the simplest way for Spring Data Jpa native SQL to return custom objects?" Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.