今回は、JNDI(Java Naming and Directory Interface)を利用したデータベースアクセスを実行してみたので、そのサンプルプログラムを共有する。
なお、JNDIとは、コンピュータネットワーク上にあらかじめ登録されたデータやオブジェクトを、名前で発見し参照するための標準的なインターフェース仕様を定義したものをいう。
前提条件
下記記事の実装が完了していること
サンプルプログラムの内容
今回のサンプルプログラムの構成は以下の通り。
なお、上記赤枠が前提条件のプログラムと変更になった箇所で、「DemoDbConfig.java」「DemoDbRepository.java」が新規で作成したプログラムで、他は変更したプログラムとなる。また、MyBatisに関連する「UserDataMapper.java」「UserDataMapper.xml」「DemoSqlInvocation.java」は削除している。
build.gradleの内容は以下の通りで、mybatisについての設定を削除し、tomcat-jdbcを利用するための設定を追加している。
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名を追加している。
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接続情報を登録している。
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接続情報の取得を行っている。
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メソッドを利用するよう修正している。
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接続情報を取得すればよい。