【Java】DBから商品名・金額・税を取得し、商品名ごとの合計金額を算出する

■概要

DBの「商品コードマスタ」および「金額・税テーブル」から、商品コードに紐づく商品名、金額、税を取得し、商品名ごとの合計金額(金額+税)を算出する。

▼実行環境

実行環境を以下に示す。

  • Java:17
  • Mavenプロジェクト
  • MySQL:8系

■テーブル定義

本処理で使用するテーブル定義を以下に示す。

▼金額・税マージスキーマ

作成する「金額・税マージ」スキーマのSQLは以下の通り。

-- 金額・税マージスキーマ作成
CREATE DATABASE AmountTaxMerge;

▼商品コードマスタ

作成する「商品コード」マスタのテーブル定義、SQL、データは以下の通り。

・テーブル定義

FieldTypeNullKeyDefaultExtra
idchar(4)NOPRINULL
data_namevarchar(50)YESNULL

・SQL

-- 商品コードマスタ
CREATE TABLE m_data_name (
  	id CHAR(4) NOT NULL PRIMARY KEY,
    data_name VARCHAR(50)
);

・データ

INSERT INTO m_data_name(id, data_name) VALUES('0001', '商品A');
INSERT INTO m_data_name(id, data_name) VALUES('0002', '商品B');
INSERT INTO m_data_name(id, data_name) VALUES('0003', '商品C');
INSERT INTO m_data_name(id, data_name) VALUES('0004', '商品D');

▼金額・税テーブル

作成する「金額・税」テーブルのテーブル定義、SQL、データは以下の通り。

・テーブル定義

FieldTypeNullKeyDefaultExtra
data_idchar(4)NOMULNULL
amountvarchar(10)NONULL
taxvarchar(5)NONULL

・SQL

-- 金額・税テーブル
CREATE TABLE t_amount_tax (
	data_id CHAR(4) NOT NULL,
	amount VARCHAR(10) NOT NULL,
	tax VARCHAR(5) NOT NULL,
	FOREIGN KEY data_id_foreign_key(data_id) REFERENCES m_data_name(id)
);

・データ

INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0001', '100', '10');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0002', '200', '20');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0003', '300', '30');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0004', '400', '40');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0003', '500', '50');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0002', '600', '60');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0001', '700', '70');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0004', '800', '80');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0002', '900', '90');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0003', '1000', '100');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0001', '1100', '110');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0002', '1200', '120');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0003', '1300', '130');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0004', '1400', '140');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0001', '1500', '150');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0002', '1600', '160');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0003', '1700', '170');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0001', '1800', '180');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0004', '1900', '190');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0004', '2000', '200');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0004', '2100', '210');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0003', '2200', '220');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0004', '2300', '230');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0001', '2400', '240');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0001', '2500', '250');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0001', '2600', '260');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0002', '2700', '270');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0002', '2800', '280');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0004', '2900', '290');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0003', '3000', '300');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0003', '3100', '310');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0002', '3200', '320');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0002', '3300', '330');
INSERT INTO t_amount_tax(data_id, amount, tax) VALUES('0001', '3400', '340');

■pom.xmlの設定

DB接続用モジュールをpom.xmlに追加しておく

<!-- 一部抜粋 -->

    <!-- MySQL接続用 -->
    <dependency>
    	<groupId>mysql</groupId>
    	<artifactId>mysql-connector-java</artifactId>
    	<version>8.0.28</version>
	</dependency>

<!-- 一部抜粋 -->

■フローチャート

本処理に関する全体および各処理について、フローチャートを以下に示す。

▼全体概要のフロー

  • 「メインクラス」から「商品名・金額・税取得クラス」を呼び出す。
  • 「商品名・金額・税取得クラス」で「DB接続クラス」を呼び出し、DB接続する。
  • DBから、商品名、金額、税を取得し、「商品名・金額・税DAOクラス」へ格納する。
  • 「メインクラス」から「商品名・金額・税DAOクラス」の値を取得し、商品名ごとの合計金額を算出する。
