「詰まってしまいました」を何やかんや見ていただいてるようで。
エラーメッセージだけ載せて、やったことやらその手のことを何も書いてないのは申し訳ないなぁと思った次第です。
が!
たかだか2、3ヵ月程度しかしてない言語の記憶なんてほぼないです。
ソース見返して思い出せる(印象深かった)やつとなるので、その点ご容赦ください。
どの原因が何のエラー吐いたか、とかそもそもどんなエラー吐いてたか、すら覚えてないので申し訳…。
クエリーの書き方
これ単体で記事作ったような覚えがあります。
全項目取るときに「select * from hoge where completion = 0」から「from hoge where completion = 0」に修正して解決しました。
お決まりかどうかは知りませんが、恐らくテーブル1つに付きファイル1つの構成になると思うので、いちいちselectする必要ないのかな、と解釈。
ものによっては「select h from hoge h where ~」って書いてました。
一部の項目だけ取るのは申し訳ないですが、やってないのでわからないです。
全項目取得して必要分だけ参照するようなやり方してました。
javaに限りませんが、改行して見た目整えながら書くときは半角スペースが必要です。
たまにやらかします。
@Query("select h"
+ "from hoge h"
+ "where h.completion = 0")
みたいな書き方をしたとき、人間的には改行されているので判読できますが、プログラム的には
@Query("select hfrom hoge hwhere h.completion = 0")
となるので「hfrom」とか「hwhere」が判読できないと怒られます。
デバックで止めてみると1行になっていることが分かると思います。
主キーが複数ある
上司に泣きついた気がします。
例として、hogeテーブルにはmainCodeとsubCodeの2項目が主キーとして指定されているとします。
こんな感じにentityを作ると思うんですが
hoge.java
~前略~
@Data
@Entity
@Table (name = "hoge")
public class hoge {
@Id
@Column(name = "mainCode")
private String mainCode;
@Id
@Column(name = "subCode")
private String subCode;
@Column(name = "listName")
private String listName;
@Column(name = "completion")
private int completion;
}
これだとうまく取れなくて、主キー用ファイルの追加とhoge.javaの追記で何とかなりました。
hogePkey.java
~前略~
@Data
public class hogePkey implements Serializable {
private String mainCode;
private String subCode;
}
hoge.java
~前略~
import javax.persistence.IdClass;
@Data
@Entity
@Table (name = "hoge")
@IdClass(value=hogePkey.class)
public class hoge {
@Id
@Column(name = "mainCode")
private String mainCode;
@Id
@Column(name = "subCode")
private String subCode;
@Column(name = "listName")
private String listName;
@Column(name = "completion")
private int completion;
}
取得データに紐づく別テーブルデータの取得
詰まったかどうかは微妙なんですが、ごちゃごちゃ触った覚えがあるような?
例えば、hogeテーブルと同じ項目を持つfugaテーブル(主キーなし)があるとします。
fuga.java
~前略~
public class fuga {
@Id
@Column(name = "mainCode")
private String mainCode;
@Id
@Column(name = "subCode")
private String subCode;
@Column(name = "toDo")
private String toDo;
@Column(name = "completion")
private int completion;
}
で、任意の呼び方で追記。
hoge.java
~前略~
public class hoge {
@Id
@Column(name = "mainCode")
private String mainCode;
@Id
@Column(name = "subCode")
private String subCode;
@Column(name = "listName")
private String listName;
@Column(name = "completion")
private int completion;
@OneToMany(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private List<fuga> fuga = new ArrayList<fuga>();
}
fuga.java
~前略~
public class fuga {
@Id
@Column(name = "mainCode")
private String mainCode;
@Id
@Column(name = "subCode")
private String subCode;
@Column(name = "toDo")
private String toDo;
@Column(name = "completion")
private int completion;
@ManyToOne
@PrimaryKeyJoinColumn
private hoge h;
}
sqlの動的作成
ファイルを作っては消し作っては消しを繰り返してたやつ。
何をどうして今の形になったかはもう覚えてませんが、どっかのサイトから丸コピしたのは覚えてます。
一部省略するとしても削りどころが分からないので取り敢えず伏せるとこ伏せて全部。
PiyoDataImpl.java
package com.example.demo.repository;
~中略(import系)~
@Repository
public class PiyoDataImpl implements HogeRepository {
@Autowired
private EntityManager entityManager;
@Autowired
PiyoController piyo;
public PiyoDataImpl() {
super();
}
public PiyoDataImpl(EntityManager manag) {
this();
entityManager = manag;
}
@SuppressWarnings("unchecked")
@Override
public List<hoge> search(GetItem item){
StringBuilder sql = new StringBuilder();
boolean chkFlg1 = false;
boolean chkFlg2 = false;
boolean chkFlg3 = false;
sql.append("select h "
+ " from hoge h "
+ " where 1 = 1 ");
//mainCode
if (!StringUtils.isEmpty(item.getMainCode())) {
sql.append("and h.mainCode = :mainCode ");
chkFlg1 = true;
}
//subCode
if (!StringUtils.isEmpty(item.getSubCode())) {
sql.append("and h.subCode = :subCode ");
chkFlg2 = true;
}
//listName
if (!StringUtils.isEmpty(item.getListName())) {
sql.append("and h.listName like :listName ");
chkFlg3 = true;
}
//completion
if (!StringUtils.isEmpty(item.getCompletion())) {
sql.append("and h.completion <> null ");
}
sql.append("order by h.listName desc ");
Query query = entityManager.createQuery(sql.toString());
//mainCode
if (chkFlg1) {
query.setParameter("mainCode", item.getMainCode());
}
//subCode
if (chkFlg2) {
query.setParameter("subCode", item.getSubCode());
}
//listName
if (chkFlg3) {
query.setParameter("listName", "%" + item.getListName() + "%");
}
return query.getResultList();
}
}
画面上のボタン押下処理
詰まった、でなく未だにちょっとよく分かってない、ってやつなんですが。
Servlet用ファイルを作るべきなのかもしれませんが、Controller用ファイルに書きました。
@PostMapping(params="button1")
public String btn1(@ModelAttribute GetItem item, Model mdl) {
~中略~
}
@PostMapping(params="button2")
public String btn2(@ModelAttribute GetItem item, Model mdl) {
~中略~
}
みたいな。
GetItemは画面に表示してる項目取得用の型です。
全体的にインデント狂ってるような。
冒頭の通り思い出せた分だけですが、他はまた思い出したら追記します。
「javaやってた時に詰まったところ」への1件のフィードバック