স্প্রিংয়ের জেডিবিসিটিম্প্লেট কার্যকরভাবে ইন () এসকিউএল কোয়েরিগুলি কীভাবে কার্যকর করা যায়?


177

আমি ভাবছিলাম যে স্প্রিংয়ের জেডিবিসিটিপিলেটের সাথে আইএন () অনুসন্ধানগুলি করার আরও বেশি মার্জিত উপায় আছে কিনা। বর্তমানে আমি এরকম কিছু করি:

StringBuilder jobTypeInClauseBuilder = new StringBuilder();
for(int i = 0; i < jobTypes.length; i++) {
    Type jobType = jobTypes[i];

    if(i != 0) {
        jobTypeInClauseBuilder.append(',');
    }

    jobTypeInClauseBuilder.append(jobType.convert());
}

যা বেশ বেদনাদায়ক কারণ যদি আমার কাছে কেবল আইএন () ক্যোয়ারীর জন্য ধারাটি তৈরি করার জন্য নয়টি লাইন থাকে। আমি প্রস্তুত বিবৃতিগুলির পরামিতি প্রতিস্থাপনের মতো কিছু পেতে চাই

উত্তর:


275

আপনি একটি প্যারামিটার উত্স চান:

Set<Integer> ids = ...;

MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("ids", ids);

List<Foo> foo = getJdbcTemplate().query("SELECT * FROM foo WHERE a IN (:ids)",
     parameters, getRowMapper());

এটি কেবল তখনই কাজ করে যদি getJdbcTemplate()টাইপের কোনও উদাহরণ দেয়NamedParameterJdbcTemplate


5
নিখুঁত, নেমডপ্যারামিটারজেডিবিসিটিম্পলেটটি ঠিক আমি যা খুঁজছিলাম। অতিরিক্তভাবে আমি সমস্ত জায়গা জুড়ে এই প্রশ্ন চিহ্নগুলির চেয়ে বেশি পরামিতি পছন্দ করি। অনেক ধন্যবাদ!
মালাক্স

5
এটি ছোট তালিকার জন্য কাজ করে, তবে এটি একটি বৃহত তালিকায় এটি ব্যবহারের চেষ্টা করে যেখানে একটি কোয়েরিতে ফলাফল: আইডিকে "?,?,?,?,? ......" দিয়ে প্রতিস্থাপন করা হয়েছে এবং পর্যাপ্ত তালিকার আইটেমগুলির সাথে এটি উপচে পড়েছে। এমন কোনও সমাধান রয়েছে যা বড় তালিকাগুলির জন্য কাজ করে?
nsayer

আপনার সম্ভবত অস্থায়ী টেবিলের মধ্যে মানগুলি সন্নিবেশ করা উচিত এবং ব্যবহার করে শর্তটি তৈরি করা উচিত WHERE NOT EXISTS (SELECT ...)
ভোর


9
আশ্চর্যজনক, আমি যখন এটি চেষ্টা করি তখন আমি "ত্রুটি কোড [17004]; অবৈধ কলামের ধরণ" পাই।
ট্রেভর

61

আমি বসন্তের jdbc এর সাথে "ইন ক্লজ" ক্যোয়ারীটি করি:

String sql = "SELECT bg.goodsid FROM beiker_goods bg WHERE bg.goodsid IN (:goodsid)";

List ids = Arrays.asList(new Integer[]{12496,12497,12498,12499});
Map<String, List> paramMap = Collections.singletonMap("goodsid", ids);
NamedParameterJdbcTemplate template = 
    new NamedParameterJdbcTemplate(getJdbcTemplate().getDataSource());

List<Long> list = template.queryForList(sql, paramMap, Long.class);

10
আপনি গ্রহণযোগ্য উত্তরের মতো একই সমাধান সহ সবেমাত্র প্রায় তিন বছরের পুরানো প্রশ্নের উত্তর পোস্ট করেছিলেন। এর পিছনে কোনও ভাল কারণ আছে কি? :-)
মাল্যাক্স

16
এই উত্তরটি আরও স্পষ্টতা সরবরাহ করে কারণ এটি চিত্রিত করে যে এই এপিআই-এর জন্য নেমডপ্যারামিটারজেডিবিসিটিম্পলেট প্রয়োজন ... তাই অতিরিক্ত বিশদ জানওয়ানের জন্য ধন্যবাদ
আইসডড্যান্ট

@ জাজেন, সমাধানের জন্য ধন্যবাদ !!! এটি আমার প্রয়োজন অনুসারে কাজ করছে !!
কার্তিক অমরনাথ সাক্রে

19

আপনি যদি এর জন্য ব্যতিক্রম পান: অবৈধ কলামের প্রকার

getNamedParameterJdbcTemplate()পরিবর্তে ব্যবহার করুনgetJdbcTemplate()

 List<Foo> foo = getNamedParameterJdbcTemplate().query("SELECT * FROM foo WHERE a IN (:ids)",parameters,
 getRowMapper());

নোট করুন যে দ্বিতীয় দুটি আর্গুমেন্ট চারপাশে বদলে গেছে।


2
এটি এই প্রশ্নের উত্তর বলে মনে হচ্ছে না। এটি অন্য উত্তরের মন্তব্য হওয়া উচিত?
ডেভ শোয়েসগুথ

2
@ ডেভসচেয়েসগুথ দু'বছর পরে, এটি অবশ্যই উত্তর হওয়ার সতর্কতা দেয়।
dwjohnston

2

পড়ুন এখানে

নামযুক্ত প্যারামিটার সহ কোয়েরি লিখুন, ListPreparedStatementSetterক্রমানুসারে সমস্ত পরামিতি সহ সহজ ব্যবহার করুন । উপলভ্য প্যারামিটারের ভিত্তিতে কোয়েরিকে traditionalতিহ্যবাহী আকারে রূপান্তর করতে কেবল নীচে স্নিপেট যুক্ত করুন,

ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(namedSql);

List<Integer> parameters = new ArrayList<Integer>();
for (A a : paramBeans)
    parameters.add(a.getId());

MapSqlParameterSource parameterSource = new MapSqlParameterSource();
parameterSource.addValue("placeholder1", parameters);
// create SQL with ?'s
String sql = NamedParameterUtils.substituteNamedParameters(parsedSql, parameterSource);     
return sql;

আমার পক্ষে এটিই একমাত্র উত্তর যা আমি কেবলমাত্র কয়েকজন স্থানধারক সেট করতে চেয়েছি কাজ করেছিল
কপিল

-4

২০০৯ সালের পর থেকে অনেক কিছুই পরিবর্তিত হয়েছে তবে আমি কেবল উত্তর পেতে পারি যে আপনাকে নেমডপ্যারামিটারজেডিবিটিসিটি ব্যবহার করতে হবে।

আমার জন্য এটি কাজ করে যদি আমি কেবল একটি করি

db.query(sql, new MyRowMapper(), StringUtils.join(listeParamsForInClause, ","));

সিম্পলজেডিবিসিটিম্প্লেট বা জেডিবিসিটিপ্লেট ব্যবহার করে


11
এই সমাধানটির সাথে সমস্যাটি হ'ল, যে সামগ্রীটি listeParamsForInClauseঅভ্যাস থেকে রক্ষা পাবে না এবং আপনাকে এসকিউএল ইঞ্জেকশনের জন্য ঝুঁকিপূর্ণ করে তুলবে।
মালাক্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.