HibernateでのCreateSQLQuery



Createsqlquery Hibernate



転送元:http://blog.csdn.net/jacman/article/details/8591152

まず、addEntity()メソッドとsetResultTransformer()メソッド

1.1。

SQLQueryの使用
ネイティブSQLクエリの実行の制御は、Session.createSQLQuery()を実行することによって取得されるSQLQueryインターフェイスを介して実行されます。最も単純なケースでは、次の形式をとることができます。

List cats = sess.createSQLQuery( 'select * from cats')。addEntity(Cat。class).list()

このクエリは以下を指定します:

SQLクエリ文字列

返されたエンティティを照会する

ここで、結果セットのフィールド名は、マッピングファイルで指定されたフィールド名と同じであると想定されます。同じ名前のフィールドが複数のテーブルに表示される可能性があるため、これは、複数のテーブルが結合されているクエリでは問題になる可能性があります。次の方法で、フィールド名が重複する問題を回避できます。

List cats = sess.createSQLQuery( 'select {cat。*} from cats cat')。addEntity( 'cat'、Cat。class).list()

このクエリは以下を指定します:

Hibernateがフィールドエイリアスを使用できるようにするプレースホルダーを含むSQLクエリステートメント。

返されたエンティティとそのSQLテーブルエイリアスをクエリします。

addEntity()メソッドは、SQLテーブルのエイリアスをエンティティクラスに関連付け、クエリ結果セットの形状を決定します。

addJoin()メソッドを使用して、他のエンティティとコレクション間の関連付けをロードできます。

リストcats = sess.createSQLQuery(
'cats cat、cats kittenから{cat。*}、{kitten。*}を選択します。ここで、kitten.mother = cat.id')
.addEntity( 'cat'、Cat .class)
.addJoin( '子猫'、 'cat.kittens')
。リスト()

ネイティブSQLクエリは、単純なスカラー値またはスカラーとエンティティの組み合わせを返す場合があります。

Double max =(Double)sess.createSQLQuery( 'select max(cat.weight)as maxWeight from cats cat')
.addScalar( 'maxWeight'、Hibernate.DOUBLE)
.uniqueResult()

さらに、クエリで使用するために、hbmファイルに結果セットのマッピング情報を記述することもできます。

リストcats = sess.createSQLQuery(
'cats cat、cats kittenから{cat。*}、{kitten。*}を選択します。ここで、kitten.mother = cat.id')
.setResultSetMapping( 'catAndKitten')
。リスト()

名前付きSQLクエリ
マッピングドキュメントでクエリの名前を定義してから、名前付きHQLクエリを呼び出すときに名前付きSQLクエリを直接呼び出すことができます。この場合、addEntity()メソッドを呼び出す必要はありません。



person.NAME AS {person.name}、person.AGE AS {person.age}、person.SEX AS {person.sex} FROM PERSON person Where person.NAME LIKE:namePatternを選択します
リスト人= sess.getNamedQuery( '人').setString( 'namePattern'、namePattern)
.setMaxResults(50)
。リスト()


二。

hibernate3のcreateSQLQueryに関する問題

アクセスを高速化するために、DAOの一部のHQL操作がSQLに変更されています。実際、主な理由は次のとおりです。操作が複数のテーブルであり、返されるデータも複数のテーブルのフィールドから取得されます。
String sql = 'select A.id ID、A.name NAME、B.salary SALARY from employee A、Salary B where .......';
クエリquery = getSession()。createSQLQuery(sql)
.setResultTransformer(Transformers.aliasToBean(ReturnEmployee.class))
返されたID、NAME、SALARYはテーブルに対応するBEANではないため、ReturnEmployee BEANを作成する必要があります。属性には、mysqlでのID、NAME、SALARYデバッグ、成功が含まれます。
ただし、ORACLE環境では、エラーが発生します。

org.hibernate.PropertyNotFoundException:クラスcom.ReturnEmployeeでIDのセッターが見つかりませんでした

数時間のトラブルシューティング、デバッグの後、問題は見つかりませんでしたが、GOOGLEを取り除くことしかできず、最終的に外国のフォーラムで答えを見つけました。

これは実際には、実際に指定した大文字小文字を使用する代わりに、エイリアスをすべて大文字で返す一部のデータベースの制限です。

それまでは、.addScalar(..)を使用して回避してください。

HibernateはORALCEをBUGでサポートしていることが判明したため、コードは次のように変更されます。
クエリquery = getSession()。createSQLQuery(sql).addScalar( 'ID')
.addScalar( 'NAME')。addScalar( 'SALARY')
大丈夫です、注意を払う価値があります
リストemployeeData = query.list()
返されるemployeeDataのデータはobject []であり、次の値を取ります。
リストemployeeBean = new ArrayList()
for(int i = 0 i 従業員employee = new Employee()//「裸の」データを独自の従業員クラスにアセンブルします

Object [] object =(Object [])employeeData.get(i)
employee.setId(object [0] .toString())
employee.setName(object [1] .toString())
employee.setOrgType(object [2] .toString())

employeeBean.add(employee)
}

