今回は、JNDI(Java Naming and Directory Interface)を利用したデータベースアクセスを実行してみたので、そのサンプルプログラムを共有する。
なお、JNDIとは、コンピュータネットワーク上にあらかじめ登録されたデータやオブジェクトを、名前で発見し参照するための標準的なインターフェース仕様を定義したものをいう。
前提条件
下記記事の実装が完了していること
サンプルプログラムの内容
今回のサンプルプログラムの構成は以下の通り。
なお、上記赤枠が前提条件のプログラムと変更になった箇所で、「DemoDbConfig.java」「DemoDbRepository.java」が新規で作成したプログラムで、他は変更したプログラムとなる。また、MyBatisに関連する「UserDataMapper.java」「UserDataMapper.xml」「DemoSqlInvocation.java」は削除している。
build.gradleの内容は以下の通りで、mybatisについての設定を削除し、tomcat-jdbcを利用するための設定を追加している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | plugins { id 'org.springframework.boot' version '2.1.7.RELEASE' id 'java' } apply plugin: 'io.spring.dependency-management' group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8' repositories { mavenCentral() } configurations { //log4j2を利用するため、Spring BootデフォルトのLogbackを利用しないよう設定 all*.exclude module : 'spring-boot-starter-logging' } dependencies { implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' compileOnly 'org.projectlombok:lombok:1.18.10' annotationProcessor 'org.projectlombok:lombok:1.18.10' compile files('lib/ojdbc6.jar') compile group: 'org.springframework.data', name: 'spring-data-commons-core', version: '1.1.0.RELEASE' //log4j2を利用するための設定 compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.12.1' compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.12.1' //AOPを利用するための設定 implementation 'org.springframework.boot:spring-boot-starter-aop' //log4j2の設定でymlファイルを利用するための設定 compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.10.1' compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.10.1' compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.10.1' //Apache Common JEXLを利用するための設定 compile group: 'org.apache.commons', name: 'commons-jexl3', version: '3.0' //tomcat-jdbcを利用するための設定 compile group: 'org.apache.tomcat', name: 'tomcat-jdbc', version: '9.0.30' } |
application.ymlは以下の通りで、「jdbc/demoJndiResource」というJNDI名を追加している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | server: port: 8084 # DB接続情報 spring: datasource: name: jdbc/demoJndiResource url: jdbc:oracle:thin:@localhost:1521:xe username: USER01 password: USER01 driverClassName: oracle.jdbc.driver.OracleDriver # 一覧画面で1ページに表示する行数 demo: list: pageSize: 2 |
さらに、データソースの設定クラスは以下の通りで、組み込みTomcatにデータベースJNDI接続情報を登録している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | package com.example.demo; import org.apache.catalina.Context; import org.apache.catalina.startup.Tomcat; import org.apache.tomcat.util.descriptor.web.ContextResource; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; /** * データソース設定クラス */ @Configuration public class DemoDbConfig { /** * データソース名(application.propertiesから取得) */ @Value("${spring.datasource.name}") private String jndiName; /** * データベースURL(application.propertiesから取得) */ @Value("${spring.datasource.url}") private String url; /** * データベースユーザー名(application.propertiesから取得) */ @Value("${spring.datasource.username}") private String username; /** * データベースパスワード(application.propertiesから取得) */ @Value("${spring.datasource.password}") private String password; @Bean public TomcatServletWebServerFactory tomcatFactory(){ //組み込みTomcatにデータベースJNDI接続情報を登録 return new TomcatServletWebServerFactory(){ @Override protected TomcatWebServer getTomcatWebServer(Tomcat tomcat){ tomcat.enableNaming(); return super.getTomcatWebServer(tomcat); } @Override protected void postProcessContext(Context context) { ContextResource resource = new ContextResource(); resource.setProperty("factory", "org.apache.tomcat.jdbc.pool.DataSourceFactory"); resource.setName(jndiName); resource.setType(DataSource.class.getName()); resource.setProperty("driverClassName", "oracle.jdbc.driver.OracleDriver"); resource.setProperty("url", url); resource.setProperty("username", username); resource.setProperty("password", password); context.getNamingResources().addResource(resource); } }; } } |
また、SQLによるデータベースアクセス処理は以下の通りで、DBコネクションの取得はgetDbConnectionメソッド内で行っていて、InitialContextクラスのlookupメソッドによりJNDI接続情報の取得を行っている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 | package com.example.demo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Repository; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.Statement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; @Repository public class DemoDbRepository { //ログ出力のためのクラス private Logger logger = LogManager.getLogger(DemoDbRepository.class); /** * データソース名(application.propertiesから取得) */ @Value("${spring.datasource.name}") private String jndiName; /** * 指定したIDをもつユーザーデータテーブル(user_data)のデータを取得するSQL */ private static final String findByIdSql = "SELECT id, name" + ", birth_year AS birthY, birth_month AS birthM, birth_day AS birthD " + ", sex, memo FROM USER_DATA WHERE id = ?"; /** * 指定したIDをもつユーザーデータテーブル(user_data)のデータを削除するSQL */ private static final String deleteSql = "DELETE FROM USER_DATA WHERE id = ?"; /** * 指定したユーザーデータテーブル(user_data)のデータを追加するSQL */ private static final String insertSql = "INSERT INTO USER_DATA ( id, name " + ", birth_year, birth_month, birth_day, sex, memo ) " + " VALUES ( ?, ?, ?, ?, ?, ?, ? ) "; /** * 指定したユーザーデータテーブル(user_data)のデータを更新するSQL */ private static final String updateSql = "UPDATE USER_DATA SET name = ? " + ", birth_year = ?, birth_month = ?, birth_day = ?, sex = ?" + ", memo = ? WHERE id = ?"; /** * ユーザーデータテーブル(user_data)の最大値IDを取得するSQL */ private static final String findMaxIdSql = "SELECT NVL(max(id), 0) AS maxId FROM USER_DATA"; /** * ユーザーデータテーブル(user_data)から検索条件に合うデータを取得する * @param searchForm 検索用Formオブジェクト * @param pageable ページネーションオブジェクト * @return ユーザーデータテーブル(user_data)の検索条件に合うデータ */ public List<UserData> findBySearchForm(SearchForm searchForm, Pageable pageable){ List<UserData> userDataList = new ArrayList<>(); Connection conn = getDbConnection(); PreparedStatement stmt = null; ResultSet rs = null; try{ String selectSql = getFindBySearchSql(searchForm, pageable); stmt = conn.prepareStatement(selectSql); logger.info(selectSql); rs = stmt.executeQuery(); while(rs.next()){ UserData userData = new UserData(); userData.setId(rs.getLong("id")); userData.setName(rs.getString("name")); userData.setBirthY(rs.getInt("birthY")); userData.setBirthM(rs.getInt("birthM")); userData.setBirthD(rs.getInt("birthD")); userData.setSex(String.valueOf(rs.getInt("sex"))); userData.setMemo(rs.getString("memo")); userData.setSex_value(rs.getString("sex_value")); userDataList.add(userData); } }catch (SQLException e){ e.printStackTrace(); }finally { closeResultSet(rs); closeStatement(stmt); closeDbConnection(conn); } return userDataList; } /** * ユーザーデータテーブル(user_data)から検索条件に合うデータを取得するSQLを生成する * @param searchForm 検索用Formオブジェクト * @param pageable ページネーションオブジェクト * @return ユーザーデータテーブル(user_data)から取得するSQL */ private String getFindBySearchSql(SearchForm searchForm, Pageable pageable){ StringBuilder sb = new StringBuilder(); sb.append("SELECT u.id, u.name, u.birth_year as birthY, u.birth_month as birthM "); sb.append(", u.birth_day as birthD, u.sex, u.memo, u.sex_value "); sb.append("FROM ( SELECT "); sb.append("u1.id, u1.name, u1.birth_year, u1.birth_month, u1.birth_day "); sb.append(", u1.sex, u1.memo, m.sex_value, ROW_NUMBER() OVER (ORDER BY u1.id) AS rn "); sb.append(" FROM USER_DATA u1, M_SEX m "); sb.append(" WHERE u1.sex = m.sex_cd "); if(!DateCheckUtil.isEmpty(searchForm.getSearchName())){ sb.append(" AND u1.name like '%" + searchForm.getSearchName() + "%' "); } if(!DateCheckUtil.isEmpty(searchForm.getFromBirthYear())){ sb.append(" AND " + searchForm.getFromBirthYear() + " || lpad(" + searchForm.getFromBirthMonth() + ", 2, '0')" + " || lpad(" + searchForm.getFromBirthDay() + ", 2, '0')" + " <= u1.birth_year || lpad(u1.birth_month, 2, '0') " + "|| lpad(u1.birth_day, 2, '0') "); } if(!DateCheckUtil.isEmpty(searchForm.getToBirthYear())){ sb.append(" AND u1.birth_year || lpad(u1.birth_month, 2, '0') " + "|| lpad(u1.birth_day, 2, '0') " + " <= " + searchForm.getToBirthYear() + "|| lpad(" + searchForm.getToBirthMonth() + ", 2, '0')" + "|| lpad(" + searchForm.getToBirthDay() + ", 2, '0') "); } if(!DateCheckUtil.isEmpty(searchForm.getSearchSex())){ sb.append(" AND u1.sex = " + searchForm.getSearchSex()); } sb.append(" ORDER BY u1.id"); sb.append(" ) u"); if(pageable != null && pageable.getPageSize() > 0){ sb.append(" WHERE u.rn BETWEEN " + pageable.getOffset() + " AND " + (pageable.getOffset() + pageable.getPageSize() - 1)); } return sb.toString(); } /** * 指定したIDをもつユーザーデータテーブル(user_data)のデータを取得する * @param id ID * @return ユーザーデータテーブル(user_data)の指定したIDのデータ */ public UserData findById(Long id){ UserData userData = null; Connection conn = getDbConnection(); PreparedStatement stmt = null; ResultSet rs = null; try{ stmt = conn.prepareStatement(findByIdSql); stmt.setLong(1, id); logger.info(findByIdSql); logger.info("Parameters: " + id + "(Long)"); rs = stmt.executeQuery(); while(rs.next()){ userData = new UserData(); userData.setId(rs.getLong("id")); userData.setName(rs.getString("name")); userData.setBirthY(rs.getInt("birthY")); userData.setBirthM(rs.getInt("birthM")); userData.setBirthD(rs.getInt("birthD")); userData.setSex(String.valueOf(rs.getInt("sex"))); userData.setMemo(rs.getString("memo")); } }catch (SQLException e){ e.printStackTrace(); }finally { closeResultSet(rs); closeStatement(stmt); closeDbConnection(conn); } return userData; } /** * 指定したIDをもつユーザーデータテーブル(user_data)のデータを削除する * @param id ID */ public void deleteById(Long id){ Connection conn = getDbConnection(); PreparedStatement stmt = null; try{ stmt = conn.prepareStatement(deleteSql); stmt.setLong(1, id); logger.info(deleteSql); logger.info("Parameters: " + id + "(Long)"); stmt.executeUpdate(); commitDbConnection(conn); }catch (SQLException e){ rollbackDbConnection(conn); e.printStackTrace(); }finally { closeStatement(stmt); closeDbConnection(conn); } } /** * 指定したユーザーデータテーブル(user_data)のデータを追加する * @param userData ユーザーデータテーブル(user_data)の追加データ */ public void create(UserData userData){ Connection conn = getDbConnection(); PreparedStatement stmt = null; try{ stmt = conn.prepareStatement(insertSql); stmt.setLong(1, userData.getId()); stmt.setString(2, userData.getName()); stmt.setInt(3, userData.getBirthY()); stmt.setInt(4, userData.getBirthM()); stmt.setInt(5, userData.getBirthD()); stmt.setString(6, userData.getSex()); stmt.setString(7, userData.getMemo()); logger.info(insertSql); logger.info("Parameters: " + userData.getId() + "(Long), " + userData.getName() + "(String), " + userData.getBirthY() + "(Integer), " + userData.getBirthM() + "(Integer), " + userData.getBirthD() + "(Integer), " + userData.getSex() + "(String), " + userData.getMemo() + "(String) "); stmt.executeUpdate(); commitDbConnection(conn); }catch (SQLException e){ rollbackDbConnection(conn); e.printStackTrace(); }finally { closeStatement(stmt); closeDbConnection(conn); } } /** * 指定したユーザーデータテーブル(user_data)のデータを更新する * @param userData ユーザーデータテーブル(user_data)の更新データ */ public void update(UserData userData){ Connection conn = getDbConnection(); PreparedStatement stmt = null; try{ stmt = conn.prepareStatement(updateSql); stmt.setString(1, userData.getName()); stmt.setInt(2, userData.getBirthY()); stmt.setInt(3, userData.getBirthM()); stmt.setInt(4, userData.getBirthD()); stmt.setString(5, userData.getSex()); stmt.setString(6, userData.getMemo()); stmt.setLong(7, userData.getId()); logger.info(updateSql); logger.info("Parameters: " + userData.getName() + "(String), " + userData.getBirthY() + "(Integer), " + userData.getBirthM() + "(Integer), " + userData.getBirthD() + "(Integer), " + userData.getSex() + "(String), " + userData.getMemo() + "(String), " + userData.getId() + "(Long)"); stmt.executeUpdate(); commitDbConnection(conn); }catch (SQLException e){ rollbackDbConnection(conn); e.printStackTrace(); }finally { closeStatement(stmt); closeDbConnection(conn); } } /** * ユーザーデータテーブル(user_data)の最大値IDを取得する * @return ユーザーデータテーブル(user_data)の最大値ID */ public long findMaxId(){ long maxId = 0; Connection conn = getDbConnection(); PreparedStatement stmt = null; ResultSet rs = null; try{ stmt = conn.prepareStatement(findMaxIdSql); logger.info(findMaxIdSql); rs = stmt.executeQuery(); while(rs.next()){ maxId = rs.getLong("maxId"); } }catch (SQLException e){ e.printStackTrace(); }finally { closeResultSet(rs); closeStatement(stmt); closeDbConnection(conn); } return maxId; } /** * データベースコネクションを取得する * @return データベースコネクション */ private Connection getDbConnection(){ Connection conn = null; try{ // DemoDbConfig.javaで登録したjndiNameに紐付くデータベース接続情報を取得 InitialContext context = new InitialContext(); DataSource dataSource = (DataSource)context.lookup("java:comp/env/" + jndiName); conn = dataSource.getConnection(); } catch (SQLException e) { e.printStackTrace(); } catch (NamingException e) { e.printStackTrace(); } return conn; } /** * ResultSetオブジェクトを閉じる * @param rs Statementオブジェクト */ private void closeResultSet(ResultSet rs){ try{ if(rs != null){ rs.close(); } }catch(SQLException e){ e.printStackTrace(); } } /** * データベースコネクションをコミットする * @param conn データベースコネクション */ private void commitDbConnection(Connection conn){ try{ if(conn != null){ conn.commit(); } }catch(SQLException e){ e.printStackTrace(); } } /** * データベースコネクションをロールバックする * @param conn データベースコネクション */ private void rollbackDbConnection(Connection conn){ try{ if(conn != null){ conn.rollback(); } }catch(SQLException e){ e.printStackTrace(); } } /** * Statementオブジェクトを閉じる * @param stmt Statementオブジェクト */ private void closeStatement(Statement stmt){ try{ if(stmt != null){ stmt.close(); } }catch(SQLException e){ e.printStackTrace(); } } /** * データベースコネクションを閉じる * @param conn データベースコネクション */ private void closeDbConnection(Connection conn){ try{ if(conn != null){ conn.close(); } }catch(SQLException e){ e.printStackTrace(); } } } |
さらに、サービスの実装クラスの内容は以下の通りで、SQL実行を先ほどのDemoDbRepository.javaクラスのpublicメソッドを利用するよう修正している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | package com.example.demo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.BindingResult; import org.springframework.data.domain.Pageable; import java.util.ArrayList; import java.util.List; @Service public class DemoServiceImpl implements DemoService{ /** * ユーザーデータテーブル(user_data)へアクセスするリポジトリ */ @Autowired private DemoDbRepository repository; /** * 1ページに表示する行数(application.propertiesから取得) */ @Value("${demo.list.pageSize}") private String listPageSize; /** * {@inheritDoc} */ @Override public List<DemoForm> demoFormList(SearchForm searchForm, Pageable pageable) { List<DemoForm> demoFormList = new ArrayList<>(); //ユーザーデータテーブル(user_data)から検索条件に合うデータを取得する List<UserData> userDataList = repository.findBySearchForm(searchForm, pageable); for (UserData userData : userDataList) { demoFormList.add(getDemoForm(userData)); } return demoFormList; } /** * {@inheritDoc} */ @Override public DemoForm findById(String id) { Long longId = stringToLong(id); UserData userData = repository.findById(longId); return getDemoForm(userData); } /** * {@inheritDoc} */ @Override @Transactional(readOnly = false) public void deleteById(String id){ Long longId = stringToLong(id); repository.deleteById(longId); } /** * {@inheritDoc} */ @Override @Transactional(readOnly = false) public void createOrUpdate(DemoForm demoForm){ //更新・追加処理を行うエンティティを生成 UserData userData = getUserData(demoForm); //追加・更新処理 if(demoForm.getId() == null){ userData.setId(repository.findMaxId() + 1); repository.create(userData); }else{ repository.update(userData); } } /** * {@inheritDoc} */ @Override public String checkForm(DemoForm demoForm, BindingResult result, String normalPath){ //formオブジェクトのチェック処理を行う if(result.hasErrors()){ //エラーがある場合は、入力画面のままとする return "input"; } //生年月日の日付チェック処理を行う //エラーがある場合は、エラーメッセージ・エラーフィールドの設定を行い、 //入力画面のままとする int checkDate = DateCheckUtil.checkDate(demoForm.getBirthYear() , demoForm.getBirthMonth(), demoForm.getBirthDay()); switch(checkDate){ case 1: //生年月日_年が空文字の場合のエラー処理 result.rejectValue("birthYear", "validation.date-empty" , new String[]{"生年月日_年"}, ""); return "input"; case 2: //生年月日_月が空文字の場合のエラー処理 result.rejectValue("birthMonth", "validation.date-empty" , new String[]{"生年月日_月"}, ""); return "input"; case 3: //生年月日_日が空文字の場合のエラー処理 result.rejectValue("birthDay", "validation.date-empty" , new String[]{"生年月日_日"}, ""); return "input"; case 4: //生年月日の日付が不正な場合のエラー処理 result.rejectValue("birthYear", "validation.date-invalidate"); //生年月日_月・生年月日_日は、エラーフィールドの設定を行い、 //メッセージを空文字に設定している result.rejectValue("birthMonth", "validation.empty-msg"); result.rejectValue("birthDay", "validation.empty-msg"); return "input"; case 5: //生年月日の日付が未来日の場合のエラー処理 result.rejectValue("birthYear", "validation.date-future"); //生年月日_月・生年月日_日は、エラーフィールドの設定を行い、 //メッセージを空文字に設定している result.rejectValue("birthMonth", "validation.empty-msg"); result.rejectValue("birthDay", "validation.empty-msg"); return "input"; default: //性別が不正に書き換えられていないかチェックする if(!demoForm.getSexItems().keySet().contains(demoForm.getSex())){ result.rejectValue("sex", "validation.sex-invalidate"); return "input"; } //エラーチェックに問題が無いので、正常時の画面遷移先に遷移 return normalPath; } } /** * {@inheritDoc} */ @Override public String checkSearchForm(SearchForm searchForm, BindingResult result){ int checkDate =DateCheckUtil.checkSearchForm(searchForm); switch (checkDate){ case 1: //生年月日_fromが不正な場合のエラー処理 result.rejectValue("fromBirthYear", "validation.date-invalidate-from"); result.rejectValue("fromBirthMonth", "validation.empty-msg"); result.rejectValue("fromBirthDay", "validation.empty-msg"); return "search"; case 2: //生年月日_toが不正な場合のエラー処理 result.rejectValue("toBirthYear", "validation.date-invalidate-to"); result.rejectValue("toBirthMonth", "validation.empty-msg"); result.rejectValue("toBirthDay", "validation.empty-msg"); return "search"; case 3: //生年月日_from>生年月日_toの場合のエラー処理 result.rejectValue("fromBirthYear", "validation.date-invalidate-from-to"); result.rejectValue("fromBirthMonth", "validation.empty-msg"); result.rejectValue("fromBirthDay", "validation.empty-msg"); result.rejectValue("toBirthYear", "validation.empty-msg"); result.rejectValue("toBirthMonth", "validation.empty-msg"); result.rejectValue("toBirthDay", "validation.empty-msg"); return "search"; default: //正常な場合はnullを返却 return null; } } /** * {@inheritDoc} */ @Override public Pageable getPageable(int pageNumber){ Pageable pageable = new Pageable() { @Override public int getPageNumber() { //現在ページ数を返却 return pageNumber; } @Override public int getPageSize() { //1ページに表示する行数を返却 //listPageSizeは、本プログラムの先頭に定義している return Integer.parseInt(listPageSize); } @Override public int getOffset() { //表示開始位置を返却 //例えば、1ページに2行表示する場合の、2ページ目の表示開始位置は //(2-1)*2+1=3 で計算される return ((pageNumber - 1) * Integer.parseInt(listPageSize) + 1); } @Override public Sort getSort() { //ソートは使わないのでnullを返却 return null; } }; return pageable; } /** * {@inheritDoc} */ @Override public int getAllPageNum(SearchForm searchForm) { //1ページに表示する行数を取得 int listPageSizeNum = Integer.parseInt(listPageSize); if(listPageSizeNum == 0){ return 1; } //一覧画面に表示する全データを取得 //第二引数のpageableにnullを設定することで、一覧画面に表示する全データが取得できる List<UserData> userDataList = repository.findBySearchForm(searchForm, null); //全ページ数を計算 //例えば、1ページに2行表示する場合で、全データ件数が5の場合、 //(5+2-1)/2=3 と計算される int allPageNum = (userDataList.size() + listPageSizeNum - 1) / listPageSizeNum; return allPageNum == 0 ? 1 : allPageNum; } /** * DemoFormオブジェクトに引数のユーザーデータの各値を設定する * @param userData ユーザーデータ * @return DemoFormオブジェクト */ private DemoForm getDemoForm(UserData userData){ if(userData == null){ return null; } DemoForm demoForm = new DemoForm(); demoForm.setId(String.valueOf(userData.getId())); demoForm.setName(userData.getName()); demoForm.setBirthYear(String.valueOf(userData.getBirthY())); demoForm.setBirthMonth(String.valueOf(userData.getBirthM())); demoForm.setBirthDay(String.valueOf(userData.getBirthD())); demoForm.setSex(userData.getSex()); demoForm.setMemo(userData.getMemo()); demoForm.setSex_value(userData.getSex_value()); return demoForm; } /** * UserDataオブジェクトに引数のフォームの各値を設定する * @param demoForm DemoFormオブジェクト * @return ユーザーデータ */ private UserData getUserData(DemoForm demoForm){ UserData userData = new UserData(); if(!DateCheckUtil.isEmpty(demoForm.getId())){ userData.setId(Long.valueOf(demoForm.getId())); } userData.setName(demoForm.getName()); userData.setBirthY(Integer.valueOf(demoForm.getBirthYear())); userData.setBirthM(Integer.valueOf(demoForm.getBirthMonth())); userData.setBirthD(Integer.valueOf(demoForm.getBirthDay())); userData.setSex(demoForm.getSex()); userData.setMemo(demoForm.getMemo()); userData.setSex_value(demoForm.getSex_value()); return userData; } /** * 引数の文字列をLong型に変換する * @param id ID * @return Long型のID */ private Long stringToLong(String id){ try{ return Long.parseLong(id); }catch(NumberFormatException ex){ return null; } } } |
その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-jndi/demo
サンプルプログラムの実行結果
画面の動作内容は、下記記事と同じ実行結果になる。
また、ログ出力例は以下の通りで、SQL実行内容も含めログ出力される。
要点まとめ
- JNDIを利用したDB接続を実装するには、あらかじめ組み込みTomcatにデータベースJNDI接続情報を登録しておき、InitialContextクラスのlookupメソッドで、そのJNDI接続情報を取得すればよい。