جاوا و تکنولوژی های آن

java programming language

در این وبلاگ به بررسی نکات موجود در جاوا و تکنولوژی های آن می پردازیم

طبقه بندی موضوعی


در ابتدا نگاهی میکنیم به کلمات کلیدی که میتوان با آن کوئری ایجاد کرد و بعد به استفاده از Query@ و name و parameter میپردازیم 



فرض کنید یک جدول بنام Movie و یک کلاس Entity به همین نام داریم :


@Entity
public class Movie {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;
    private String title;
    private String director;
    private String rating;
    private int duration;
 
    // standard getters and setters
}


و یکسری نمونه از آن ذخیره میکنیم :


INSERT INTO movie(id, title, director, rating, duration) 
    VALUES(1, 'Godzilla: King of the Monsters', ' Michael Dougherty', 'PG-13', 132);
INSERT INTO movie(id, title, director, rating, duration) 
    VALUES(2, 'Avengers: Endgame', 'Anthony Russo', 'PG-13', 181);
INSERT INTO movie(id, title, director, rating, duration) 
    VALUES(3, 'Captain Marvel', 'Anna Boden', 'PG-13', 123);
INSERT INTO movie(id, title, director, rating, duration) 
    VALUES(4, 'Dumbo', 'Tim Burton', 'PG', 112);
INSERT INTO movie(id, title, director, rating, duration) 
    VALUES(5, 'Booksmart', 'Olivia Wilde', 'R', 102);
INSERT INTO movie(id, title, director, rating, duration) 
    VALUES(6, 'Aladdin', 'Guy Ritchie', 'PG', 128);
INSERT INTO movie(id, title, director, rating, duration) 
    VALUES(7, 'The Sun Is Also a Star', 'Ry Russo-Young', 'PG-13', 100);



حال ببینیم برای پیدا کردن فیلم مورد نظر و کوئری آن چه راه کار هایی داریم :


ابتدا با چند کلمه کلیدی آشنا شویم :


- Containing

- Contains

- IsContaining

- Like


این کلمات کلیدی توسط Spring شناخته شده هستند و میتوانیم در Repository از آنها برای ایجاد متد های Repository استفاده کنیم 



کوئری Like زیر در در نظر بگیرید :

SELECT * FROM movie WHERE title LIKE '%in%';


حال متدهایی برای استفاده از کلمات کلیدی تعریف میکنیم که Spring آنها را میشناسد و برای ما در پشت پرده پیاده سازی میکند :


List<Movie> findByTitleContaining(String title);
List<Movie> findByTitleContains(String title);
List<Movie> findByTitleIsContaining(String title);


حالا میتوانیم از این متد ها استفاده کنیم :


List<Movie> results = movieRepository.findByTitleContaining("in");
assertEquals(3, results.size());
 
results = movieRepository.findByTitleIsContaining("in");
assertEquals(3, results.size());
 
results = movieRepository.findByTitleContains("in");
assertEquals(3, results.size());


*میتوان انتطار داشت که هر یک از این سه متد جوابی مشابه هم داشته باشند 



اما کلمه کلیدی Like جا موند ، Spring همچنین این کلمه کلیدی را میشناسد ولی میتواند رفتاری متفاوت داشته باشد چون میتوانیم از wildcard استفاده کنیم 


شکل  کلی :


List<Movie> findByTitleLike(String title);


و استفاده از آن همراه با wildcard :


results = movieRepository.findByTitleLike("%in%");
assertEquals(3, results.size());



شکل دیگری استفاده از wildcard با استفاده از کلمه کلیدی StartsWith :


List<Movie> findByRatingStartsWith(String rating);

با استفاده از StartsWith میتوانیم کوئری مشابه زیر را استفاده کنیم :

SELECT * FROM Movie WHERE Rating LIKE 'PG%';

و تست استفاده از آن :

List<Movie> results = movieRepository.findByRatingStartsWith("PG");
assertEquals(6, results.size());



برعکس StartsWith که با استفاده از کلمه کلیدی EndsWith میباشد :


SELECT * FROM Movie WHERE director LIKE '%Burton';
List<Movie> findByDirectorEndsWith(String director);
List<Movie> results = movieRepository.findByDirectorEndsWith("Burton");
assertEquals(1, results.size());




کلمه کلیدی IgnoreCase برای مواقعی که میخواهیم در کوئری بزرگ و کوچک بودن حروف را نادیده بگیرد :


List<Movie> findByTitleContainingIgnoreCase(String title);
List<Movie> results = movieRepository.findByTitleContainingIgnoreCase("the");
assertEquals(2, results.size());




ترکیب کوئری های جستجو با NOT برای مواقعی که میخواهیم نتیجه به غیر از شرایط ذکر شده باشد :


ما میتوانیم Not را بصورت NotContains, NotContaining, NotLike استفاده کنیم 

List<Movie> findByRatingNotContaining(String rating);
List<Movie> results = movieRepository.findByRatingNotContaining("PG");
assertEquals(1, results.size());


List<Movie> findByDirectorNotLike(String director);
List<Movie> results = movieRepository.findByDirectorNotLike("An%");
assertEquals(5, results.size());




استفاده از Query@ :


گاهی اوقات کوئری ما پیچیدگی زیادی دارد و پارامتر هایی را به عنوان ورودی دریافت میکند و نیاز داریم آنرا بصورت سفارشی طراحی کنیم و روی یک متد تعریف کنیم 


Named Parameter :


پارامتر هایی هستند که با نام مشخص میشوند و هم نام فیلد مورد نظر در کلاس Entity است 


@Query("SELECT m FROM Movie m WHERE m.title LIKE %:title%")
List<Movie> searchByTitleLike(@Param("title") String title);

* به سینتکس دو نقطه ':' قبل از Named Parameter توجه کنید 

در این کوئری از wildcard هم استفاده شده است

این کوئری مشابه متد findByTitleContaining  که قبلا صحبت کردیم رفتار میکند که با Query@ پیاده سازی شده



Ordered Parameter :


پارامتر هایی هستند که بر اساس شماره الویت بندی شده اند و طبق آرگومان های ورودی متد نیز جای گزاری میشوند 


@Query("SELECT m FROM Movie m WHERE m.rating LIKE ?1%")
List<Movie> searchByRatingStartsWith(String rating);

* به سینتکس ? و بعد یک عدد بعد از علامت سوال دقت کنید

این کوئری مشابه findByRatingStartsWith است که قبلا بحث شد و از wildcard هم استفاده شده


تست آن :

List<Movie> results = movieRepository.searchByRatingStartsWith("PG");
assertEquals(6, results.size());


** هنگامی که ما از Ordered Parameter استفاده میکنیم باید احتیاط کنیم چون ورودی که به عنوان پارامتر جای گزاری میشود از نظر SQL Injection چک نمیشود و میتواند بسیار خطرناک باشد برای همین میتوانیم از escape method در SpeL استفاده کنیم


اگر از Spring Boot 2.4.1 به بعد استفاده میکنید میتوانیم از SpEL استفاده کنیم و خطر SQL Injection را پوشش دهیم


@Query("SELECT m FROM Movie m WHERE m.director LIKE %?#{escape([0])} escape ?#{escapeCharacter()}")
List<Movie> searchByDirectorEndsWith(String director);


تست :

List<Movie> results = movieRepository.searchByDirectorEndsWith("Burton");
assertEquals(1, results.size());







نظرات  (۰)

هیچ نظری هنوز ثبت نشده است

ارسال نظر

ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی