বসন্ত-ডেটা-জেপিএ টীকা দেওয়ার জন্য সেটম্যাক্সের ফলাফল?


127

আমি আমার প্রকল্পে স্প্রিং-ডেটা-জেপিএ অন্তর্ভুক্ত করার চেষ্টা করছি। আমাকে বিভ্রান্ত করার একটি জিনিস হ'ল আমি টীকা দ্বারা কীভাবে setMaxResults (n) অর্জন করব?

উদাহরণস্বরূপ, আমার কোড:

public interface UserRepository extends CrudRepository<User , Long>
{
  @Query(value="From User u where u.otherObj = ?1 ")
  public User findByOhterObj(OtherObj otherObj);
}

আমার কেবল অন্যান্য one (and only one)ওজেজে থেকে ব্যবহারকারী ফিরে আসতে হবে তবে আমি সর্বোচ্চ ফলাফলগুলি টিকিয়ে দেওয়ার কোনও উপায় খুঁজে পাচ্ছি না। কেউ কি আমাকে ইঙ্গিত দিতে পারে?

(মাইএসকিএল অভিযোগ করে:

com.mysql.jdbc.JDBC4PreparedStatement@5add5415: select user0_.id as id100_, user0_.created as created100_ from User user0_ where user0_.id=2 limit ** NOT SPECIFIED **
WARN  util.JDBCExceptionReporter - SQL Error: 0, SQLState: 07001
ERROR util.JDBCExceptionReporter - No value specified for parameter 2

)

আমি একটি লিঙ্ক পেয়েছি: https://jira.springsource.org/browse/DATAJPA-147 , আমি চেষ্টা করেছি কিন্তু ব্যর্থ হয়েছিল। এটা কি এখন সম্ভব হচ্ছে না? স্প্রিং-ডেটাতে এ জাতীয় গুরুত্বপূর্ণ বৈশিষ্ট্যটি কেন নির্মিত হয়নি?

যদি আমি নিজেই এই বৈশিষ্ট্যটি প্রয়োগ করি:

public class UserRepositoryImpl implements UserRepository

আমাকে প্রচুর পূর্বনির্ধারিত পদ্ধতি প্রয়োগ CrudRepositoryকরতে হবে, এটি ভয়ানক হবে।

পরিবেশ: স্প্রিং -৩.১, স্প্রিং-ডেটা-জেপা-১.০.৩.আরএলইএসই.জার, স্প্রিং-ডেটা-কমন্স-কোর -১.১.০.আরলেএএসই.জার

উত্তর:


176

স্প্রিং ডেটা জেপিএ ১.7.০ হিসাবে (ইভান্স রিলিজ ট্রেন)।

আপনি সদ্য চালু হওয়া Topএবং Firstকীওয়ার্ডগুলি ব্যবহার করতে পারেন যা আপনাকে কোয়েরি পদ্ধতিগুলি এভাবে সংজ্ঞায়িত করতে দেয়:

findTop10ByLastnameOrderByFirstnameAsc(String lastname);

স্প্রিং ডেটা ফলাফলগুলি স্বয়ংক্রিয়ভাবে আপনার সংখ্যায় সংখ্যায় সীমাবদ্ধ করবে (বাদ দিলে ডিফল্টে 1) to নোট করুন যে ফলাফলের ক্রমটি এখানে প্রাসঙ্গিক হয়ে ওঠে (হয় OrderByউদাহরণ হিসাবে দেখা একটি ধারা দ্বারা বা Sortপদ্ধতিতে একটি পরামিতি হস্তান্তর করে )। স্প্রিং ডেটা ইভান্স রিলিজ ট্রেনের নতুন বৈশিষ্ট্যগুলি বা ডকুমেন্টেশনে ব্লগ পোস্টে আরও পড়ুন ।

পূর্ববর্তী সংস্করণগুলির জন্য

কেবলমাত্র ডেটার টুকরো পুনরুদ্ধার করতে, স্প্রিং ডেটা পৃষ্ঠাগুলি বিমূর্তি ব্যবহার করে যা Pageableঅনুরোধকারী পক্ষের ইন্টারফেসের পাশাপাশি Pageজিনিসগুলির ফলাফলের দিক থেকে বিমূর্তি ব্যবহার করে। সুতরাং আপনি দিয়ে শুরু করতে পারে

public interface UserRepository extends Repository<User, Long> {

  List<User> findByUsername(String username, Pageable pageable);
}

এবং এটি এর মতো ব্যবহার করুন:

Pageable topTen = new PageRequest(0, 10);
List<User> result = repository.findByUsername("Matthews", topTen);

যদি আপনার ফলাফলের প্রসঙ্গটি জানতে হয় (আসলে এটি কোন পৃষ্ঠাটি? এটিই প্রথমটি? মোট কতজন আছে?), Pageফেরতের প্রকার হিসাবে ব্যবহার করুন :

public interface UserRepository extends Repository<User, Long> {

  Page<User> findByUsername(String username, Pageable pageable);
}

ক্লায়েন্ট কোডটি এর পরে এমন কিছু করতে পারে:

Pageable topTen = new PageRequest(0, 10);
Page<User> result = repository.findByUsername("Matthews", topTen);
Assert.assertThat(result.isFirstPage(), is(true));

আপনি যে Pageরিটার্ন টাইপ হিসাবে ব্যবহার করেন সেই ক্ষেত্রে মেটাডেটা গণনা করার জন্য মোট কতগুলি উপাদান রয়েছে তা আমাদের খুঁজে বের করার প্রয়োজনে আসল ক্যোয়ারির একটি গণনা প্রক্ষেপণকে ট্রিগার করব না। এর বাইরেও, নিশ্চিত হয়ে নিন যে আপনি PageRequestস্থিতিশীল ফলাফল পাওয়ার জন্য বাছাই করা তথ্য দিয়ে আসলে সজ্জিত করেছেন । অন্যথায় আপনি কোয়েরিটি দুবার ট্রিগার করতে পারেন এবং নীচের ডেটা পরিবর্তন না করেও বিভিন্ন ফলাফল পেতে পারেন।


14
ধন্যবাদ, তবে আমি এখনও 'টীকা ভিত্তিক' সমাধানের আশা করি। কারণ 'পৃষ্ঠা / পৃষ্ঠাযোগ্য' এই ক্ষেত্রে খুব বেশি ওভারকিল are এবং ক্লায়েন্টকে 'এক এবং একমাত্র' ফলাফল পুনরুদ্ধার করার জন্য একটি পৃষ্ঠযোগ্য / পৃষ্ঠা তৈরি করতে হবে ... এটি ব্যবহারের পক্ষে খুব বন্ধুত্বপূর্ণ। এবং মনে হচ্ছে আপনি স্প্রিং-ডেটার দায়িত্বে রয়েছেন, আমি আশা করি আপনি আরও এই সমস্যাটি দেখতে পারবেন: স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 9276461/… । আপনি কি নিশ্চিত করতে পারেন যে এটি স্প্রিং-ডেটার বাগ রয়েছে?
স্মার্টুফো

1
+ এটি কাজ করে, ধন্যবাদ তবে একটি টিকা-ভিত্তিক সমাধান নতুন সংস্করণে আরও ভাল হবে
আজেফরাতি

1
এখানে একটি গণনা কোয়েরি বরখাস্ত করা হয়েছে যা আমরা যদি একটি সীমাবদ্ধ জিজ্ঞাসা চাই তবে এটি সম্পূর্ণ অপ্রয়োজনীয়।
আজেরাফতি

1
আপনি যদি Listপদ্ধতিটির রিটার্ন টাইপ হিসাবে ব্যবহার করেন তবে তা নয় ।
অলিভার ড্রটবহম

3
আমি মনে করি, Topএবং Firstকীওয়ার্ডগুলি @Queryটীকাগুলি ব্যবহার করা পদ্ধতিগুলির জন্য প্রযোজ্য নয় ? কেবল যারা, পদ্ধতি-নাম-ভিত্তিক ক্যোয়ারী জেনারেশন ব্যবহার করে?
রুসলান স্টেলমাচেনকো

106

আপনি যদি জাভা 8 এবং স্প্রিং ডেটা 1.7.0 ব্যবহার করছেন তবে আপনি @Queryসর্বাধিক ফলাফল নির্ধারণের সাথে কোনও টিকাটি একত্রিত করতে চাইলে আপনি ডিফল্ট পদ্ধতিগুলি ব্যবহার করতে পারেন :

public interface UserRepository extends PagingAndSortingRepository<User,Long> {
  @Query("from User u where ...")
  List<User> findAllUsersWhereFoo(@Param("foo") Foo foo, Pageable pageable);

  default List<User> findTop10UsersWhereFoo(Foo foo) {
    return findAllUsersWhereFoo(foo, new PageRequest(0,10));
  }

}

3
একক ফলাফলের জন্য সম্ভাব্যভাবে কার্যকরStream<User> ... {...} default Optional<User> ... { ...findAny() }
xenoterracide

28

নিম্নলিখিত উপায়গুলির মতো আপনি "টীকা দ্বারা একটি সেটম্যাক্সারসাল্টস (এন)" এর সমতুল্য সরবরাহ করতে পারেন:

public interface ISomething extends JpaRepository<XYZ, Long>
{
    @Query("FROM XYZ a WHERE a.eventDateTime < :before ORDER BY a.eventDateTime DESC")
    List<XYZ> findXYZRecords(@Param("before") Date before, Pageable pageable);
}

যখন কোনও পৃষ্ঠাযোগ্য পরামিতি হিসাবে প্রেরণ করা হয় তখন এই কৌশলটি করা উচিত। উদাহরণস্বরূপ প্রথম 10 টি রেকর্ড আনার জন্য আপনাকে এই মানটির জন্য পৃষ্ঠযোগ্য সেট করতে হবে:

new PageRequest(0, 10)

আপনি যদি প্যাগেবল ব্যবহার করছেন তবে এর ফিরতি পৃষ্ঠা <XYZ> তালিকা <XYZ> নয়
অরুণদেব

@ অরনদেব ভুল - Listপুরোপুরি কাজ করে (এবং পূর্ববর্তী মন্তব্যেcount ইতিমধ্যে উল্লিখিত একটি অপ্রয়োজনীয় জিজ্ঞাসা এড়ানো )
জনক বান্দারা

21

স্প্রিং ডেটা ইভান্স ব্যবহার করুন (1.7.0 রিলিজ)

স্প্রিং ডেটা জেপিএর নতুন প্রকাশের সাথে মডিউলগুলির অন্য তালিকাগুলির সাথে একত্রে ইভান্স নামে পরিচিত হ'ল কীওয়ার্ড Top20এবং ব্যবহারের বৈশিষ্ট্য রয়েছেFirst , ক্যোয়ারী ফলাফলের সীমিত করতে

সুতরাং আপনি এখন লিখতে পারে

List<User> findTop20ByLastname(String lastname, Sort sort);

অথবা

List<User> findTop20ByLastnameOrderByIdDesc(String lastname);

বা একক ফলাফলের জন্য

List<User> findFirstByLastnameOrderByIdDesc(String lastname);

5
<চ্ছিক <ব্যবহারকারীর সন্ধান করুনফার্সবাইলাস্টনেম অর্ডারবাইআইডিডেস্ক (স্ট্রিং লাস্টনেম);
krmanish007

শীর্ষ ২০ ফলাফল পাওয়ার পরে, পৃষ্ঠা পৃষ্ঠাটি ব্যবহার করে ওয়েবসাইটে পরবর্তী পৃষ্ঠায় গেলে আমি কীভাবে পরবর্তী 20 ফলাফল পাব?
কিট্টু

@ কিট্টু, অবশ্যই এটি অন্য একটি প্রশ্ন তবে আপনাকে একটি Pageableবিষয় পাস করতে হবে । বসন্তের ডকুমেন্টেশনগুলি দেখুন
আজফরাফি

তারা প্রথমে নির্দিষ্ট করে যদি পদ্ধতিটিকে একটি জঘন্য তালিকা ফিরিয়ে দেয় কেন ??
ভ্যাসাইল সুরদু

13

আমার জন্য সেরা পছন্দটি হল দেশীয় ক্যোয়ারী:

@Query(value="SELECT * FROM users WHERE other_obj = ?1 LIMIT 1", nativeQuery = true)
User findByOhterObj(OtherObj otherObj);

হাইবারনেটটিতে সীমাটি সমর্থন করা হয়েছে কিনা তা নিশ্চিত নয়: ফোরাম.হিবারনেট.আর্গ
ভিউটোপিক.ফ্প? ফ=

2
পুরো ধারণাটি ভেঙে দেয়! পরিবর্তে সত্তা ম্যানেজার ব্যবহার করুন!
স্পেকটাকুলটিয়াস

@ কোড.IT আমি কেআইএসএস ধারণাটি প্রচার করি। এ ছাড়া JPA nativeQuery টিকা প্যারামিটার উপেক্ষা করার জন্য যোগ করা হয়নি।
গ্রিগরি কিসলিন

@GKislin- এর চেয়ে আপনার নামটির নামকরণের মতো FindLimitOneByOtherObj করতে হবে। এছাড়াও আপনি একটি অর্ডারবাই যুক্ত করতে ভুলে গেছেন যা অন্য_বজ অনন্য না হলে ভুল ফলাফলের দিকে নিয়ে যায়। অন্যথায় যেখানে অনন্য কলামে বিবৃতি সীমা ছাড়াই যথেষ্ট হওয়া উচিত
স্পেকটাকুলটিয়াস

সীমাবদ্ধ কীওয়ার্ড হাইবারনেট নয় তবে
পোস্টগ্রিস

5

যদি আপনার শ্রেণি @Repositoryপ্রসারিত হয় JpaRepositoryআপনি নীচের উদাহরণটি ব্যবহার করতে পারেন।

int limited = 100;
Pageable pageable = new PageRequest(0,limited);
Page<Transaction> transactionsPage = transactionRepository.findAll(specification, pageable);
return transactionsPage.getContent();

getContent রিটার্ন a List<Transaction>


যদি আমার 2 টি থাকে যেখানে ক্যোয়ারির মতো শর্তগুলির মতো ট্রানজেকশনরপোজিটরি.ফাইন্ডবাই ফার্স্টনাম এবং লাস্টনেম (প্রথম নাম, পদবি)? এটা কি কাজ করবে ? আমি এই ব্যতিক্রমটি org.springframework.data.mapping.PropertyReferencesException পেয়ে যাচ্ছি: টাইপ বোর্ডের জন্য কোনও সম্পত্তি তৈরির সন্ধান পাওয়া যায় নি।
শৈলেশ

4

এটি @ কুইরিহিন্টস ব্যবহার করেও সুস্পষ্ট। নমুনা উদাহরণস্বরূপ org.eclipse.persistance.config.QueryHints # JDBC_MAX_ROWS ব্যবহার করে

@Query("SELECT u FROM User u WHERE .....")
@QueryHints(@QueryHint(name = JDBC_MAX_ROWS, value = "1"))
Voter findUser();

আমি এই কোডটি পরীক্ষা করেছি কিন্তু এটি কাজ করছে না। কোনও ব্যতিক্রম নয়, তবে কোনও সঠিক ফলাফলের দম্পতি নেই। এছাড়াও ডকুমেন্টেশন ক্যোরিহিন্টস সম্পর্কে খুব পাতলা। নিচে দেখ. docs.spring.io/spring-data/jpa/docs/1.7.1.RELEASE/references/…
বোগদান.রাসু

আইআইআরসি, এমন কোনও গ্যারান্টি নেই যে কোনও প্রশ্নের ইঙ্গিত অনুসরণ করা হবে। এটি বাস্তবায়নের জন্য "বন্ধুত্বপূর্ণ সুপারিশগুলি" পাশ করার কেবল একটি উপায়।
প্রিয়দু নিমরে

আমি এটি @QueryHints({@QueryHint(name = org.hibernate.annotations.FETCH_SIZE, value = "1")})হাইবারনেটে চেষ্টা করে দেখি , তবে ওরফে :( কাজ করে না
গ্রিগরি কিসলিন

2
org.hibernate.annotations.FETCH_SIZE এর আনার আকার, এটির সীমা নেই, সর্বোচ্চ ফলাফল নয়। Hiber নাকিসুরে কথা
Zhuravskiy Vitaliy

4

new PageRequest(0,10)নতুন বসন্ত সংস্করণগুলিতে কাজ করে না (আমি ব্যবহার করছি 2.2.1.RELEASE)। মূলত, কনস্ট্রাক্টর Sortটাইপ হিসাবে একটি অতিরিক্ত প্যারামিটার পেয়েছিল । তদ্ব্যতীত, নির্মাণকারীর কাজটি protectedতাই এটির একটিতে আপনার চাইল্ড ক্লাস ব্যবহার করতে হবে বা তার ofস্থির পদ্ধতিটি কল করতে হবে :

PageRequest.of(0, 10, Sort.sort(User.class).by(User::getFirstName).ascending()))

আপনি Sortপ্যারামিটারের ব্যবহার বাদ দিতে পারেন এবং স্পষ্টতই ব্যবহারকারীকে ডিফল্ট সাজান (pk ইত্যাদি অনুসারে বাছাই করুন):

PageRequest.of(0, 10)

আপনার ফাংশন ঘোষণাটি এরকম কিছু হওয়া উচিত:

List<User> findByUsername(String username, Pageable pageable)

এবং ফাংশনটি হবে:

userRepository.findByUsername("Abbas", PageRequest.of(0,10, Sort.sort(User.class).by(User::getLastName).ascending());
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.