開始
開始
メインクラス
メインクラス
商品名・金額・税
取得クラス
商品名・金額・税 取得クラス
商品名・金額・税
DAOクラス
商品名・金額・税 DAOクラス
DB接続クラス
DB接続クラス
DB
金額・税マージ
DB…
終了
終了
Text is not SVG – cannot display

▼各処理のフロー

・メインクラス(AmountTaxMergeMain.java)

開始
開始
商品名・金額・税取得クラス
インスタンス
商品名・金額・税取得クラス インスタンス
商品名・金額・税DAOのリストに
取得結果を格納
商品名・金額・税DAOのリストに…
出力用MAP初期化
出力用MAP初期化
取得したデータ分繰り返し
取得したデータ分繰り返し
商品名・金額・税取得
商品名・金額・税取得
金額+税算出
金額+税算出
MAPに
商品名
MAPに…
MAPから合計金額を取得し、加算
MAPから合計金額を取得し、加算
あり
あり
なし
なし
MAPの合計金額を更新
MAPの合計金額を更新
MAPへ商品名と金額を格納
MAPへ商品名と金額を格納
MAP分繰り返し
MAP分繰り返し
「商品名:合計金額」を出力
「商品名:合計金額」を出力
終了
終了
Text is not SVG – cannot display

商品名・金額・税取得クラス(SelectNameAmountTax.java)

開始
開始
商品名・金額・税DAOのリスト初期化
商品名・金額・税DAOのリスト初期化
DB接続クラスインスタンス
DB接続クラスインスタンス
try
try
DB接続
DB接続
ステートメントをセット
ステートメントをセット
SQL実行
SQL実行
実行件数分繰り返し
実行件数分繰り返し
商品名・金額・税DAOの
インスタンス
商品名・金額・税DAOの…
商品名・金額・税をセット
商品名・金額・税をセット
商品名・金額・税DAOのリストに格納
商品名・金額・税DAOのリストに格納
catch
catch
例外エラー出力
例外エラー出力
商品名・金額・税DAOのリストを返却
商品名・金額・税DAOのリストを返却
終了
終了
Text is not SVG – cannot display

・DB接続クラス(ConnectMysql.java)

開始
開始
コネクション情報初期化
コネクション情報初期化
try
try
ドライバ初期化
ドライバ初期化
DB接続
DB接続
catch
catch
例外出力(SQL Exception)
例外出力(SQL Exception)
例外出力(Class Not Found Exception)
例外出力(Class Not Found Exception)
コネクション情報を返却
コネクション情報を返却
終了
終了
Text is not SVG – cannot display

■サンプルコード

・メインクラス(AmountTaxMergeMain.java)

package com.amounttaxmerge.main;

import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import com.amounttaxmerge.biz.SelectNameAmountTax;
import com.amounttaxmerge.util.NameAmountTaxDao;

public class AmountTaxMergeMain {
	
	// メイン処理
	public static void main(String[] args) {
		
		// 商品名・金額・税取得クラスインスタンス
		SelectNameAmountTax snat = new SelectNameAmountTax();
		
		// 商品名・金額・税DAOのリストに取得結果を格納
		List<NameAmountTaxDao> select_datas = snat.getNameAcountTax();
		
		// 出力用MAP
		Map<String, Integer> output_map_data = new TreeMap<>();
		
		// 取得したデータ分繰り返し
		for(NameAmountTaxDao data : select_datas) {
			
			// 商品名・金額・税取得
			String name = data.getName();
			int amount = Integer.parseInt(data.getAmount());
			int tax = Integer.parseInt(data.getTax());
			
			// 金額+税算出
			int data_total = amount + tax;
			
			// 商品名がすでにMAPに存在している場合
			if(output_map_data.containsKey(name)) {
				// MAPから合計金額を取得し、加算
				int total = output_map_data.get(name) + data_total;
				// MAPの合計金額を更新
				output_map_data.replace(name, total);
				
			// 商品名がMAPに存在していない場合
			}else {
				// MAPへ商品名と金額を格納
				output_map_data.put(name, data_total);
			}
		}
		
		// MAP分繰り返し
		for(Map.Entry<String, Integer> entry : output_map_data.entrySet()) {
			// 「商品名:合計金額」を出力
			System.out.println(entry.getKey() + ":" + entry.getValue());
		}
	}
}

