স্প্রিং ডেটা জেপিএ অ-সত্তা পোজোর নেটিভ ক্যোয়ারির ফলাফলকে মানচিত্র করে


92

নেটিভ ক্যোয়ারী সহ আমার কাছে একটি স্প্রিং ডেটা সংগ্রহস্থল পদ্ধতি রয়েছে

@Query(value = "SELECT g.*, gm.* FROM group g LEFT JOIN group_members gm ON g.group_id = gm.group_id and gm.user_id = :userId WHERE g.group_id = :groupId", nativeQuery = true)
    GroupDetails getGroupDetails(@Param("userId") Integer userId, @Param("groupId") Integer groupId);

এবং আমি ফলাফলটি অ-সত্তা পোজোতে মানচিত্র করতে চাই GroupDetails

এটি কি সম্ভব এবং যদি তাই হয় তবে আপনি দয়া করে একটি উদাহরণ সরবরাহ করতে পারেন?

উত্তর:


65

ওরিডের উত্তরের মতো গ্রুপডেটেলগুলি ধরে নিচ্ছেন আপনি কি জেপিএ ২.১ ব্যবহার করেছেন @ কনস্ট্রাক্টর রিসাল্ট ?

@SqlResultSetMapping(
    name="groupDetailsMapping",
    classes={
        @ConstructorResult(
            targetClass=GroupDetails.class,
            columns={
                @ColumnResult(name="GROUP_ID"),
                @ColumnResult(name="USER_ID")
            }
        )
    }
)

@NamedNativeQuery(name="getGroupDetails", query="SELECT g.*, gm.* FROM group g LEFT JOIN group_members gm ON g.group_id = gm.group_id and gm.user_id = :userId WHERE g.group_id = :groupId", resultSetMapping="groupDetailsMapping")

এবং সংগ্রহস্থল ইন্টারফেসে নিম্নলিখিত ব্যবহার করুন:

GroupDetails getGroupDetails(@Param("userId") Integer userId, @Param("groupId") Integer groupId);

স্প্রিং ডাটা JPA মতে ডকুমেন্টেশন , বসন্ত প্রথম নামে ক্যোয়ারী আপনার পদ্ধতির নাম মিলে খুঁজে পেতে চেষ্টা করবে - তাই ব্যবহার করে @NamedNativeQuery, @SqlResultSetMappingএবং @ConstructorResultআপনি যে আচরণ অর্জন করতে সক্ষম হওয়া উচিত


15
নেমডনেটিভ কিওয়ারীর সাথে বসন্তের ডেটা মেলাতে সক্ষম হওয়ার জন্য ডোমেন সত্তার ক্লাস নামটি ডট দ্বারা অনুসরণ করা হয়, নামডাইভেটিভ কিওয়ারির নামের সাথে উপসর্গ করা প্রয়োজন। সুতরাং নামটি হওয়া উচিত (ডোমেন সত্তা ধরে নেওয়া গ্রুপ) 'গ্রুপ.গ্রেটগ্রুপডেটেলস'।
অনুদান দিন

@ গ্রান্টলে আপনি এই প্রশ্নটি দেখতে পারেন : stackoverflow.com/q/44871757/7491770 আমার ঠিক এই ধরণের সমস্যা আছে।
রাম

আমি কীভাবে এই জাতীয় অবজেক্টের একটি তালিকা ফিরিয়ে দেব?
নিখিল সাহু

4
এটি কাজ করতে, GroupDetailsদিয়ে চিহ্নিত করা উচিত @Entity? যদি সম্ভব হয় তবে দয়া করে বলতে পারেন যে টীকাটি @NamedNativeQueryপ্রয়োগ করতে হবে কোন শ্রেণিতে ?
মানু

4
@SqlResultSetMappingএবং @NamedNativeQueryআপনার স্প্রিং ডেটা রিপোজিটরিতে ব্যবহৃত সংস্থার উপর টীকা অবশ্যই উপস্থিত থাকতে হবে (উদাহরণস্বরূপ public interface CustomRepository extends CrudRepository<CustomEntity, Long>এটি CustomEntityশ্রেণিটি)
টমাসজ ডব্লিউ

112

