 |
 |
| 閲覧数:2554 |
掲示板(jdbcManagerの可変条件式について) |
 |
| 名前 |
匿名
|
| 題名 |
jdbcManagerの可変条件式について
|
質問内容
質問を評価する
(0ポイント)
|
こんにちは。S2JDBCでのSQL条件式を作っているのですが、何とも汚いソースとなっており、指摘いただければと思い、投稿します。
下記のようにWhere句以降、パラメータのNullによって条件に含める、含めないといったものが、よくあると思うのですが、このように指定しないと組めないものでしょうか?
下記は単一テーブルに対してであり、Seasarのリファレンスページを見る限り、「SimpleWhere」を使ったもので実現できそうですが、INNER JOINなど複数テーブル結合文となると更にややこしくなりそうで、シンプルにSQL文をpreparestatement方式で実行できる形にしたいと思って、下記の様なソースになっています。 (動作自体は正常に動きますが・・汚い・・)
特に下記のこの部分が何とかならないものかと悩んでいます。
results = this.jdbcManager.selectBySql(BeanMap.class, sql, "1個目", "2個目","3個目", "4個目").getResultList();
良い方法がありましたら、指摘頂ければありがたいです。 よろしくお願いします。
|
| 質問日時 |
2013-04-02 03:54:49 |
|
| 名前 |
匿名
|
回答内容
回答を評価する
(0ポイント)
|
以下、汚いソースです。。
public List<UserMst> userSearch(String username, String usermail, String pref, String role) { List<UserMst> lt = new ArrayList<UserMst>();
// 条件チェック List<LabelValueBean> cond = new ArrayList<LabelValueBean>(); if (StringUtilz.isStr(username)) { cond.add(new LabelValueBean("username", "%"+username+"%")); } if (StringUtilz.isStr(usermail)) { cond.add(new LabelValueBean("mail", usermail)); } if (StringUtilz.isStr(pref) && !"全国".equals(pref)) { cond.add(new LabelValueBean("pref", pref)); } if (StringUtilz.isStr(role) && !"2".equals(role)) { cond.add(new LabelValueBean("role", role)); } // SQL組立 StringBuffer sql = new StringBuffer(); sql.append("SELECT * FROM user_mst"); for (int i = 0; i < cond.size(); i++) { LabelValueBean bn = cond.get(i); if (i == 0) { sql.append(" where "); } else { sql.append(" and "); } if (bn.getLabel().equals("username")) { sql.append("username like ? "); } else { sql.append(bn.getLabel()+" = ? "); } } sql.append(" order by role, yubin, username"); // 一覧取得 List<BeanMap> results; if (cond.size() == 4) { results = this.jdbcManager.selectBySql(BeanMap.class, sql.toString(), cond.get(0).getValue(), cond.get(1).getValue(), cond.get(2).getValue(), cond.get(3).getValue()).getResultList(); } else if(cond.size() == 3) { results = this.jdbcManager.selectBySql(BeanMap.class, sql.toString(), cond.get(0).getValue(), cond.get(1).getValue(), cond.get(2).getValue()).getResultList(); } else if(cond.size() == 2) { results = this.jdbcManager.selectBySql(BeanMap.class, sql.toString(), cond.get(0).getValue(), cond.get(1).getValue()).getResultList(); } else if(cond.size() == 1) { results = this.jdbcManager.selectBySql(BeanMap.class, sql.toString(), cond.get(0).getValue()).getResultList(); } else { results = this.jdbcManager.selectBySql(BeanMap.class, sql.toString()).getResultList(); }
for (int i = 0; i < results.size(); i++) { BeanMap bn = results.get(i); UserMst mt = new UserMst(); mt.setUserid(bn.get("userid").toString()); mt.setMail(bn.get("mail").toString()); mt.setUsername(bn.get("username").toString()); lt.add(mt); } return lt; }
|
| 回答日時 |
2013-04-02 03:55:49 |
|
| 名前 |
匿名
|
回答内容
回答を評価する
(0ポイント)
|
S2は好みの問題で余り使わないのですが、 selectBySqlの第3引数は可変長引数ではないですか?
であれば、SQL組み立て前にパラメータ取り置き用に ArrayList<Object>等を作って、
selectBySql(BeanMap.class,sql,paramList.toArray());
などではいかがでしょうか。 SQL組み立てと同タイミングでparamListに値を追加する ことでselectBySql一行で、可変個数のパラメータに 対応できるのではないでしょうか。
(※試さないで書いてるのでうまくいかなかったらすみません)
|
| 回答日時 |
2013-04-02 10:47:42 |
|
| 名前 |
匿名
|
回答内容
回答を評価する
(0ポイント)
|
ありがとうございます。
確かに可変式なのですが、Listを指定してもout of Indexとエラーになります(空のList<Object>)。
Jd-clipseが正しく機能せず、動作部まで追えていません。。
<T> SqlSelect<T> selectBySql(Class<T> baseClass, String sql, Object... params);
|
| 回答日時 |
2013-04-02 15:06:33 |
|
| 名前 |
匿名
|
回答内容
回答を評価する
(0ポイント)
|
sql内にあるプレースホルダと同数、渡ってないんじゃない の? 発行直前が想定通りか見てみたら。
ループではStringbuilderではなくListに溜めて、最後にjoinす る。 区切りに何を指定するかというようなのを考えなくていいか ら。 " where " + StringUtils.join(ary, " and ")みたいに。
また、DB周りはそこだけでクラスを分けておく方がいい。
|
| 回答日時 |
2013-04-02 20:25:28 |
|
| 名前 |
匿名
|
回答内容
回答を評価する
(0ポイント)
|
2つ上の者です。 分かりにくくてすみません。 リストではなくList.toArrayで配列にして渡しても駄目ですか?
|
| 回答日時 |
2013-04-02 20:27:23 |
|
| 名前 |
匿名
|
回答内容
回答を評価する
(0ポイント)
|
プレースホルダ0のときに配列渡しちゃいけない仕様なんだと したら、それだけ条件分岐すりゃいい。
|
| 回答日時 |
2013-04-02 20:27:44 |
|
| 名前 |
匿名
|
回答内容
回答を評価する
(0ポイント)
|
うーん ざっくり、S2周りのソース見た限りでは長さ0の配列でもエラー出なさそうだけど
○JdbcManagerImpl.java http://www.seasar.org/source/browse/s2dao/trunk/slim- dao/src/main/java/org/seasar/dao/manager/JdbcManagerImpl.java?view=markup&sortby=rev&sortdir=down
○SqlSelectImpl http://www.seasar.org/source/browse/s2dao/trunk/slim- dao/src/main/java/org/seasar/dao/query/SqlSelectImpl.java?view=markup&sortby=rev&sortdir=down
ListオブジェクトをそのままselectBySqlの第3引数に渡したりしてないですよね?
|
| 回答日時 |
2013-04-02 20:44:26 |
|
| 名前 |
匿名
|
回答内容
回答を評価する
(0ポイント)
|
質問者です。
ありがとうございます。 確認してみたのですが、やはりだめでした。
>プレースホルダ0のときに配列渡しちゃいけない仕様なんだと >したら、それだけ条件分岐すりゃいい。
おっしゃる通り、この分岐は必要ですがこれはWhere句の無いSQLとなります。
また、1個以上条件が含まれても、out of Indexでエラーとなります。 内部的なキャストエラーなのか・・
|
| 回答日時 |
2013-04-02 20:48:38 |
|
| 名前 |
匿名
|
回答内容
回答を評価する
(0ポイント)
|
質問者です。
ありがとうございます。 解決しました。
下記のように若干ソースが綺麗になりました。 StringUtils.joinをするとListが3つも必要となってしまう為、このままにしました。すみません。
あと、パラメータ格納のListですが、Objectにしないと正常に動かないようです。 Stringでやってみましたがだめでした。 (toArray()も必要です)
色々ありがとうございました。
public List<UserMst> userSearch(String username, String usermail, String pref, String role) { List<UserMst> lt = new ArrayList<UserMst>();
// SQL組立 StringBuffer sql = new StringBuffer(); sql.append("SELECT * FROM user_mst"); List<Object> cond = new ArrayList<Object>(); if (StringUtilz.isStr(username)) { sql.append(" where username like ? "); cond.add("%"+username+"%"); } if (StringUtilz.isStr(usermail)) { if (cond.size() < 1) { sql.append(" where "); } else { sql.append(" and "); } sql.append(" mail = ? "); cond.add(usermail); } if (StringUtilz.isStr(pref) && !"全国".equals(pref)) { if (cond.size() < 1) { sql.append(" where "); } else { sql.append(" and "); } sql.append(" pref = ? "); cond.add(pref); } if (StringUtilz.isStr(role) && !"2".equals(role)) { if (cond.size() < 1) { sql.append(" where "); } else { sql.append(" and "); } sql.append(" role = ? "); cond.add(role); } sql.append(" order by role, yubin, username"); // 一覧取得 List<BeanMap> results; if (cond.size() > 0) { results = this.jdbcManager.selectBySql(BeanMap.class, sql.toString(), cond.toArray()).getResultList(); } else { results = this.jdbcManager.selectBySql(BeanMap.class, sql.toString()).getResultList(); }
for (int i = 0; i < results.size(); i++) { BeanMap bn = results.get(i); UserMst mt = new UserMst(); mt.setUserid(bn.get("userid").toString()); mt.setMail(bn.get("mail").toString()); mt.setUsername(bn.get("username").toString()); } }
|
| 回答日時 |
2013-04-03 01:17:29 |
|
| 名前 |
匿名
|
回答内容
回答を評価する
(0ポイント)
|
intやらDateやらもあるんだから、もちろんObjectだよ。
|
| 回答日時 |
2013-04-03 06:42:33 |
|
| 名前 |
匿名
|
回答内容
回答を評価する
(0ポイント)
|
ん?
なぜプログラム中でSQLを組むの? http://s2container.seasar.org/2.4/ja/s2jdbc_manager_ sqlfile.html
|
| 回答日時 |
2013-04-03 14:49:08 |
|
質問から6ヶ月以上経過しているので、回答を書き込むことはできません。
|
|
 |
|
 |
 |