JAvaライブラリ関連クエリーツールクラス
32643 ワード
質問:
企業の業務が拡大したため、各サブシステムは次々と異なるデータソースに移行し、導入され、拡張が容易になったが、いくつかの問題が発生した.
例として、「受注」(受注サブシステムにある)リストを照会する際に、関連する「ユーザー」(アカウントサブシステムにある)の名前を照会する必要があるが、この場合、データが異なるデータソースに格納されているため、1つの連結テーブルのsqlですべてのデータを取得することはできないが、2回のデータベース照会を行い、異なるデータソースからそれぞれデータを取得しなければならない.Webサーバで関連マッピングを行います.しばらく観察したところ,関連マッピングを行うコードの大部分がテンプレート化されていることが分かったため,これらのテンプレートコードを抽象化し,開発を簡素化し,コードの可読性を向上させる考えが生まれた.同時に、同じデータ・ソースでも、複数のテーブル・クエリーのニーズを単一のテーブル・複数回のクエリーに変換できれば、コードの結合を低減し、データベースの効率を向上させることができます.
設計の主な考え方:
リレーショナル・データベース:
一対一の関係は、一般に、一方のデータテーブル構造に1つのビジネス上の外部キーが別のテーブルに関連付けられているプライマリ・キー(受注とユーザーが一対一の関係である場合、受注テーブルに外部キーがユーザー・テーブルに対応するプライマリ・キー)として表されます.
一対多の関係は、一般に、複数のデータに1つの業務上の外部キーが関連する一方のプライマリ・キー(店舗と受注が一対多の関係である場合、受注テーブルに外部キーが存在する場合、店舗のプライマリ・キーに対応する)として表される.
非リレーショナル・データベースでは、次のようになります.
一対一の関係は、一般に、一方に属性が存在し、値が関連する他方のデータ・オブジェクト(受注とユーザーが一対一の関係である場合、受注オブジェクトにユーザー属性が存在する)として表されます.
一対多の関係は一般に、一方に1つの属性が存在し、値が関連する他方のデータオブジェクトリスト(店舗と所属受注が一対多の関係である場合、店舗オブジェクトには1つの受注リスト(List)属性が存在する)と表される.
Javaのオブジェクトメカニズムは,自然に非関係型のデータモデルをサポートするため,クエリされた2つのリストを要求に合ったマッピングすればよいという大まかな考え方が見られる.
pojoクラス:
補助ツール関数:
1対1の接続インタフェース定義:
上記の1対1の接続例を持ち込むと、beanListは受注リスト(List)であり、beanKeyNameは受注がユーザを関連付けるためのフィールド名(例えば、外部キー「OrderForm.customerID」)であり、beanModelNameはユーザクラスを格納するためのフィールド名(「例えばOrderForm.customer」)であり、dataListは顧客リスト(List)であり、DataKeyNameは、関連付けられたデータのkey(プライマリ・キー「Customer.id」)です.
1対1の接続コードの実装:
1対の複数接続インタフェースの定義:
上記の一対のマルチコネクションの例を持ち込むと、oneDataListは店舗リスト(List)であり、oneKeyNameは店舗が受注を関連付けるためのフィールド名(例えばメインキー「Shop.id」)であり、oneModelNameは受注リストを格納するためのフィールド名(例えば「Shop.orderFomrList」)であり、manyDataListはマルチリスト(List)であり、manyKeyNameは、関連付けられたデータのkey(例えば、外部キー「OrderFrom.shopID」)である.
1対のマルチ接続コード実装:
テスト例はgithubの上にありますhttps://github.com/1399852153/linkedQueryUtil.
これは私の最初の技術ブログで、レイアウトにしても共有にしてもまだ多くの不足点があります.皆さんが指摘して、お互いに交流して、お互いに進歩してほしいと思っています.
企業の業務が拡大したため、各サブシステムは次々と異なるデータソースに移行し、導入され、拡張が容易になったが、いくつかの問題が発生した.
例として、「受注」(受注サブシステムにある)リストを照会する際に、関連する「ユーザー」(アカウントサブシステムにある)の名前を照会する必要があるが、この場合、データが異なるデータソースに格納されているため、1つの連結テーブルのsqlですべてのデータを取得することはできないが、2回のデータベース照会を行い、異なるデータソースからそれぞれデータを取得しなければならない.Webサーバで関連マッピングを行います.しばらく観察したところ,関連マッピングを行うコードの大部分がテンプレート化されていることが分かったため,これらのテンプレートコードを抽象化し,開発を簡素化し,コードの可読性を向上させる考えが生まれた.同時に、同じデータ・ソースでも、複数のテーブル・クエリーのニーズを単一のテーブル・複数回のクエリーに変換できれば、コードの結合を低減し、データベースの効率を向上させることができます.
設計の主な考え方:
リレーショナル・データベース:
一対一の関係は、一般に、一方のデータテーブル構造に1つのビジネス上の外部キーが別のテーブルに関連付けられているプライマリ・キー(受注とユーザーが一対一の関係である場合、受注テーブルに外部キーがユーザー・テーブルに対応するプライマリ・キー)として表されます.
一対多の関係は、一般に、複数のデータに1つの業務上の外部キーが関連する一方のプライマリ・キー(店舗と受注が一対多の関係である場合、受注テーブルに外部キーが存在する場合、店舗のプライマリ・キーに対応する)として表される.
非リレーショナル・データベースでは、次のようになります.
一対一の関係は、一般に、一方に属性が存在し、値が関連する他方のデータ・オブジェクト(受注とユーザーが一対一の関係である場合、受注オブジェクトにユーザー属性が存在する)として表されます.
一対多の関係は一般に、一方に1つの属性が存在し、値が関連する他方のデータオブジェクトリスト(店舗と所属受注が一対多の関係である場合、店舗オブジェクトには1つの受注リスト(List)属性が存在する)と表される.
Javaのオブジェクトメカニズムは,自然に非関係型のデータモデルをサポートするため,クエリされた2つのリストを要求に合ったマッピングすればよいという大まかな考え方が見られる.
pojoクラス:
public class OrderForm {
/**
* id
* */
private String id;
/**
* id
* */
private String shopID;
/**
* id
* */
private String customerID;
/**
* model
* */
private Customer customer;
}
public class Customer {
/**
* id
* */
private String id;
/**
*
* */
private String userName;
}
public class Shop {
/**
* id
* */
private String id;
/**
*
* */
private String shopName;
/**
* ( N )
* */
private List orderFormList;
}
補助ツール関数:
/***
* keyName bean get
* @param keyName
* @return get
*/
private static String makeGetMethodName(String keyName){
//:::
String newKeyName = transFirstCharUpperCase(keyName);
return "get" + newKeyName;
}
/***
* keyName bean set
* @param keyName
* @return set
*/
private static String makeSetMethodName(String keyName){
//:::
String newKeyName = transFirstCharUpperCase(keyName);
return "set" + newKeyName;
}
/**
*
* @param str
* @return
*/
private static String transFirstCharUpperCase(String str){
return str.replaceFirst(str.substring(0, 1), str.substring(0, 1).toUpperCase());
}
/**
*
*
* ,
* @return false, true
* */
private static boolean needTrans(List beanList,List dataList){
if(listIsEmpty(beanList) || listIsEmpty(dataList)){
return false;
}else{
return true;
}
}
/**
*
* */
private static boolean listIsEmpty(List list){
if(list == null || list.isEmpty()){
return true;
}else{
return false;
}
}
/**
* javaBean list map, key bean
*
* @param beanList list
* @param keyName map key
* @return
* @throws Exception
*/
public static Map beanListToMap(List beanList,String keyName) throws Exception{
//::: map
Map map = new HashMap<>();
//::: keyName get
String getMethodName = makeGetMethodName(keyName);
//::: beanList
for(Object obj : beanList){
//::: hashMap
if(obj.getClass() == HashMap.class){
Map currentMap = (Map)obj;
//::: keyName map key
String result = (String)currentMap.get(keyName);
//::: map ( key , )
map.put(result,currentMap);
}else{
//::: pojo
//::: get
Method getMethod = obj.getClass().getMethod(getMethodName);
//::: get bean key
String result = (String)getMethod.invoke(obj);
//::: map ( key , )
map.put(result,obj);
}
}
//:::
return map;
}
1対1の接続インタフェース定義:
/**
* : beanKeyName dataKeyName
*
* @param beanList beanList( )
* @param beanKeyName beanList key
* @param beanModelName beanList value
* @param dataList data
* @param dataKeyName data key
*
* @throws Exception
*/
public static void oneToOneLinked(List beanList, String beanKeyName, String beanModelName, List dataList, String dataKeyName) throws Exception { }
上記の1対1の接続例を持ち込むと、beanListは受注リスト(List)であり、beanKeyNameは受注がユーザを関連付けるためのフィールド名(例えば、外部キー「OrderForm.customerID」)であり、beanModelNameはユーザクラスを格納するためのフィールド名(「例えばOrderForm.customer」)であり、dataListは顧客リスト(List)であり、DataKeyNameは、関連付けられたデータのkey(プライマリ・キー「Customer.id」)です.
1対1の接続コードの実装:
/**
* : beanKeyName dataKeyName
*
* @param beanList beanList( )
* @param beanKeyName beanList key
* @param beanModelName beanList value
* @param dataList data
* @param dataKeyName data key
*
* @throws Exception
*/
public static void oneToOneLinked(List beanList, String beanKeyName, String beanModelName, List dataList, String dataKeyName) throws Exception {
//::: ,
if(!needTrans(beanList,dataList)){
return;
}
//::: , key, map,
Map dataMap = beanListToMap(dataList,dataKeyName);
//:::
matchedDataToBeanList(beanList,beanKeyName,beanModelName,dataMap);
}
/**
* , beanList
* @param beanList beanList( )
* @param beanKeyName beanList
* @param beanModelName beanList
* @param dataMap data key map
* @throws Exception
*/
private static void matchedDataToBeanList(List beanList, String beanKeyName, String beanModelName, Map dataMap) throws Exception {
//::: beanList key get
String beanGetMethodName = makeGetMethodName(beanKeyName);
//::: beanList model set
String beanSetMethodName = makeSetMethodName(beanModelName);
//::: beanList
for(Object bean : beanList){
//::: bean key method
Method beanGetMethod = bean.getClass().getMethod(beanGetMethodName);
//::: key
String currentBeanKey = (String)beanGetMethod.invoke(bean);
//::: map
Object matchedData = dataMap.get(currentBeanKey);
//:::
if(matchedData != null){
//::: bean model set
Class clazz = matchedData.getClass();
//::: hashMap
if(clazz == HashMap.class){
//::: map class set
clazz = Map.class;
}
//::: bean set
Method beanSetMethod = bean.getClass().getMethod(beanSetMethodName,clazz);
//::: set , model
beanSetMethod.invoke(bean,matchedData);
}
}
}
1対の複数接続インタフェースの定義:
/**
* : oneKeyName manyKeyName
*
* @param oneDataList ' '
* @param oneKeyName ' ' key
* @param oneModelName ' ' ' '
* @param manyDataList ' '
* @param manyKeyName ' ' key
*
* : ' ' ' ' oneModelName List
*
* @throws Exception
*/
public static void oneToManyLinked(List oneDataList,String oneKeyName,String oneModelName,List manyDataList,String manyKeyName) throws Exception {}
上記の一対のマルチコネクションの例を持ち込むと、oneDataListは店舗リスト(List)であり、oneKeyNameは店舗が受注を関連付けるためのフィールド名(例えばメインキー「Shop.id」)であり、oneModelNameは受注リストを格納するためのフィールド名(例えば「Shop.orderFomrList」)であり、manyDataListはマルチリスト(List)であり、manyKeyNameは、関連付けられたデータのkey(例えば、外部キー「OrderFrom.shopID」)である.
1対のマルチ接続コード実装:
/**
* : oneKeyName manyKeyName
*
* @param oneDataList ' '
* @param oneKeyName ' ' key
* @param oneModelName ' ' ' '
* @param manyDataList ' '
* @param manyKeyName ' ' key
*
* : ' ' ' ' oneModelName List
*
* @throws Exception
*/
public static void oneToManyLinked(List oneDataList,String oneKeyName,String oneModelName,List manyDataList,String manyKeyName) throws Exception {
if(!needTrans(oneDataList,manyDataList)){
return;
}
//::: ' ' , key, map,
Map oneDataMap = beanListToMap(oneDataList,oneKeyName);
//::: ' ' ' ' get
String oneDataModelGetMethodName = makeGetMethodName(oneModelName);
//::: ' ' ' ' set
String oneDataModelSetMethodName = makeSetMethodName(oneModelName);
//::: ' ' get
String manyDataKeyGetMethodName = makeGetMethodName(manyKeyName);
try {
//::: ' '
for (Object manyDataItem : manyDataList) {
//:::' ' key
String manyDataItemKey;
//::: ' ' hashMap
if(manyDataItem.getClass() == HashMap.class){
//::: hashMap , Map
Map manyDataItemMap = (Map)manyDataItem;
//::: key key
manyDataItemKey = (String)manyDataItemMap.get(manyKeyName);
}else{
//::: pojo , get key
//::: ' ' key method
Method manyDataKeyGetMethod = manyDataItem.getClass().getMethod(manyDataKeyGetMethodName);
//::: ' ' get ' ' key
manyDataItemKey = (String) manyDataKeyGetMethod.invoke(manyDataItem);
}
//::: ' ' key ' ' map key ' '
Object matchedOneData = oneDataMap.get(manyDataItemKey);
//::: ,
if(matchedOneData != null){
//::: ' ' ' '
setManyDataToOne(matchedOneData,manyDataItem,oneDataModelGetMethodName,oneDataModelSetMethodName);
}
}
}catch(Exception e){
throw new Exception(e);
}
}
/**
* ' ' ' '
* @param oneData ' '
* @param manyDataItem ' '
* @param oneDataModelGetMethodName get
* @param oneDataModelSetMethodName set
* @throws Exception
*/
private static void setManyDataToOne(Object oneData,Object manyDataItem,String oneDataModelGetMethodName,String oneDataModelSetMethodName) throws Exception {
//::: ' ' ' ' get
Method oneDataModelGetMethod = oneData.getClass().getMethod(oneDataModelGetMethodName);
//::: ' ' ' ' set
Method oneDataModelSetMethod;
try {
//::: ' ' set
oneDataModelSetMethod = oneData.getClass().getMethod(oneDataModelSetMethodName,List.class);
}catch(NoSuchMethodException e){
throw new Exception(" ' 'set ");
}
//::: ' ' get
Class modelType = oneDataModelGetMethod.getReturnType();
//::: get List
if(modelType.equals(List.class)){
//::: get ,
List modelList = (List)oneDataModelGetMethod.invoke(oneData);
//::: null
if(modelList == null){
//::: List
List newList = new ArrayList<>();
//::: ' ' list
newList.add(manyDataItem);
//::: List ' '
oneDataModelSetMethod.invoke(oneData,newList);
}else{
//::: List
//::: ' ' list
modelList.add(manyDataItem);
}
}else{
throw new Exception(" , model list ");
}
}
テスト例はgithubの上にありますhttps://github.com/1399852153/linkedQueryUtil.
これは私の最初の技術ブログで、レイアウトにしても共有にしてもまだ多くの不足点があります.皆さんが指摘して、お互いに交流して、お互いに進歩してほしいと思っています.