1 package com.lavans.luz2.sql.dao;
\r
3 import java.lang.reflect.InvocationTargetException;
\r
4 import java.lang.reflect.Method;
\r
5 import java.sql.ResultSet;
\r
6 import java.sql.ResultSetMetaData;
\r
7 import java.sql.SQLException;
\r
8 import java.util.ArrayList;
\r
9 import java.util.LinkedHashMap;
\r
10 import java.util.List;
\r
11 import java.util.Map;
\r
13 import org.apache.commons.logging.Log;
\r
14 import org.apache.commons.logging.LogFactory;
\r
16 import com.lavans.luz2.commons.ClassUtils;
\r
17 import com.lavans.luz2.commons.StringUtils;
\r
18 import com.lavans.luz2.sql.DBManager;
\r
19 import com.lavans.luz2.sql.bind.BindConnection;
\r
20 import com.lavans.luz2.sql.bind.BindPreparedStatement;
\r
21 import com.lavans.luz2.util.PageInfo;
\r
22 import com.lavans.luz2.util.Pager;
\r
30 public class CommonDao{
\r
32 private static Log logger = LogFactory.getLog(CommonDao.class);
\r
33 /** default connection name */
\r
34 private static final String DEFALUT_CONNECTION = "default";
\r
43 * Executes the given SQL statement, which returns ResultSet object. This method convert ResultSet to List<Map<String, Object>>
\r
45 * @return converted data.
\r
47 public List<Map<String, Object>> executeQuery(String sql) throws SQLException {
\r
48 return executeQuery(sql, null, DEFALUT_CONNECTION);
\r
50 public List<Map<String, Object>> executeQuery(String sql, Map<String, Object> params) throws SQLException {
\r
51 return executeQuery(sql, params, DEFALUT_CONNECTION);
\r
53 public List<Map<String, Object>> executeQuery(String sql, Map<String, Object> params, String connectionName) throws SQLException {
\r
55 List<Map<String, Object>> result = new ArrayList<Map<String,Object>>();
\r
56 BindConnection con = null;
\r
57 BindPreparedStatement st = null;
\r
59 con = DBManager.getConnection(connectionName);
\r
60 st = con.bindPrepareStatement(sql);
\r
61 st.setParams(params);
\r
63 ResultSet rs = st.executeQuery();
\r
64 result = rsToMapList(rs);
\r
65 logger.debug("result count = "+ result.size());
\r
66 }catch (SQLException e) {
\r
67 // SQLException needs rethrow.
\r
70 try { st.close(); } catch (Exception e) {}
\r
71 try { con.close(); } catch (Exception e) {}
\r
77 * ResultSetからList<Map<String, Object>>に変換
\r
80 * @throws SQLException
\r
82 private List<Map<String, Object>> rsToMapList(ResultSet rs) throws SQLException{
\r
83 List<Map<String, Object>> result = new ArrayList<Map<String,Object>>();
\r
85 Map<String, Object> record = new LinkedHashMap<String, Object>();
\r
86 ResultSetMetaData metaData = rs.getMetaData();
\r
87 for(int i=1; i<metaData.getColumnCount()+1; i++){
\r
88 record.put(metaData.getColumnName(i), rs.getObject(i));
\r
96 * Executes the given SQL statement, which returns effective rows(INSERT/DELETE/UPDATE) or returns nothing(DDL);
\r
98 public int executeUpdate(String sql, Map<String, Object> params) throws SQLException {
\r
99 return executeUpdate(sql, params, DEFALUT_CONNECTION);
\r
101 public int executeUpdate(String sql, Map<String, Object> params, String connectionName) throws SQLException {
\r
104 BindConnection con = null;
\r
105 BindPreparedStatement st = null;
\r
107 con = DBManager.getConnection(connectionName);
\r
108 st = con.bindPrepareStatement(sql);
\r
109 st.setParams(params);
\r
111 result = st.executeUpdate();
\r
112 }catch (SQLException e) {
\r
113 // SQLException needs rethrow.
\r
116 try { st.close(); } catch (Exception e) {}
\r
117 try { con.close(); } catch (Exception e) {}
\r
126 * @throws SQLException
\r
127 * @throws InvocationTargetException
\r
128 * @throws NoSuchMethodException
\r
129 * @throws IllegalAccessException
\r
130 * @throws InstantiationException
\r
132 public <T> List<T> list(Class<T> clazz, String sql, Map<String, Object> params) throws SQLException {
\r
133 return list(clazz, sql, params, DEFALUT_CONNECTION);
\r
135 public <T> List<T> list(Class<T> clazz, String sql, Map<String, Object> params, String connectionName) throws SQLException {
\r
136 if(StringUtils.isEmpty(sql)){
\r
137 throw new SQLException("sql is empty["+ sql +"]");
\r
141 List<Map<String, Object>> list = executeQuery(sql, params);
\r
143 // make entity instance from result data.
\r
144 List<T> resultList = new ArrayList<T>();
\r
145 for(Map<String, Object> dataMap: list){
\r
146 resultList.add(mapToEntity(dataMap, clazz));
\r
153 * You have to insert ":offset" and ":limit" like this:
\r
154 * "SELECT * FROM MEMBER OFFSET :offset LIMIT :limit".
\r
157 * @param countSql SQL string for count all.
\r
159 * @param sql SQL string for select.
\r
162 * @throws SQLException
\r
163 * @throws InvocationTargetException
\r
164 * @throws NoSuchMethodException
\r
165 * @throws IllegalAccessException
\r
166 * @throws InstantiationException
\r
168 public <T> Pager<T> list(Class<T> clazz, String countSql, PageInfo pageInfo, String sql, Map<String, Object> params) throws SQLException{
\r
169 return list(clazz, countSql, pageInfo, sql, params, DEFALUT_CONNECTION);
\r
171 public <T> Pager<T> list(Class<T> clazz, String countSql, PageInfo pageInfo, String sql, Map<String, Object> params, String connectionName) throws SQLException {
\r
172 // execute count sql
\r
173 List<Map<String, Object>> list = executeQuery(sql);
\r
174 int count = (Integer)list.get(0).values().toArray()[0];
\r
177 int start = pageInfo.getPage() * pageInfo.getRows();
\r
178 sql.replace(":offset", String.valueOf(start));
\r
179 sql.replace(":limit", String.valueOf(pageInfo.getRows()));
\r
181 // params.put(":offset", start);
\r
182 // params.put(":limit", pageInfo.getRows());
\r
185 list = executeQuery(sql, params);
\r
187 // make entity instance from result data.
\r
188 Pager<T> pager = new Pager<T>(pageInfo);
\r
189 pager.setTotalCount(count);
\r
190 for(Map<String, Object> dataMap: list){
\r
191 pager.add(mapToEntity(dataMap, clazz));
\r
197 * SQLから呼び出した汎用Map<String, Object>からEntityに変換
\r
198 * try to set all columns to entity with java.lang.reflection
\r
204 * @throws InstantiationException
\r
205 * @throws IllegalAccessException
\r
206 * @throws NoSuchMethodException
\r
207 * @throws InvocationTargetException
\r
209 private <T> T mapToEntity(Map<String, Object> record, Class<T> clazz) throws SQLException{
\r
212 entity = clazz.newInstance();
\r
213 // for each map member, set value to entity
\r
214 for(Map.Entry<String, Object> column: record.entrySet()){
\r
215 // "MEMBER_ID_SEQ" -> "member_id_seq" -> "memberIdSeq"(Camel) -> "MemberIdSeq"(Capitalize) -> "setMemberIdSeq"(add "set")
\r
216 String setterName = "set"+StringUtils.capitalize(StringUtils.toCamelCase(column.getKey().toLowerCase()));
\r
217 Class<?> valueClass = column.getValue().getClass();
\r
219 // logger.debug(setterName +"("+valueClass.getSimpleName() +")");
\r
221 // プリミティブなら引数の方を変更する
\r
222 Class<?> primitiveType = ClassUtils.wrapperToPrimitive(valueClass);
\r
223 if(primitiveType!=null){
\r
224 valueClass = primitiveType;
\r
227 // SQLTimestamp型はjava.util.Date型で処理する
\r
228 if(valueClass.getName().equals(java.sql.Timestamp.class.getName())){
\r
229 valueClass = java.util.Date.class;
\r
233 Method setterMethod = clazz.getMethod(setterName, valueClass);
\r
234 setterMethod.invoke(entity, column.getValue());
\r
236 } catch (Exception e) {
\r
237 throw new SQLException(e);
\r