Hibernate/マッピング定義について/いろいろな検索方法
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。
#contents
データは以下のようになっているとします。
mysql> select * from Samples.CUSTOMER;
+----+-----------+---------+
| ID | NAME | USER_ID |
+----+-----------+---------+
| 1 | CUSTOMER1 | 1 |
| 2 | CUSTOMER2 | NULL |
| 3 | CUSTOMER3 | 3 |
| 4 | CUSTOMER4 | 2 |
| 5 | CUSTOMER5 | 2 |
+----+-----------+---------+
5 rows in set (0.00 sec)
mysql> select * from Samples.USER;
+----+-------+
| ID | NAME |
+----+-------+
| 1 | USER1 |
| 2 | USER2 |
| 3 | USER3 |
+----+-------+
3 rows in set (0.00 sec)
mysql>
**HQLで検索する [#vf487710]
***通常通りやってみる [#l6bef2aa]
まずはHQLで検索してみます。
public static void main(String[] args) {
DOMConfigurator.configure("log4j.xml");
try {
final SessionFactory sessionFactory = getSessionFac...
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer");
List models = query.list();
Iterator it = models.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
session.flush();
session.close();
} catch (Throwable e) {
e.printStackTrace();
}
}
結果は以下の通り。
org.hibernate.SQL - select customer0_.ID as ID1_, custom...
customer0_.NAME as NAME1_ from Sampl...
org.hibernate.SQL - select user0_.ID as ID0_0_, user0_.N...
nu.mine.kino.entity.Customer@1d439fe[id=1,name=CUSTOMER1...
nu.mine.kino.entity.Customer@148f8c8[id=2,name=CUSTOMER2...
org.hibernate.SQL - select user0_.ID as ID0_0_, user0_.N...
nu.mine.kino.entity.Customer@1c5466b[id=3,name=CUSTOMER3...
org.hibernate.SQL - select user0_.ID as ID0_0_, user0_.N...
nu.mine.kino.entity.Customer@922804[id=4,name=CUSTOMER4,...
nu.mine.kino.entity.Customer@1815338[id=5,name=CUSTOMER5...
CUSTOMERが全件検索されて、その後に関連つくUSERが検索され...
***結合をHQLでやる(from句で) [#l8fd849c]
Joinをhbmの設定を利用してやってると、デフォルトではSQL一...
public static void main(String[] args) {
DOMConfigurator.configure("log4j.xml");
try {
final SessionFactory sessionFactory = getSessionFact...
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session
.createQuery("from Customer as customer left joi...
List models = query.list();
Iterator it = models.iterator();
while (it.hasNext()) {
Object element = it.next();
Object[] objects = (Object[]) element;
System.out.println(objects[0]); // 明示的にjoinす...
System.out.println(objects[1]); // CustomerとUser...
}
session.flush();
session.close();
} catch (Throwable e) {
e.printStackTrace();
}
}
結果は以下の通り。
org.hibernate.SQL - select customer0_.ID as ID1_0_, user...
customer0_.NAME as NAME1_0_,u...
from Samples.CUSTOMER custome...
on customer0_.USER_ID=user1_.ID
nu.mine.kino.entity.Customer@17e845a[id=1,name=CUSTOMER1...
nu.mine.kino.entity.User@1ba0f36[id=1,name=USER1]
nu.mine.kino.entity.Customer@3caa4b[id=2,name=CUSTOMER2,...
null
nu.mine.kino.entity.Customer@d0220c[id=3,name=CUSTOMER3,...
nu.mine.kino.entity.User@6b496d[id=3,name=USER3]
nu.mine.kino.entity.Customer@1a19458[id=4,name=CUSTOMER4...
nu.mine.kino.entity.User@1124746[id=2,name=USER2]
nu.mine.kino.entity.Customer@105691e[id=5,name=CUSTOMER5...
nu.mine.kino.entity.User@1124746[id=2,name=USER2]
SQL内でOuter Joinしてくれるようになりました。しかし戻りが...
ちなみにleft joinを ただの joinと書くと内部結合になります...
***配列のところを改善する [#fd63deb5]
先のクエリ
Query query = session
.createQuery("from Customer as customer left joi...
では返り値がCustomer,Userの配列(のリスト)となっていました...
Query query = session
.createQuery("select customer from Customer as c...
このようにselect [クラスのエイリアス名] とすれば、指定し...
org.hibernate.SQL - select customer0_.ID as ID1_, custom...
from Samples.CUSTOMER custome...
on customer0_.USER_ID=user1_.ID
org.hibernate.SQL - select user0_.ID as ID0_0_, user0_.N...
nu.mine.kino.entity.Customer@1815338[id=1,name=CUSTOMER1...
nu.mine.kino.entity.Customer@12368df[id=2,name=CUSTOMER2...
DEBUG org.hibernate.SQL - select user0_.ID as ID0_0_, us...
nu.mine.kino.entity.Customer@1ba0f36[id=3,name=CUSTOMER3...
DEBUG org.hibernate.SQL - select user0_.ID as ID0_0_, us...
nu.mine.kino.entity.Customer@3caa4b[id=4,name=CUSTOMER4,...
nu.mine.kino.entity.Customer@d0220c[id=5,name=CUSTOMER5,...
確かに戻り値が配列ではなくなったのですが、selectがまた乱...
***配列のところを改善する、かつフェッチ済み [#a5509f31]
Query query = session
.createQuery("select customer from Customer as c...
だとCustomerから参照されているUserを参照したときにselect...
Query query = session
.createQuery("select customer from Customer as c...
結果は以下の通り。
org.hibernate.SQL - select customer0_.ID as ID1_0_, user...
customer0_.NAME as NAME1_0_, ...
from Samples.CUSTOMER custome...
left outer join Samples.USER ...
nu.mine.kino.entity.Customer@17e845a[id=1,name=CUSTOMER1...
nu.mine.kino.entity.Customer@3caa4b[id=2,name=CUSTOMER2,...
nu.mine.kino.entity.Customer@d0220c[id=3,name=CUSTOMER3,...
nu.mine.kino.entity.Customer@1a19458[id=4,name=CUSTOMER4...
nu.mine.kino.entity.Customer@105691e[id=5,name=CUSTOMER5...
完璧です。。。
またこのfetch指定を付けた場合は select customer を付けな...
Query query = session
.createQuery("from Customer as customer left join cus...
の戻り値はCustomerクラスでした。
***結合をHQLでやる(where句で) [#a03858b1]
次にwhere句で結合します。
Query query = session
.createQuery("from Customer as customer,User as user wh...
これの結果はCustomer,Userの配列です。
org.hibernate.SQL - select customer0_.ID as ID1_0_, user...
customer0_.NAME as NAME1_0_, ...
from Samples.CUSTOMER custome...
where customer0_.USER_ID=user...
nu.mine.kino.entity.Customer@3caa4b[id=1,name=CUSTOMER1,...
nu.mine.kino.entity.Customer@1a19458[id=3,name=CUSTOMER3...
nu.mine.kino.entity.Customer@105691e[id=4,name=CUSTOMER4...
nu.mine.kino.entity.Customer@11f23e5[id=5,name=CUSTOMER5...
だんだんSQLみたいになってきました。これにselect句をつけて...
**Criteriaで検索する [#g0e8b0dd]
***通常通りやってみる [#a959f42c]
次にCriteriaを使って検索します。
public static void main(String[] args) {
DOMConfigurator.configure("log4j.xml");
try {
final SessionFactory sessionFactory = getSessionFact...
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Customer....
// criteria.setFetchMode("user", FetchMode.JOIN); <-...
List models = criteria.list();
Iterator it = models.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
session.flush();
session.close();
} catch (Throwable e) {
e.printStackTrace();
}
}
結果は以下の通り。
org.hibernate.SQL - select this_.ID as ID1_0_, this_.USE...
this_.NAME as NAME1_0_ from Samples....
org.hibernate.SQL - select user0_.ID as ID0_0_, user0_.N...
nu.mine.kino.entity.Customer@32060c[id=1,name=CUSTOMER1,...
nu.mine.kino.entity.Customer@1efb4be[id=2,name=CUSTOMER2...
org.hibernate.SQL - select user0_.ID as ID0_0_, user0_.N...
nu.mine.kino.entity.Customer@435a3a[id=3,name=CUSTOMER3,...
org.hibernate.SQL - select user0_.ID as ID0_0_, user0_.N...
nu.mine.kino.entity.Customer@1d8c528[id=4,name=CUSTOMER4...
nu.mine.kino.entity.Customer@77eaf8[id=5,name=CUSTOMER5,...
やっぱりCUSTOMERが全件検索されて、その後に関連付くUSERが...
***フェッチの指定をする [#r1fc338e]
コメントアウトしていた
criteria.setFetchMode("user", FetchMode.JOIN); <-フェッ...
をアンコメントしてフェッチのモードを変更してやってみます...
org.hibernate.SQL - select this_.ID as ID1_1_, this_.USE...
this_.NAME as NAME1_1_, user2...
user2_.NAME as NAME0_0_ from ...
left outer join Samples.USER ...
nu.mine.kino.entity.Customer@e35bb7[id=1,name=CUSTOMER1,...
nu.mine.kino.entity.Customer@9a8a68[id=2,name=CUSTOMER2,...
nu.mine.kino.entity.Customer@1038de7[id=3,name=CUSTOMER3...
nu.mine.kino.entity.Customer@183e7de[id=4,name=CUSTOMER4...
nu.mine.kino.entity.Customer@10fe2b9[id=5,name=CUSTOMER5...
あらかじめOuter Joinして検索してくれています。
-[[HIBERNATE イン アクション 7.6.1 n+1セレクト問題の解決>...
***SQLのLike指定をしてみる [#v2d6853a]
(この辺から諸般の事情で顧客とかユーザとか日本語になってた...
Criteria criteria = session.createCriteria(Customer.clas...
Expression.like("name", "%顧客%"));
criteria.setFetchMode("user", FetchMode.JOIN);
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
で
where Customer.name like '%顧客%'
な検索ができます。
%はメソッドの引数で制御することもできて、たとえば
Criteria criteria = session.createCriteria(Customer.clas...
Expression.like("name", "顧客", MatchMode.ANYWHER...
は上の
where Customer.name like '%顧客%'
と同じだったり、
Criteria criteria = session.createCriteria(Customer.clas...
Expression.like("name", "顧客", MatchMode.START));
は
where Customer.name like '顧客%'
だし
Criteria criteria = session.createCriteria(Customer.clas...
Expression.like("name", "顧客", MatchMode.END));
は
where Customer.name like '%顧客'
となります。便利ですね。
***関連先の条件で検索する [#m1cc484d]
たとえばユーザを検索するときに「顧客4を担当しているユー...
例として他には、顧客で、複数持ってる口座のうちある区分の...
そんな場合はCriteriaをくっつけて検索することができます。
Criteria criteria = session.createCriteria(User.class)
.createCriteria("customers").add(
Expression.like("name", "顧客4"));
List<User> list = criteria.list();
for (User user : list) {
Set<Customer> customers = user.getCustomers();
for (Customer customer : customers) {
System.out.println(customer);
}
System.out.println("---------- 以上: " + user);
}
これで「顧客4という名前のCustomerを持っているUser」を検...
実行結果は以下の通り
select this_.ID as ID0_1_, this_.NAME as NAME0_1_, custo...
customer1_.USER_ID as USER2_1_0_, customer1_.NAME...
from USER_ATTR this_, CUSTOMER customer1_
where this_.ID=customer1_.USER_ID
and customer1_.NAME like ?
select customers0_.USER_ID as USER2_1_, customers0_.ID a...
customers0_.ID as ID1_0_, customers0_.USER_ID as ...
customers0_.NAME as NAME1_0_
from CUSTOMER customers0_ where customers0_.USER_...
nu.mine.kino.entity.Customer@15881588[id=4,name=顧客4,...
nu.mine.kino.entity.Customer@b820b82[id=5,name=顧客5,担...
---------- 以上: nu.mine.kino.entity.User@5a3e5a3e[id=2,...
はじめのSQLで、Customer.name like ? としてユーザを検索し...
***DetachedCriteria [#nb7c2215]
Criteriaは通常
session.createCriteria(User.class);
などとsessionから生成しますが、セッションにひも付いていな...
DetachedCriteria userCriteria = DetachedCriteria
.forClass(User.class);
DetachedCriteria customerCriteria = userCriteria
.createCriteria("customers");
customerCriteria.add(Expression.like("name", "顧客4",
MatchMode.ANYWHERE));
Criteria criteria = userCriteria.getExecutableCriteria(s...
List<User> list = criteria.list();
ほとんど同じですが、DetachedCriteriaをつくりきったあと、
Criteria criteria = userCriteria.getExecutableCriteria(s...
とCriteriaをセッションにひも付く形で取得して実行、となり...
たとえばSpringでHibernateTemplateにCriteriaを渡したいとき...
**HQLいろいろ [#fcacc0af]
***サイズ指定 [#tf9fed02]
Query query = session
.createQuery("from Customer customer left join fetch c...
とかで、複数の顧客を抱える担当者を検索できます。
from Customer customer left join fetch customer.user user
で
-Customerクラスを返します
-customer.userを使って外部結合します。
-あらかじめUserクラスをfetchしておきます。
となります。で、
where size(user.customers) > 1
で、UserクラスのCustomersのコレクション(Set)のサイズが1以...
実行結果は以下の通り。
org.hibernate.SQL - select customer0_.ID as ID1_0_, user...
customer0_.NAME as NAME1_0_, ...
from Samples.CUSTOMER custome...
on customer0_.USER_ID=user1_....
where (
select count(customers2_.USE...
from Samples.CUSTOMER custom...
where user1_.ID=customers2_....
)> 1
nu.mine.kino.entity.Customer@16dc861[id=4,name=CUSTOMER4...
nu.mine.kino.entity.Customer@aae86e[id=5,name=CUSTOMER5,...
なるほど。。
-[[Hibernate 入門記 問い合せ その3 式いろいろ>http://d.ha...
***検索条件にプロパティを使う [#n6787da1]
下のように検索条件としてname=xxxってあるときgetName()とい...
user = (User) session.load(User.class, user.getId());
Query query = session.createFilter(user.getCustomers(),
"where this.name=:name");
CustomerModoki modoki = new CustomerModoki();
modoki.setName("顧客1");
query.setProperties(modoki);
List list = query.list();
class CustomerModoki {
private String name;
public String getName() {return name;}
public void setName(String name) {this.name = name;}
}
この場合は名前が"顧客1"という検索を行うことができます。
**ちなみにgetSessionFactory()ってこんな内容 [#jf4a9283]
private static SessionFactory getSessionFactory() {
Configuration config = new Configuration();
return config.configure(new File("hibernate.cfg.xml"))
.buildSessionFactory();
}
**ちなみにInsertってすぐに行われるワケじゃない [#e1642958]
データをインサートして、その後検索するってばあい、DBに実...
Customer c1 = new Customer();
c1.setName("顧客1");
customerDao.create(c1);
System.out.println("検索を開始します");
Customer[] customers = customerDao.readAll();
for (Customer customer : customers) {
System.out.println(customer);
}
ってやった場合((Daoとかは示してしてないけどまあ、普通のDa...
Hibernate: select max(ID) from CUSTOMER
-----------------------------onSave
検索を開始します
-----------------------------preFlush
Hibernate: insert into CUSTOMER (USER_ID, NAME, ID) valu...
-----------------------------postFlush
Hibernate: select this_.ID as ID1_0_, this_.USER_ID as U...
nu.mine.kino.entity.Customer@76627662[id=1,name=顧客1,...
org.springframework.orm.hibernate3.HibernateTransactionM...
Triggering beforeCompletion synchronization
org.springframework.orm.hibernate3.HibernateTransactionM...
Initiating transaction rollback
org.springframework.orm.hibernate3.HibernateTransactionM...
Rolling back Hibernate transaction on Session [org.hibe...
-----------------------------afterTransactionCompletion
org.springframework.orm.hibernate3.HibernateTransactionM...
Triggering afterCompletion synchronization
org.springframework.orm.hibernate3.HibernateTransactionM...
Closing Hibernate Session [org.hibernate.impl.SessionIm...
org.springframework.orm.hibernate3.SessionFactoryUtils -...
nu.mine.kino.dao.CustomerDaoTest - Rolled back transacti...
データを挿入した後に「検索を開始します」と書きましたが、...
----
この記事は
#vote(おもしろかった[21],そうでもない[3])
-結合はhbm.xmlに書いておけばHQLのクエリに書く必要はないみ...
-[[HIBERNATE イン アクション 7.3.1 Hibernateのjoinオプシ...
-関連づけのないテーブル同士のOuter Joinはできないのか。。...
-通常From句でJoinすると配列が返ってくるけれど、fetchって...
#comment
#topicpath
SIZE(10){現在のアクセス:&counter;}
終了行:
// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。
#contents
データは以下のようになっているとします。
mysql> select * from Samples.CUSTOMER;
+----+-----------+---------+
| ID | NAME | USER_ID |
+----+-----------+---------+
| 1 | CUSTOMER1 | 1 |
| 2 | CUSTOMER2 | NULL |
| 3 | CUSTOMER3 | 3 |
| 4 | CUSTOMER4 | 2 |
| 5 | CUSTOMER5 | 2 |
+----+-----------+---------+
5 rows in set (0.00 sec)
mysql> select * from Samples.USER;
+----+-------+
| ID | NAME |
+----+-------+
| 1 | USER1 |
| 2 | USER2 |
| 3 | USER3 |
+----+-------+
3 rows in set (0.00 sec)
mysql>
**HQLで検索する [#vf487710]
***通常通りやってみる [#l6bef2aa]
まずはHQLで検索してみます。
public static void main(String[] args) {
DOMConfigurator.configure("log4j.xml");
try {
final SessionFactory sessionFactory = getSessionFac...
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer");
List models = query.list();
Iterator it = models.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
session.flush();
session.close();
} catch (Throwable e) {
e.printStackTrace();
}
}
結果は以下の通り。
org.hibernate.SQL - select customer0_.ID as ID1_, custom...
customer0_.NAME as NAME1_ from Sampl...
org.hibernate.SQL - select user0_.ID as ID0_0_, user0_.N...
nu.mine.kino.entity.Customer@1d439fe[id=1,name=CUSTOMER1...
nu.mine.kino.entity.Customer@148f8c8[id=2,name=CUSTOMER2...
org.hibernate.SQL - select user0_.ID as ID0_0_, user0_.N...
nu.mine.kino.entity.Customer@1c5466b[id=3,name=CUSTOMER3...
org.hibernate.SQL - select user0_.ID as ID0_0_, user0_.N...
nu.mine.kino.entity.Customer@922804[id=4,name=CUSTOMER4,...
nu.mine.kino.entity.Customer@1815338[id=5,name=CUSTOMER5...
CUSTOMERが全件検索されて、その後に関連つくUSERが検索され...
***結合をHQLでやる(from句で) [#l8fd849c]
Joinをhbmの設定を利用してやってると、デフォルトではSQL一...
public static void main(String[] args) {
DOMConfigurator.configure("log4j.xml");
try {
final SessionFactory sessionFactory = getSessionFact...
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session
.createQuery("from Customer as customer left joi...
List models = query.list();
Iterator it = models.iterator();
while (it.hasNext()) {
Object element = it.next();
Object[] objects = (Object[]) element;
System.out.println(objects[0]); // 明示的にjoinす...
System.out.println(objects[1]); // CustomerとUser...
}
session.flush();
session.close();
} catch (Throwable e) {
e.printStackTrace();
}
}
結果は以下の通り。
org.hibernate.SQL - select customer0_.ID as ID1_0_, user...
customer0_.NAME as NAME1_0_,u...
from Samples.CUSTOMER custome...
on customer0_.USER_ID=user1_.ID
nu.mine.kino.entity.Customer@17e845a[id=1,name=CUSTOMER1...
nu.mine.kino.entity.User@1ba0f36[id=1,name=USER1]
nu.mine.kino.entity.Customer@3caa4b[id=2,name=CUSTOMER2,...
null
nu.mine.kino.entity.Customer@d0220c[id=3,name=CUSTOMER3,...
nu.mine.kino.entity.User@6b496d[id=3,name=USER3]
nu.mine.kino.entity.Customer@1a19458[id=4,name=CUSTOMER4...
nu.mine.kino.entity.User@1124746[id=2,name=USER2]
nu.mine.kino.entity.Customer@105691e[id=5,name=CUSTOMER5...
nu.mine.kino.entity.User@1124746[id=2,name=USER2]
SQL内でOuter Joinしてくれるようになりました。しかし戻りが...
ちなみにleft joinを ただの joinと書くと内部結合になります...
***配列のところを改善する [#fd63deb5]
先のクエリ
Query query = session
.createQuery("from Customer as customer left joi...
では返り値がCustomer,Userの配列(のリスト)となっていました...
Query query = session
.createQuery("select customer from Customer as c...
このようにselect [クラスのエイリアス名] とすれば、指定し...
org.hibernate.SQL - select customer0_.ID as ID1_, custom...
from Samples.CUSTOMER custome...
on customer0_.USER_ID=user1_.ID
org.hibernate.SQL - select user0_.ID as ID0_0_, user0_.N...
nu.mine.kino.entity.Customer@1815338[id=1,name=CUSTOMER1...
nu.mine.kino.entity.Customer@12368df[id=2,name=CUSTOMER2...
DEBUG org.hibernate.SQL - select user0_.ID as ID0_0_, us...
nu.mine.kino.entity.Customer@1ba0f36[id=3,name=CUSTOMER3...
DEBUG org.hibernate.SQL - select user0_.ID as ID0_0_, us...
nu.mine.kino.entity.Customer@3caa4b[id=4,name=CUSTOMER4,...
nu.mine.kino.entity.Customer@d0220c[id=5,name=CUSTOMER5,...
確かに戻り値が配列ではなくなったのですが、selectがまた乱...
***配列のところを改善する、かつフェッチ済み [#a5509f31]
Query query = session
.createQuery("select customer from Customer as c...
だとCustomerから参照されているUserを参照したときにselect...
Query query = session
.createQuery("select customer from Customer as c...
結果は以下の通り。
org.hibernate.SQL - select customer0_.ID as ID1_0_, user...
customer0_.NAME as NAME1_0_, ...
from Samples.CUSTOMER custome...
left outer join Samples.USER ...
nu.mine.kino.entity.Customer@17e845a[id=1,name=CUSTOMER1...
nu.mine.kino.entity.Customer@3caa4b[id=2,name=CUSTOMER2,...
nu.mine.kino.entity.Customer@d0220c[id=3,name=CUSTOMER3,...
nu.mine.kino.entity.Customer@1a19458[id=4,name=CUSTOMER4...
nu.mine.kino.entity.Customer@105691e[id=5,name=CUSTOMER5...
完璧です。。。
またこのfetch指定を付けた場合は select customer を付けな...
Query query = session
.createQuery("from Customer as customer left join cus...
の戻り値はCustomerクラスでした。
***結合をHQLでやる(where句で) [#a03858b1]
次にwhere句で結合します。
Query query = session
.createQuery("from Customer as customer,User as user wh...
これの結果はCustomer,Userの配列です。
org.hibernate.SQL - select customer0_.ID as ID1_0_, user...
customer0_.NAME as NAME1_0_, ...
from Samples.CUSTOMER custome...
where customer0_.USER_ID=user...
nu.mine.kino.entity.Customer@3caa4b[id=1,name=CUSTOMER1,...
nu.mine.kino.entity.Customer@1a19458[id=3,name=CUSTOMER3...
nu.mine.kino.entity.Customer@105691e[id=4,name=CUSTOMER4...
nu.mine.kino.entity.Customer@11f23e5[id=5,name=CUSTOMER5...
だんだんSQLみたいになってきました。これにselect句をつけて...
**Criteriaで検索する [#g0e8b0dd]
***通常通りやってみる [#a959f42c]
次にCriteriaを使って検索します。
public static void main(String[] args) {
DOMConfigurator.configure("log4j.xml");
try {
final SessionFactory sessionFactory = getSessionFact...
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Customer....
// criteria.setFetchMode("user", FetchMode.JOIN); <-...
List models = criteria.list();
Iterator it = models.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
session.flush();
session.close();
} catch (Throwable e) {
e.printStackTrace();
}
}
結果は以下の通り。
org.hibernate.SQL - select this_.ID as ID1_0_, this_.USE...
this_.NAME as NAME1_0_ from Samples....
org.hibernate.SQL - select user0_.ID as ID0_0_, user0_.N...
nu.mine.kino.entity.Customer@32060c[id=1,name=CUSTOMER1,...
nu.mine.kino.entity.Customer@1efb4be[id=2,name=CUSTOMER2...
org.hibernate.SQL - select user0_.ID as ID0_0_, user0_.N...
nu.mine.kino.entity.Customer@435a3a[id=3,name=CUSTOMER3,...
org.hibernate.SQL - select user0_.ID as ID0_0_, user0_.N...
nu.mine.kino.entity.Customer@1d8c528[id=4,name=CUSTOMER4...
nu.mine.kino.entity.Customer@77eaf8[id=5,name=CUSTOMER5,...
やっぱりCUSTOMERが全件検索されて、その後に関連付くUSERが...
***フェッチの指定をする [#r1fc338e]
コメントアウトしていた
criteria.setFetchMode("user", FetchMode.JOIN); <-フェッ...
をアンコメントしてフェッチのモードを変更してやってみます...
org.hibernate.SQL - select this_.ID as ID1_1_, this_.USE...
this_.NAME as NAME1_1_, user2...
user2_.NAME as NAME0_0_ from ...
left outer join Samples.USER ...
nu.mine.kino.entity.Customer@e35bb7[id=1,name=CUSTOMER1,...
nu.mine.kino.entity.Customer@9a8a68[id=2,name=CUSTOMER2,...
nu.mine.kino.entity.Customer@1038de7[id=3,name=CUSTOMER3...
nu.mine.kino.entity.Customer@183e7de[id=4,name=CUSTOMER4...
nu.mine.kino.entity.Customer@10fe2b9[id=5,name=CUSTOMER5...
あらかじめOuter Joinして検索してくれています。
-[[HIBERNATE イン アクション 7.6.1 n+1セレクト問題の解決>...
***SQLのLike指定をしてみる [#v2d6853a]
(この辺から諸般の事情で顧客とかユーザとか日本語になってた...
Criteria criteria = session.createCriteria(Customer.clas...
Expression.like("name", "%顧客%"));
criteria.setFetchMode("user", FetchMode.JOIN);
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
で
where Customer.name like '%顧客%'
な検索ができます。
%はメソッドの引数で制御することもできて、たとえば
Criteria criteria = session.createCriteria(Customer.clas...
Expression.like("name", "顧客", MatchMode.ANYWHER...
は上の
where Customer.name like '%顧客%'
と同じだったり、
Criteria criteria = session.createCriteria(Customer.clas...
Expression.like("name", "顧客", MatchMode.START));
は
where Customer.name like '顧客%'
だし
Criteria criteria = session.createCriteria(Customer.clas...
Expression.like("name", "顧客", MatchMode.END));
は
where Customer.name like '%顧客'
となります。便利ですね。
***関連先の条件で検索する [#m1cc484d]
たとえばユーザを検索するときに「顧客4を担当しているユー...
例として他には、顧客で、複数持ってる口座のうちある区分の...
そんな場合はCriteriaをくっつけて検索することができます。
Criteria criteria = session.createCriteria(User.class)
.createCriteria("customers").add(
Expression.like("name", "顧客4"));
List<User> list = criteria.list();
for (User user : list) {
Set<Customer> customers = user.getCustomers();
for (Customer customer : customers) {
System.out.println(customer);
}
System.out.println("---------- 以上: " + user);
}
これで「顧客4という名前のCustomerを持っているUser」を検...
実行結果は以下の通り
select this_.ID as ID0_1_, this_.NAME as NAME0_1_, custo...
customer1_.USER_ID as USER2_1_0_, customer1_.NAME...
from USER_ATTR this_, CUSTOMER customer1_
where this_.ID=customer1_.USER_ID
and customer1_.NAME like ?
select customers0_.USER_ID as USER2_1_, customers0_.ID a...
customers0_.ID as ID1_0_, customers0_.USER_ID as ...
customers0_.NAME as NAME1_0_
from CUSTOMER customers0_ where customers0_.USER_...
nu.mine.kino.entity.Customer@15881588[id=4,name=顧客4,...
nu.mine.kino.entity.Customer@b820b82[id=5,name=顧客5,担...
---------- 以上: nu.mine.kino.entity.User@5a3e5a3e[id=2,...
はじめのSQLで、Customer.name like ? としてユーザを検索し...
***DetachedCriteria [#nb7c2215]
Criteriaは通常
session.createCriteria(User.class);
などとsessionから生成しますが、セッションにひも付いていな...
DetachedCriteria userCriteria = DetachedCriteria
.forClass(User.class);
DetachedCriteria customerCriteria = userCriteria
.createCriteria("customers");
customerCriteria.add(Expression.like("name", "顧客4",
MatchMode.ANYWHERE));
Criteria criteria = userCriteria.getExecutableCriteria(s...
List<User> list = criteria.list();
ほとんど同じですが、DetachedCriteriaをつくりきったあと、
Criteria criteria = userCriteria.getExecutableCriteria(s...
とCriteriaをセッションにひも付く形で取得して実行、となり...
たとえばSpringでHibernateTemplateにCriteriaを渡したいとき...
**HQLいろいろ [#fcacc0af]
***サイズ指定 [#tf9fed02]
Query query = session
.createQuery("from Customer customer left join fetch c...
とかで、複数の顧客を抱える担当者を検索できます。
from Customer customer left join fetch customer.user user
で
-Customerクラスを返します
-customer.userを使って外部結合します。
-あらかじめUserクラスをfetchしておきます。
となります。で、
where size(user.customers) > 1
で、UserクラスのCustomersのコレクション(Set)のサイズが1以...
実行結果は以下の通り。
org.hibernate.SQL - select customer0_.ID as ID1_0_, user...
customer0_.NAME as NAME1_0_, ...
from Samples.CUSTOMER custome...
on customer0_.USER_ID=user1_....
where (
select count(customers2_.USE...
from Samples.CUSTOMER custom...
where user1_.ID=customers2_....
)> 1
nu.mine.kino.entity.Customer@16dc861[id=4,name=CUSTOMER4...
nu.mine.kino.entity.Customer@aae86e[id=5,name=CUSTOMER5,...
なるほど。。
-[[Hibernate 入門記 問い合せ その3 式いろいろ>http://d.ha...
***検索条件にプロパティを使う [#n6787da1]
下のように検索条件としてname=xxxってあるときgetName()とい...
user = (User) session.load(User.class, user.getId());
Query query = session.createFilter(user.getCustomers(),
"where this.name=:name");
CustomerModoki modoki = new CustomerModoki();
modoki.setName("顧客1");
query.setProperties(modoki);
List list = query.list();
class CustomerModoki {
private String name;
public String getName() {return name;}
public void setName(String name) {this.name = name;}
}
この場合は名前が"顧客1"という検索を行うことができます。
**ちなみにgetSessionFactory()ってこんな内容 [#jf4a9283]
private static SessionFactory getSessionFactory() {
Configuration config = new Configuration();
return config.configure(new File("hibernate.cfg.xml"))
.buildSessionFactory();
}
**ちなみにInsertってすぐに行われるワケじゃない [#e1642958]
データをインサートして、その後検索するってばあい、DBに実...
Customer c1 = new Customer();
c1.setName("顧客1");
customerDao.create(c1);
System.out.println("検索を開始します");
Customer[] customers = customerDao.readAll();
for (Customer customer : customers) {
System.out.println(customer);
}
ってやった場合((Daoとかは示してしてないけどまあ、普通のDa...
Hibernate: select max(ID) from CUSTOMER
-----------------------------onSave
検索を開始します
-----------------------------preFlush
Hibernate: insert into CUSTOMER (USER_ID, NAME, ID) valu...
-----------------------------postFlush
Hibernate: select this_.ID as ID1_0_, this_.USER_ID as U...
nu.mine.kino.entity.Customer@76627662[id=1,name=顧客1,...
org.springframework.orm.hibernate3.HibernateTransactionM...
Triggering beforeCompletion synchronization
org.springframework.orm.hibernate3.HibernateTransactionM...
Initiating transaction rollback
org.springframework.orm.hibernate3.HibernateTransactionM...
Rolling back Hibernate transaction on Session [org.hibe...
-----------------------------afterTransactionCompletion
org.springframework.orm.hibernate3.HibernateTransactionM...
Triggering afterCompletion synchronization
org.springframework.orm.hibernate3.HibernateTransactionM...
Closing Hibernate Session [org.hibernate.impl.SessionIm...
org.springframework.orm.hibernate3.SessionFactoryUtils -...
nu.mine.kino.dao.CustomerDaoTest - Rolled back transacti...
データを挿入した後に「検索を開始します」と書きましたが、...
----
この記事は
#vote(おもしろかった[21],そうでもない[3])
-結合はhbm.xmlに書いておけばHQLのクエリに書く必要はないみ...
-[[HIBERNATE イン アクション 7.3.1 Hibernateのjoinオプシ...
-関連づけのないテーブル同士のOuter Joinはできないのか。。...
-通常From句でJoinすると配列が返ってくるけれど、fetchって...
#comment
#topicpath
SIZE(10){現在のアクセス:&counter;}
ページ名: