質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

2回答

3406閲覧

JavaでSQLファイルの個人情報部分をマスキングして新しいテストファイルを作る方法がわからない。

zeuma

総合スコア6

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

1グッド

1クリップ

投稿2019/10/04 16:33

前提・実現したいこと

SQLファイルの中に大量の顧客データが入っており、それをJavaを用いてマスキングしたいです。具体的には、JavaでそのSQLファイルを読み込んで、個人情報がマスキングされたバージョンのSQLファイルを新たに生成するJavaプログラムを作りたいです。

発生している問題・エラーメッセージ

JavaでSQLファイルの必要部分をマスキングして新しいテストファイルを作る方法がわからない。

該当のソースコード

SQL

1INSERT INTO `wp_postmeta` (`meta_id`, `post_id`, `meta_key`, `meta_value`) VALUES 2... 3(112, 32, '_customer_user', '11'), 4(113, 32, '_payment_method', 'cod'), 5(114, 32, '_payment_method_title', '代金引換'), 6(115, 32, '_customer_ip_address', '::1'), 7(116, 32, '_customer_user_agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'), 8(117, 32, '_created_via', 'checkout'), 9(118, 32, '_cart_hash', '87df4e6e684584c5061fed4b9e6f1063'), 10(119, 32, '_billing_first_name', '利人'), 11(120, 32, '_billing_last_name', '遠藤'), 12(121, 32, '_billing_address_1', '8-9-1'), 13(122, 32, '_billing_city', '四万十市西土佐岩間'), 14(123, 32, '_billing_state', 'JP39'), 15(124, 32, '_billing_postcode', '787-1321'), 16(125, 32, '_billing_country', 'JP'), 17(126, 32, '_billing_email', 'endou72@example.com'), 18(127, 32, '_billing_phone', '090-7716-5803'), 19(128, 32, '_order_currency', 'JPY'), 20(129, 32, '_cart_discount', '0'), 21(130, 32, '_cart_discount_tax', '0'), 22(131, 32, '_order_shipping', '0'), 23(132, 32, '_order_shipping_tax', '0'), 24(133, 32, '_order_tax', '0'), 25(134, 32, '_order_total', '11700'), 26(135, 32, '_order_version', '3.7.0'), 27(136, 32, '_prices_include_tax', 'no'), 28(137, 32, '_billing_address_index', '利人 遠藤 8-9-1 四万十市西土佐岩間 JP39 787-1321 JP endou72@example.com 090-7716-5803'), 29(138, 32, '_shipping_address_index', ' '), 30(139, 32, 'is_vat_exempt', 'no'), 31(140, 32, '_download_permissions_granted', 'yes'), 32(141, 32, '_recorded_sales', 'yes'), 33(142, 32, '_recorded_coupon_usage_counts', 'yes'), 34(143, 32, '_order_stock_reduced', 'yes'), 35

ここにより詳細な情報を記載してください。

上記コードのように、個人情報は4列目に記載されていて、3列目のkeyと紐づけられているので、Javaで3列目のkeyが例えば'?billing_address_index'の場合は、最後の何文字は*に置換する、といったようにして個人情報をマスキングしたいです。
ただ、全てのデータをユニークなままにしたいので、全ての文字を*に置換するということはしたくありません。

A-pZ👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

SQLパーサ(またはデパーサ機能があるもの)についてはいくつかありますが、MySQLの一括INSERTに対応できるパーサ・デパーサは、JSQLParser:https://github.com/JSQLParser/JSqlParser があります。

java

1package com.github.apz.java8sample; 2 3import java.io.File; 4import java.nio.charset.Charset; 5import java.nio.file.Files; 6import java.util.List; 7import java.util.stream.Collectors; 8 9import net.sf.jsqlparser.expression.Expression; 10import net.sf.jsqlparser.expression.operators.relational.ExpressionList; 11import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList; 12import net.sf.jsqlparser.parser.CCJSqlParserUtil; 13import net.sf.jsqlparser.schema.Column; 14import net.sf.jsqlparser.statement.Statement; 15import net.sf.jsqlparser.statement.insert.Insert; 16 17/** 18 * JSQL Insertパーサの実装例 19 * @author a-pz 20 * 21 */ 22public class JSQLInsertSample { 23 24 public static void main(String[] args) throws Exception { 25 JSQLInsertSample sample = new JSQLInsertSample(); 26 sample.execute(); 27 } 28 29 public void execute() throws Exception { 30 String sql = getSQL("insert.sql"); 31 32 Statement statement = CCJSqlParserUtil.parse(sql); 33 Insert insert = (Insert) statement; 34 35 // INSERTのcolumn 36 List<Column> columns = insert.getColumns(); 37 columns.stream().forEach(column -> { 38 System.out.println(column.getColumnName()); 39 }); 40 41 // INSERT文のVALUES要素をすべて取得 42 MultiExpressionList itemsList = (MultiExpressionList)insert.getItemsList(); 43 44 // VALUES要素を1行ごとにListへ展開 45 List<ExpressionList> expressionList = itemsList.getExprList(); 46 47 expressionList.forEach(explist -> { 48 List<Expression> expression = explist.getExpressions(); 49 50 expression.forEach(exp -> { 51 System.out.print( exp.toString() + ", "); 52 }); 53 System.out.println(); 54 }); 55 } 56 57 String getClasspath() { 58 String classpath = Thread.currentThread().getContextClassLoader().getResource("").getPath(); 59 return classpath; 60 } 61 62 String getSQL(String filename) throws Exception { 63 String sqlfile = getClasspath() + filename; 64 File file = new File(sqlfile); 65 List<String> lines = Files.readAllLines( file.toPath() , Charset.forName("utf-8")); 66 String sql = lines.stream().collect(Collectors.joining("\r\n")); 67 return sql; 68 } 69} 70

これを利用すれば、INSERT文を一気にマスク化したSQLに変換できるでしょう。

投稿2019/10/05 01:19

A-pZ

総合スコア12011

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

マスキングされたユニークな値を持つテーブルを自力で作成していくしか方法は無いように思います。愚直な例ですが、

  1. 分かり易く処理対象を限定するために、{meta_key, meta_value}を1要素とする全データ、N件のテーブル st を初期データとして作成する。
  2. stを対象に、meta_keyの数、つまりN件分の処理を行う。ループカウンターを i として、1...N 間ループする。

2-1. st[i] の meta_value をもとに、最後の何文字かを *でマスクする。これを候補値 rv とする。
2-2. 候補値 rv が、テーブルst 内の st[i] 以外の要素に存在しないか確認する。
(a) 存在しない場合
ユニークな値であることが確定したので、st[i] の meta_value を rvにする。
(b) 既に存在する場合
候補値 rvはユニークではないので、衝突しないであろう別の値に改変し、rvの値を再生成する。2-2へ戻る。

  1. ループ終了。上記1,2で処理済のstの値は、meta_valueがマスキングされたユニークなデータとなる。

少なくとも個人的にはロジックだけの問題だと思いますので、コードでの例示は省きます。
また、上記で言うテーブルst のような要素のコレクションに対して、Javaで使い得るラムダ式を併用したような関数型プログラミングをすれば、よりスマートに見えるコードが書けるようにも思います。

投稿2019/10/04 17:33

編集2019/10/04 17:54
dodox86

総合スコア9183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問