今回は、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接続情報を取得すればよい。