・商品名・金額・税取得クラス(SelectNameAmountTax.java)

package com.amounttaxmerge.biz;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import com.amounttaxmerge.util.ConnectMysql;
import com.amounttaxmerge.util.NameAmountTaxDao;

// 商品名・金額・税取得クラス
public class SelectNameAmountTax {
	
	// 商品名・金額・税取得SQL
	private static final String SQL = "select "
			+ "    A.data_name, "
			+ "    B.amount, "
			+ "    B.tax "
			+ "from"
			+ "    m_data_name A, "
			+ "    t_amount_tax B "
			+ "where"
			+ "    A.id = B.data_id "
			+ "order by "
			+ "    A.data_name "
			+ ";";
	
	// 商品名・金額・税取得処理
	public List<NameAmountTaxDao> getNameAcountTax(){
		
		//  商品名・金額・税DAOのリスト
		List<NameAmountTaxDao> amountTaxList = new ArrayList<NameAmountTaxDao>();
		
		// DB接続クラスインスタンス
		ConnectMysql cm = new ConnectMysql();
		
		try {
			// DB接続
			Connection con = cm.mysqlconnection();
			
			// ステートメントをセット
			Statement stmt = con.createStatement();
			
			// SQL実行
			ResultSet rs =  stmt.executeQuery(SQL);
			
			// 実行件数分繰り返し
			while(rs.next()){
				// 商品名・金額・税DAOのインスタンス
				NameAmountTaxDao result_data = new NameAmountTaxDao();
				
				// 商品名・金額・税をセット
				result_data.setName(rs.getString("A.data_name"));
				result_data.setAmount(rs.getString("B.amount"));
				result_data.setTax(rs.getString("B.tax"));
				
				// 商品名・金額・税DAOのリストに格納
				amountTaxList.add(result_data);
		      }
		//  例外処理
		}catch(Exception e) {
			// 例外エラー出力
			System.out.println("データ取得例外エラー:" + e);
		}
		
		// 商品名・金額・税DAOのリストを返却
		return amountTaxList;
	}
}

・商品名・金額・税DAOクラス(NameAmountTaxDao.java)

package com.amounttaxmerge.util;

// 商品名・金額・税DAOクラス
public class NameAmountTaxDao {

	private String name;	// 商品名
	private String amount;	// 金額
	private String tax;		// 税
	
	// 商品名
	public String getName() {
		return this.name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	// 金額
	public String getAmount() {
		return this.amount;
	}
	
	public void setAmount(String amount) {
		this.amount = amount;
	}
	
	// 税
	public String getTax() {
		return this.tax;
	}
	
	public void setTax(String tax) {
		this.tax = tax;
	}
}

・DB接続クラス(ConnectMysql.java)

package com.amounttaxmerge.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

// DB接続クラス
public class ConnectMysql {
	
	// DB接続情報
	private static final String DATABASE_NAME = "AmountTaxMerge";
	private static final String JDBC_URL = "jdbc:mysql://127.0.0.1/" + DATABASE_NAME;
	private static final String DB_USER = "user001";
	private static final String DB_PASSWORD = "aaa";
	private static final String DRIVER_NAME = "com.mysql.cj.jdbc.Driver";
	
	// DB接続処理
	public Connection mysqlconnection() {
		
		// コネクション情報初期化
		Connection conn = null;
		
		try {
			// ドライバセット
			Class.forName(DRIVER_NAME);
			
			// DB接続
			conn = DriverManager.getConnection(JDBC_URL, DB_USER, DB_PASSWORD);
			
			// debug code
			// System.out.println("SQL接続成功");
		
		// 例外処理:SQL EXCEPTION
		} catch(SQLException sql_e) {
			// 例外出力
			System.out.println("SQL接続Exception:" + sql_e);
		
		// 例外処理:ClassNotFoundException 
		} catch(ClassNotFoundException class_e) {
			// 例外出力
			System.out.println("ClassException:" + class_e);
		}
		
		// DB接続情報を返す
		return conn;
	}
}

■実行結果

商品A:17710
商品B:18150
商品C:14410
商品D:15180
タイトルとURLをコピーしました