Spring Boot DB連携

Spring Bootで改行コードを変換してDBに登録してみた

テキストエリアで改行コードを含むデータをデータベースに登録する際、改行コードを何も変換しなければそのままの状態で登録されるが、別の文字列に変換し登録することもできる。

今回は、改行コードを「&#10」という文字列に変換して登録してみたので、そのサンプルプログラムを共有する。

前提条件

下記記事の実装が完了していること。

Spring BootでJavaScriptによるチェック処理を実装してみたこれまでは、Spring Bootによるチェック処理を利用してきたが、今回はJavaScriptによって同等のチェック処理を実装してみた...

サンプルプログラムの作成

作成したサンプルプログラムの構成は以下の通り。
サンプルプログラムの構成
なお、上記の赤枠は、前提条件のプログラムから追加/変更したプログラムである。

今回追加したユーティリティクラスの内容は以下の通りで、改行コードを「&#10」に変換するメソッドと、「&#10」を改行コードに戻すメソッドを用意している。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.example.demo;
import org.thymeleaf.util.StringUtils;
//ユーティリティクラス
public class DemoUtil {
/**
* 改行コード
*/
private static final String LINE_SEP = System.getProperty("line.separator");
/**
* 変換後の改行コード
*/
private static final String ENCODE_LINE_SEP = "&#10";
/**
* 引数の文字列に改行コードが含まれている場合に、変換後の改行コードに変換する
* @param str 任意の文字列
* @return 変換後の文字列
*/
public static String encodeNewLine(String str){
if(StringUtils.isEmpty(str)){
return str;
}
return str.replaceAll(LINE_SEP, ENCODE_LINE_SEP);
}
/**
* 引数の文字列に変換後の改行コードが含まれている場合に、改行コードに変換する
* @param str 任意の文字列
* @return 変換後の文字列
*/
public static String decodeNewLine(String str){
if(StringUtils.isEmpty(str)){
return str;
}
return str.replaceAll(ENCODE_LINE_SEP, LINE_SEP);
}
}
package com.example.demo; import org.thymeleaf.util.StringUtils; //ユーティリティクラス public class DemoUtil { /** * 改行コード */ private static final String LINE_SEP = System.getProperty("line.separator"); /** * 変換後の改行コード */ private static final String ENCODE_LINE_SEP = "&#10"; /** * 引数の文字列に改行コードが含まれている場合に、変換後の改行コードに変換する * @param str 任意の文字列 * @return 変換後の文字列 */ public static String encodeNewLine(String str){ if(StringUtils.isEmpty(str)){ return str; } return str.replaceAll(LINE_SEP, ENCODE_LINE_SEP); } /** * 引数の文字列に変換後の改行コードが含まれている場合に、改行コードに変換する * @param str 任意の文字列 * @return 変換後の文字列 */ public static String decodeNewLine(String str){ if(StringUtils.isEmpty(str)){ return str; } return str.replaceAll(ENCODE_LINE_SEP, LINE_SEP); } }
package com.example.demo;

import org.thymeleaf.util.StringUtils;

//ユーティリティクラス
public class DemoUtil {

    /**
     * 改行コード
     */
    private static final String LINE_SEP = System.getProperty("line.separator");

    /**
     * 変換後の改行コード
     */
    private static final String ENCODE_LINE_SEP = "&#10";

    /**
     * 引数の文字列に改行コードが含まれている場合に、変換後の改行コードに変換する
     * @param str 任意の文字列
     * @return 変換後の文字列
     */
    public static String encodeNewLine(String str){
        if(StringUtils.isEmpty(str)){
            return str;
        }
        return str.replaceAll(LINE_SEP, ENCODE_LINE_SEP);
    }

    /**
     * 引数の文字列に変換後の改行コードが含まれている場合に、改行コードに変換する
     * @param str 任意の文字列
     * @return 変換後の文字列
     */
    public static String decodeNewLine(String str){
        if(StringUtils.isEmpty(str)){
            return str;
        }
        return str.replaceAll(ENCODE_LINE_SEP, LINE_SEP);
    }
}



フリーランスエンジニアのエージェントは就業中でも無料で登録できるITエンジニアには、フリーランスという働き方がある。 フリーランスとは、会社や団体などに所属せず、仕事に応じて自由に契約する人のこ...