Mapオブジェクトを返すこともできます。つまり、リストに複数のマップを含めることができます。コードは次のとおりです。
Query query = session.createSQLQuery( 'select id、name from Tree t where pid in(select id from Tree)')。setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)//マップを返します。KEY:名前はDBで一貫しています(大文字と小文字を区別します)センシティブ)一貫性)リストをトラバースするとき

マップマップ=(Map)list.get [i]

Map.get( 'id')map.get( 'name')を使用して、値を取得します。 SQLステートメントのフィールド名に従って、マップキーとして選択しますが、このキーはデータベースのフィールド名と完全に同じである必要があります。


関数としても使用できます。といった
クエリquery = session.createSQLQuery( 'select sum(id)SUMID from Tree t where pid in(select id from Tree)
.addScalar( 'SUMID'、Hibernate.INTEGER)//変換タイプ、DBでタイプを押します
.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)//マップを返します。KEY:名前はDBで同じです(同じ場合)

map.get( 'SUMID')で直接値を取ることができます


もう1つのポイントは、この方法がHibernate3.2で正常に機能することです。


眉毛を見つけたので、まとめは次のとおりです。

1、oracle charフィールドは、hibernateの文字型にマップされ、varcharのサブセットです。

2、createSQLQueryメソッドクエリを使用した複雑なSQLは問題ありません。複数のフィールドをクエリする場合、object []モデリングでトラバースし、0からの添え字出力値、マッピングBeanを記述できる場合はマッピングファイルなし、簡単にアクセスできます。

3、クエリSQLにフィールドが1つしかない場合、object []配列で受け取ることはできず、オブジェクトクラスでのみ受け取ることができ、このフィールドの値であるobject.toString()を直接出力します。

4、addScalar(String arg、Type type)メソッドを使用して、返すフィールドのタイプを定義できます。

s.createSQLQuery(shuiQingHQL).addScalar( 'STCD'、Hibernate.STRING).addScalar( 'STNM');

これにより、CHARフィールドタイプに1文字しかないという問題が解決されます。

ただし、他のフィールドもaddScalar()に追加する必要があります。

5、addScalar(String arg)のパラメーターは大文字です!



次に、SQLQueryの追加、削除、および変更

SQLQueryを使用したHibernateクエリ:

BaseHibernateDAO dao = new BaseHibernateDAO()
//文を確認します
String strSql = 'select * from hrrole h where h.code like?およびh.id? '
//クエリオブジェクトを設定します
SQLQueryクエリ= dao.getSession()。createSQLQuery(strSql)
//クエリパラメータを設定します
query.setString(0、(String)this.getCode()。getText())
//クエリパラメータを設定します
query.setString(1、this.getTextField1()。getText()。toString())
//クラスに追加
query.addEntity(HrRole.class)
//結果データ
ArrayList idlist =(ArrayList)query.list()
//値があるかどうかを判断します
if(idlist.size()!= 0){
/ / エラーメッセージ
this.label2.setText( 'コードはすでに存在します')
}

HibernateでSQLQueryを使用した更新:

public void updateR(String Code, String NewCode) {
BaseHibernateDAO dao = new BaseHibernateDAO()

try {
Transaction tx = dao.getSession().beginTransaction()

String sql1 = 'update roleandgrant set rolecode = '' + Code + ''' + ' where rolecode ='' + NewCode + '''
String sql2 = 'update emprole set rolecode = '' + Code + ''' + ' where rolecode ='' + NewCode + '''

SQLQuery query1 = dao.getSession().createSQLQuery(sql1)
SQLQuery query2 = dao.getSession().createSQLQuery(sql2)

query1.addEntity(RoleAndGrant.class)
query2.addEntity(EmpVsRole.class)

query2.executeUpdate()
query1.executeUpdate()

tx.commit()

dao.closeSession()
} catch (Exception ex) {
System.out.println(ex)
dao.closeSession()
}
}



HibernateはSQLQueryの削除を使用します:

public void DeleteR(String Code) {
BaseHibernateDAO dao = new BaseHibernateDAO()

try {
Transaction tx = dao.getSession().beginTransaction()

String sql1 = 'delete from roleandgrant where rolecode ='' + Code + '''
String sql2 = 'delete from emprole where rolecode ='' + Code + '''

SQLQuery query1 = dao.getSession().createSQLQuery(sql1)
SQLQuery query2 = dao.getSession().createSQLQuery(sql2)

query1.addEntity(RoleAndGrant.class)
query2.addEntity(EmpVsRole.class)

query2.executeUpdate()
query1.executeUpdate()

tx.commit()

dao.closeSession()
} catch (Exception ex) {
System.out.println(ex)
dao.closeSession()
}
}