আমি মনে করি এটি করার সবচেয়ে সহজ উপায় হ'ল তথাকথিত অভিক্ষেপ ব্যবহার করা। এটি ইন্টারফেসে ক্যোয়ারির ফলাফলগুলি ম্যাপ করতে পারে। ব্যবহার SqlResultSetMappingকরা অসুবিধাজনক এবং আপনার কোডটিকে কুৎসিত করে তোলে :)।

বসন্তের তথ্য জেপিএ উত্স কোড থেকে সরাসরি একটি উদাহরণ:

public interface UserRepository extends JpaRepository<User, Integer> {

   @Query(value = "SELECT firstname, lastname FROM SD_User WHERE id = ?1", nativeQuery = true)
   NameOnly findByNativeQuery(Integer id);

   public static interface NameOnly {

     String getFirstname();

     String getLastname();

  }
}

আপনি অনুমানগুলির একটি তালিকা পেতে এই পদ্ধতিটিও ব্যবহার করতে পারেন।

অনুমান সম্পর্কে আরও তথ্যের জন্য এই বসন্তের ডেটা জেপিএ ডক্স এন্ট্রি দেখুন।

নোট 1:

আপনার Userসত্তাকে স্বাভাবিক হিসাবে সংজ্ঞায়িত করা মনে রাখবেন - অনুমান করা ইন্টারফেসের ক্ষেত্রগুলি অবশ্যই এই সত্তার ক্ষেত্রগুলির সাথে মেলে। অন্যথায় ফিল্ড ম্যাপিংটি ভেঙে যেতে পারে ( getFirstname()শেষ নাম এবং সেটেরার মান ফিরে আসতে পারে)।

নোট 2:

আপনি যদি SELECT table.column ...স্বরলিপি ব্যবহার করেন তবে সর্বদা সত্তার থেকে নামগুলির সাথে মিলে যাওয়া নামগুলি সংজ্ঞায়িত করুন। উদাহরণস্বরূপ এই কোডটি সঠিকভাবে কাজ করবে না (প্রজেকশন প্রতিটি প্রাপ্তির জন্য নাল ফেরায়):

@Query(value = "SELECT user.firstname, user.lastname FROM SD_User user WHERE id = ?1", nativeQuery = true)
NameOnly findByNativeQuery(Integer id);

তবে এটি কাজ করে:

@Query(value = "SELECT user.firstname AS firstname, user.lastname AS lastname FROM SD_User user WHERE id = ?1", nativeQuery = true)
NameOnly findByNativeQuery(Integer id);

আরও জটিল প্রশ্নের ক্ষেত্রে আমি JdbcTemplateপরিবর্তে কাস্টম সংগ্রহস্থল ব্যবহার করব।


এটি একটি পরিষ্কার সমাধান। আমি যাচাই করেছিলাম তবে স্কেলআরসাল্টস্যাপ্যাপিং ব্যবহারের চেয়ে পারফরম্যান্সটি আরও খারাপ (এটি প্রায় 30-40% :( ধীর)
কিডনান 1991

সুন্দরভাবে কাজ করে! আপনি যদি অন্য কোথাও এটি ব্যবহার করতে চান তবে ইন্টারফেসটিকে সর্বজনীন করুন
tibi

আপনি যদি এক্সএমএল টাইপ (ক্লাব) ক্ষেত্রটি বের করতে চান তবে কাজ করে না। যেকোনো পরামর্শ?
আশীষ

@ আশিশের পরিবর্তে আমি এর পরিবর্তে JdbcTemplate( ডকস.স্প্রিং.আইও / স্প্রিং-ফ্রেমওয়ার্ক / ডকস / সারেন্ট / জাভাদোক- এপি / অর্গ / ৮ ) ব্যবহার করব। চশমা আনতে আপনি getClobপদ্ধতিটি ব্যবহার করতে পারেন । একটি উদাহরণস্বরূপ: । resultSetInputStreamrs.getClob("xml_column").getCharacterStream()
মাইখা স্টোকমাল

আমি যদি ক্যোয়ারীতে SELECT * ব্যবহার করি এবং কোয়েরিটি একটি স্থানীয়?
সালমান কাজমী

17

আমার মনে হয় মিশেলের এপ্রোচ আরও ভাল। তবে, ফলাফলটি নেটিভ ক্যোয়ারী থেকে বের করার আরও একটি উপায় রয়েছে।

@Query(value = "SELECT g.*, gm.* FROM group g LEFT JOIN group_members gm ON g.group_id = gm.group_id and gm.user_id = :userId WHERE g.group_id = :groupId", nativeQuery = true)
String[][] getGroupDetails(@Param("userId") Integer userId, @Param("groupId") Integer groupId);

এখন, আপনি এই 2D স্ট্রিং অ্যারেটিকে আপনার পছন্দসই সত্তায় রূপান্তর করতে পারেন।


4
সহজ এবং মার্জিত
জন

9

আপনি নিজের আদি বা অ-নেটিভ ক্যোয়ারীটি আপনার পছন্দ মতো লিখতে পারেন এবং কাস্টম রেজাল্ট ক্লাসগুলির উদাহরণ সহ আপনি জেপিকিউএল কোয়েরি ফলাফলগুলি মোড়ানো করতে পারেন। ক্যোরিয়ায় ফিরে আসা একই কলামগুলির একই নামের সাথে একটি ডিটিও তৈরি করুন এবং একই ক্রম এবং ক্যোয়ারির দ্বারা ফিরে আসা নামগুলির সাথে একটি সমস্ত আর্গুমেন্ট কনস্ট্রাক্টর তৈরি করুন। তারপরে ডাটাবেসটি অনুসন্ধান করার জন্য নিম্নলিখিত পদ্ধতি ব্যবহার করুন।

@Query("SELECT NEW example.CountryAndCapital(c.name, c.capital.name) FROM Country AS c")

ডিটিও তৈরি করুন:

package example;

public class CountryAndCapital {
    public String countryName;
    public String capitalName;

    public CountryAndCapital(String countryName, String capitalName) {
        this.countryName = countryName;
        this.capitalName = capitalName;
    }
}

সংশোধন: একই নামগুলি বাধ্যতামূলক নয় ... কেবলমাত্র কনস্ট্রাক্টরের প্যারামিটারগুলির একই ক্রম এবং ফলাফল ফলাফলের সেট।
ওয়াকাস মেমন

এটি কেবল তখন কাজ করে যদি দেশটি আপনার জাভা সত্তা শ্রেণি। এটি যদি আপনার জাভা সত্তা শ্রেণি না হয় তবে এটি হবে না।
যশবন্ত কাকাদ

4
আপনি বলছেন যে এগুলিও দেশীয় প্রশ্নের সাথে কাজ করা উচিত? আপনি একটি উদাহরণ দিতে পারেন?
রিচার্ড টিঙ্গল

ওপি নেটিভ কোয়েরি জিজ্ঞাসা করে, তবে প্রদত্ত উদাহরণটি একটি অ-নেটিভ
সিএলএস

0

আপনি যেমন কিছু করতে পারেন

@NamedQuery(name="IssueDescriptor.findByIssueDescriptorId" ,

    query=" select new com.test.live.dto.IssuesDto (idc.id, dep.department, iss.issueName, 
               cat.issueCategory, idc.issueDescriptor, idc.description) 
            from Department dep 
            inner join dep.issues iss 
            inner join iss.category cat 
            inner join cat.issueDescriptor idc 
            where idc.id in(?1)")

এবং অবশ্যই কনস্ট্রাক্টর থাকতে হবে

public IssuesDto(long id, String department, String issueName, String issueCategory, String issueDescriptor,
            String description) {
        super();
        this.id = id;
        this.department = department;
        this.issueName = issueName;
        this.issueCategory = issueCategory;
        this.issueDescriptor = issueDescriptor;
        this.description = description;
    }

13
প্রশ্নটি এইচকিউএল-এ লেখা কোয়েরি নয়, দেশীয় প্রশ্নের সম্পর্কে eries
ডিবিকে 14 '

-5

আমার কম্পিউটারে, আমি এই কোডটি পেয়েছি। এটি ডাইমনের উত্তর থেকে কিছুটা আলাদা।

@SqlResultSetMapping(
    name="groupDetailsMapping",
    classes={
        @ConstructorResult(
            targetClass=GroupDetails.class,
            columns={
                @ColumnResult(name="GROUP_ID",type=Integer.class),
                @ColumnResult(name="USER_ID",type=Integer.class)
            }
        )
    }
)

@NamedNativeQuery(name="User.getGroupDetails", query="SELECT g.*, gm.* FROM group g LEFT JOIN group_members gm ON g.group_id = gm.group_id and gm.user_id = :userId WHERE g.group_id = :groupId", resultSetMapping="groupDetailsMapping")

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.