また、サービス実装クラスの内容は以下の通りで、getDemoFormメソッドでメモ欄の「&#10」を改行コードに戻し、getUserDataメソッドでメモ欄の改行コードを「&#10」に変換している。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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.data.domain.Pageable;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Service
public class DemoServiceImpl implements DemoService{
/**
* ユーザーデータテーブル(user_data)へアクセスするマッパー
*/
@Autowired
private UserDataMapper mapper;
/**
* 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)から検索条件に合うデータを取得する
Collection<UserData> userDataList = mapper.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 = mapper.findById(longId);
return getDemoForm(userData);
}
/**
* {@inheritDoc}
*/
@Override
@Transactional(readOnly = false)
public void deleteById(String id){
Long longId = stringToLong(id);
mapper.deleteById(longId);
}
/**
* {@inheritDoc}
*/
@Override
@Transactional(readOnly = false)
public void createOrUpdate(DemoForm demoForm){
//更新・追加処理を行うエンティティを生成
UserData userData = getUserData(demoForm);
//追加・更新処理
if(demoForm.getId() == null){
userData.setId(mapper.findMaxId() + 1);
mapper.create(userData);
}else{
mapper.update(userData);
}
}
/**
* {@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を設定することで、一覧画面に表示する全データが取得できる
Collection<UserData> userDataList = mapper.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(DemoUtil.decodeNewLine(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(!StringUtils.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(DemoUtil.encodeNewLine(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;
}
}
}
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.data.domain.Pageable; import org.springframework.util.StringUtils; import java.util.ArrayList; import java.util.Collection; import java.util.List; @Service public class DemoServiceImpl implements DemoService{ /** * ユーザーデータテーブル(user_data)へアクセスするマッパー */ @Autowired private UserDataMapper mapper; /** * 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)から検索条件に合うデータを取得する Collection<UserData> userDataList = mapper.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 = mapper.findById(longId); return getDemoForm(userData); } /** * {@inheritDoc} */ @Override @Transactional(readOnly = false) public void deleteById(String id){ Long longId = stringToLong(id); mapper.deleteById(longId); } /** * {@inheritDoc} */ @Override @Transactional(readOnly = false) public void createOrUpdate(DemoForm demoForm){ //更新・追加処理を行うエンティティを生成 UserData userData = getUserData(demoForm); //追加・更新処理 if(demoForm.getId() == null){ userData.setId(mapper.findMaxId() + 1); mapper.create(userData); }else{ mapper.update(userData); } } /** * {@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を設定することで、一覧画面に表示する全データが取得できる Collection<UserData> userDataList = mapper.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(DemoUtil.decodeNewLine(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(!StringUtils.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(DemoUtil.encodeNewLine(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; } } }
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.data.domain.Pageable;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Service
public class DemoServiceImpl implements DemoService{

    /**
     * ユーザーデータテーブル(user_data)へアクセスするマッパー
     */
    @Autowired
    private UserDataMapper mapper;

    /**
     * 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)から検索条件に合うデータを取得する
        Collection<UserData> userDataList = mapper.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 = mapper.findById(longId);
        return getDemoForm(userData);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @Transactional(readOnly = false)
    public void deleteById(String id){
        Long longId = stringToLong(id);
        mapper.deleteById(longId);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @Transactional(readOnly = false)
    public void createOrUpdate(DemoForm demoForm){
        //更新・追加処理を行うエンティティを生成
        UserData userData = getUserData(demoForm);
        //追加・更新処理
        if(demoForm.getId() == null){
            userData.setId(mapper.findMaxId() + 1);
            mapper.create(userData);
        }else{
            mapper.update(userData);
        }
    }

    /**
     * {@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を設定することで、一覧画面に表示する全データが取得できる
        Collection<UserData> userDataList = mapper.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(DemoUtil.decodeNewLine(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(!StringUtils.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(DemoUtil.encodeNewLine(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-change-new-line/demo

サンプルプログラムの実行結果

サンプルプログラムの実行結果は、以下の通り。

1) Spring Bootアプリケーションを起動し、「http://(サーバー名):(ポート番号)/」とアクセスし、検索ボタンを押下する。
サンプルプログラムの実行結果_1

2) 一覧画面に遷移するので、「データ追加」ボタンを押下する。
サンプルプログラムの実行結果_2

3) 入力画面で以下のような値を入力し、「確認」ボタンを押下する。
サンプルプログラムの実行結果_3

4) 確認画面に遷移するので、「送信」ボタンを押下する。
サンプルプログラムの実行結果_4

5) 以下のように、完了画面に遷移することが確認できる。
サンプルプログラムの実行結果_5

6) 登録されたデータを確認すると、メモ欄の改行コードが「&#10」と変換されていることが確認できる。
サンプルプログラムの実行結果_6

7) 登録されたデータを入力画面で表示し確認すると、メモ欄の改行コードがそのまま表示されることが確認できる。
サンプルプログラムの実行結果_7

8) 今回の修正を行う前は、以下のように、メモ欄の改行コード「CHR(13)||CHR(10)」がそのまま登録されている。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
select * from user_data where ID = 4
and MEMO = 'テスト' || CHR(13)||CHR(10) || '改行コードあり' || CHR(13)||CHR(10) || '登録メモ';
select * from user_data where ID = 4 and MEMO = 'テスト' || CHR(13)||CHR(10) || '改行コードあり' || CHR(13)||CHR(10) || '登録メモ';
select * from user_data where ID = 4 
and MEMO = 'テスト' || CHR(13)||CHR(10) || '改行コードあり' || CHR(13)||CHR(10) || '登録メモ'; 
サンプルプログラムの実行結果_8

要点まとめ

  • テキストエリアで改行コードを含むデータをデータベースに登録する際、別の文字列に変換し登録することもできる。その際、あらかじめユーティリティクラスを作っておくとよい。