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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Java

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

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Q&A

解決済

3回答

2698閲覧

オブジェクト指向の考え方に関して

lianprivate

総合スコア23

Java

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

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

0グッド

0クリップ

投稿2018/12/21 02:10

現在JavaでDB連携の勉強をしております。
その中で疑問に思ったのですが、現在3つのテーブルをそれぞれユーザーIDで管理し、それを結合して出力するという事を行う上で、Javaからそれぞれのテーブルのデータ更新や登録、消去を行おうとしています。

やりたい事は概ね出来上がってきたのですが、その中で更新、登録、消去をそれぞれクラスを作り、メインメソッドでそれぞれのクラスを呼び出し、その中でそれぞれの処理を実施しています。

まず1点は、この方法はJavaの考え方では正しい方法なのでしょうか?

そして2点目ですが、その各クラスの中でその3つのテーブルの操作を同じメソッドで行っていますが、メインメソッドからクラスを呼び出す際にそれぞれを識別する値を引数で渡し、それを元にif分で分岐させ、それぞれの処理を実施していますが、その方法ですとどうしてもコードが長くなってしまいます。
果たしてJavaではこのようなやり方で合っているのでしょうか?

下記にその呼び出されるクラスの中でも一番短いDB登録後のID検索のメソッドを添付致します。
例えばDB更新のクラスですとこの数倍の長さになります。
お手数ですがご見解を教えていただけますでしょうか。宜しくお願い致します。

Java

1public class Serch { 2 public int SerchID() { 3 int Uid = 0; 4 Connection conn = null; 5 PreparedStatement stmt = null; 6 ResultSet rset = null; 7 8 //接続文字列 9 String url = "jdbc:postgresql://localhost:5432/sample"; 10 String user = "postgres"; 11 String password = "Password"; 12 13 try{ 14 Class.forName("org.postgresql.Driver"); 15 16 //PostgreSQLへ接続 17 conn = DriverManager.getConnection(url, user, password); 18 19 //自動コミットOFF 20 conn.setAutoCommit(false); 21 22 //SELECT文の実行 23 String sql = "SELECT MAX(Uid) FROM m_user"; 24 stmt = conn.prepareStatement(sql); 25 rset = stmt.executeQuery(); 26 27 //SELECT結果の受け取り 28 while(rset.next()){ 29 Uid = Integer.parseInt(rset.getString(1)); 30 } 31 } 32 catch (ClassNotFoundException e) { 33 e.printStackTrace(); 34 } 35 catch (SQLException e){ 36 e.printStackTrace(); 37 } 38 finally { 39 try { 40 if(rset != null)rset.close(); 41 if(stmt != null)stmt.close(); 42 if(conn != null)conn.close(); 43 } 44 catch (SQLException e){ 45 e.printStackTrace(); 46 } 47 48 } 49 return Uid; 50 } 51 52 public void LatestDate(int Uid,int DB) { 53 Connection conn = null; 54 PreparedStatement stmt = null; 55 ResultSet rset = null; 56 57 //接続文字列 58 String url = "jdbc:postgresql://localhost:5432/sample"; 59 String user = "postgres"; 60 String password = "Qoakzm12"; 61 62 try{ 63 Class.forName("org.postgresql.Driver"); 64 65 //PostgreSQLへ接続 66 conn = DriverManager.getConnection(url, user, password); 67 68 //自動コミットOFF 69 conn.setAutoCommit(false); 70 71 //SELECT文の実行 72 if(DB == 1) { 73 String sql = "SELECT * FROM m_user WHERE Uid = ?"; 74 stmt = conn.prepareStatement(sql); 75 stmt.setLong(1,Uid); 76 rset = stmt.executeQuery(); 77 78 //SELECT結果の受け取り 79 while(rset.next()){ 80 System.out.println("1件の登録が完了しました。"); 81 System.out.println("名前:" + rset.getString(1)); 82 System.out.println("年齢:" + rset.getString(2)); 83 System.out.println("住所:" + rset.getString(3)); 84 System.out.println("性別:" + rset.getString(4)); 85 System.out.println("登録日:" + rset.getString(5)); 86 System.out.println("ユーザーID:" + rset.getString(6)); 87 } 88 }else if(DB == 2) { 89 String sql = "SELECT * FROM privacy_tbl WHERE UserId = ?"; 90 stmt = conn.prepareStatement(sql); 91 stmt.setLong(1,Uid); 92 rset = stmt.executeQuery(); 93 94 //SELECT結果の受け取り 95 while(rset.next()){ 96 System.out.println("1件の登録が完了しました。"); 97 System.out.println("ユーザーID:" + rset.getString(1)); 98 System.out.println("EMAILアドレス:" + rset.getString(2)); 99 System.out.println("電話番号:" + rset.getString(3)); 100 System.out.println("郵便番号:" + rset.getString(4)); 101 System.out.println("居住国:" + rset.getString(5)); 102 } 103 }else if(DB == 3) { 104 String sql = "SELECT * FROM Otherinfo WHERE InfoId = ?"; 105 stmt = conn.prepareStatement(sql); 106 stmt.setLong(1,Uid); 107 rset = stmt.executeQuery(); 108 109 //SELECT結果の受け取り 110 while(rset.next()){ 111 System.out.println("1件の登録が完了しました。"); 112 System.out.println("ユーザーID:" + rset.getString(1)); 113 System.out.println("趣味:" + rset.getString(2)); 114 System.out.println("特技:" + rset.getString(3)); 115 System.out.println("夢:" + rset.getString(4)); 116 } 117 } 118 } 119 catch (ClassNotFoundException e) { 120 e.printStackTrace(); 121 } 122 catch (SQLException e){ 123 e.printStackTrace(); 124 } 125 finally { 126 try { 127 if(rset != null)rset.close(); 128 if(stmt != null)stmt.close(); 129 if(conn != null)conn.close(); 130 } 131 catch (SQLException e){ 132 e.printStackTrace(); 133 } 134 135 } 136 } 137 138}

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

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

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

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

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

m.ts10806

2018/12/21 02:13

新規質問立つまでの間に回答作ってみてたのでそのまま投稿しました。 ご参考まで。
hayataka2049

2018/12/21 02:19

Searchでは? あと、前の質問はちゃんと削除リクエストできましたか?(ゴミ箱ボタンからリクエストを送れます)
lianprivate

2018/12/21 02:21

hayatakaさん Searchですね・・・。根本的なミス、お恥ずかしい限りです。削除リクエストは既に行いました!ご心配頂きありがとうございます!
hayataka2049

2018/12/21 05:11

削除リクエストを出すと、 この質問は、一時的に非表示にされています 質問者から削除リクエストが行われたため、運営チームで確認を行っています。 申し訳ありませんが、確認が終わるまでしばらくお待ち下さい。 のような表示に切り替わり、新着の質問欄などからも見れなくなるはずなので、何かしら上手く行っていない可能性があります。まだ質問が見れる状態のようなので・・・。
guest

回答3

0

1メソッドの長さは理想はスクロールせずに収まる長さまでとどこかで聞いたことがあります。

いいところまでいっているとは思いますが、私なら
DB接続するメソッド、1の更新をするメソッド、2の更新をするメソッド、3の更新をするメソッド
を作って、latestDateメソッドからそれぞれのメソッドをif文の分岐で呼び出すかな~と思います。

ただ、オブジェクト指向とはあまり関係ありませんが、Java的に宜しくないコーディングがいくつか見受けられるのでそこも書いておきます。

まず、メソッド名の先頭は小文字です。
今回ですと、LatestDate() → latestDate()です

あとは、文字(数字)の直書きは宜しくないです。
定数化したほうがよいと思います。

あとは超どうでもいいですが、 Serch()じゃなくて Search()・・・?かなと。

コーディング規則は超めんどくさいし、どうでもいいじゃん~!と思うかもしれませんが、現場に出るとかなり怒られます。
初期のうちに直せるところは直しておくと、後々困らないです。おすすめします。

投稿2018/12/21 02:22

azuapricot

総合スコア2341

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

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

lianprivate

2018/12/21 02:26

azuapricotさん ご指導、ご指摘ありがとうございます! そういったコーディング規則まで中々頭が回らないので、現場に入る前に教えて頂いてありがたい限りです! オブジェクト指向に関してもとても参考になりました!よく勉強します!英語に関しても勉強します・・・。 ありがとうございました!
guest

0

ベストアンサー

クラスやメソッドの基本的な考え方は「役割分担」です。
同じような記述をしているのであれば、そこはメソッドとして切り出して、可変的なところと固定的なところを決めて
可変的なところを引数で対応します。

今回の処理内容ですと、
//接続文字列 から //PostgreSQLへ接続 までの一連の手続きは固定です。
その先の処理はConnectionだけあれば良いので、接続処理はまとめましょう。

ここで問題となるのがSerchというクラスの「役割」です。
Connection自体は検索に限らず、新規追加・更新・削除 でも使います。
そして、もしかしたら「検索」という処理自体も様々なところで使えますし、
m_user以外のテーブルで利用することもあるかもしれません。

ということは、今の作りだとそのたびにクラスが増えるということになりますね。
「Serch」という名前も相応しくなくなります。
そこでやはりMVCのMである「モデル」の考え方が必要になってくると思います。

色々と解釈はありますが「データを取り扱うAPI」としての利用方法が一般的には多い印象です。

つまり、例えばUserというクラスを作り、そこで今回のテーブルで言えばm_userに関する
処理全てを書く というやり方ですね。

ただ、ここで注意点があります。
m_userはあくまでデータテーブルの1つであり、最上位ではないということ。
並列で並ぶのは他のテーブルです。
では、最上位とは何か。

「データベースを取り扱う」そのものです。

DB接続もそう、検索・新規追加・更新・削除 もそうです。
もっと言えば、「検索・新規追加・更新・削除」も共通しているのは
SQLを実行してexecuteQueryして結果を得ているということ。
得た結果をどう取り扱うかは違いますが、結局のところResultSetを受け取っています。

つまり、各テーブル用のクラスにその最上位のクラスを継承させることで、
より汎用的な作りが可能となります。

今回提示されているコードは検索のコードなので、そこにもフォーカス宛てますと、
確かに取得する列やWhere句の条件は違いますが、最終的にはSELECT文を発行しています。

ここで私の回答の最初に立ち戻りましょう。
**「役割分担」**のところですね。
「同じような記述をしているのであれば、そこはメソッドとして切り出して、可変的なところと固定的なところを決めて
**可変的なところを引数で対応します。」**のところですね。

うまく引数を使えば、如何様にも対応が可能です。
検索するカラムやカラムの型、検索の方法(完全一致、部分一致) このあたりを
例えば配列で渡してその内容によってWhere句を作るようにすればメソッド1つでどのようなSELECTにも対応が可能です。
もちろん汎用メソッドを作るのは作ってそちらを呼び出せば良いですが、それだけだと呼び出すときに意図がもてなかったり、
毎回配列を作るのが大変だったりします。
今回提示されたLatestDateですとかSerchIDのように「特定の情報を取得する場合」ですね。
その場合は、それ専用のメソッドを用意しておき、そのメソッドの中で検索用の配列を作り、
汎用メソッドを呼び出すような仕組みにすることで、専用メソッドを呼び出すだけで特定の動作をしてくれるように作ります。

という感じで。
他の更新や削除についても同じように考えてみてください。
「役割分担」「共通化」ですね。

メソッドの引数は情報が増えれば増えるほど、引数が多くなりすぎるようなイメージがあるかもしれませんが、
配列を使うことで、そこをスマートに対応することもできるようになります。
分岐が増えることにもなるのでそこはメソッド自体も太り過ぎないように気をつける必要はありますが、
汎用メソッドと専用メソッドをうまく使い分けることができれば、あまりFat Codeにはならないようにも思います。

そこは何度も組んで、組みなおして、リファクタリングしていくしかないですね。

ご参考まで。

投稿2018/12/21 02:12

m.ts10806

総合スコア80850

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

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

lianprivate

2018/12/21 02:20

いつもいつもありがとうございます!! 正に私が欲していた答えを丸々頂いたような感じです!! 今作っている流れが根本から変えていけるような答えでしたので、これからの学習が楽しくなってきました! 本当にありがとうございます!頑張ります!
m.ts10806

2018/12/21 02:28

いろいろな意見を聞けるはずなのでもうちょっと待ってみても良かったのかなあとは思います。
m.ts10806

2018/12/21 02:32

(Javaコーディング規約については置いといて) 英語の誤表記にはあえて触れませんでした。 我々が対応しているのはプログラムであり、英語ではないので。 まあでも「指示した通りしか動かない」という観点からスペルミスは命取りになり得るので間違えない方が良いのは言うまでもないですが。 変に難しい英単語を使うよりはローマ字表記の方が分かりやすいという現場も少なくないですしね。
lianprivate

2018/12/21 02:36

確かにおっしゃる通り、今回の質問は奥が深そうで、色々とご意見ありそうでですね。 そんな現場もあるんですね、勉強になります! もうしばらくすると初の現場に入るので、そこで更にスキルアップできればと思っています。 みなさんのご意見を参考にして少しでも迷惑掛からないよう精進していきます。ありがとうございます!
m.ts10806

2018/12/21 02:44

現場に入ってみないとわからないこともあるし、現場のルールもあります。 まずは現場のルールをしっかり把握してコードに反映するようにしてください。 初めての現場であれば必ず先輩がつくはずなので、分からないところは必ず確認するようにしてくださいね。 質問の仕方はteratailのような聞き方が実は望ましかったりします(何も調べず試さずはNG。でも考えすぎ、自己判断もNGというバランス)
lianprivate

2018/12/21 03:04

なかなかバランスが難しいですねw でもteratailを多分そこそこ上手く使えてると思うので(パスワードの件は除く)、現場に行ったらコミュニケーション大事にしてやってみます!また詰まったらその時は宜しくおねがいします!
guest

0

DB を SQL で直接操作してもよいですが、 DB 操作をあつかうためのライブラリーがいくつも存在しています。

  • Javaを使うなら知っておきたい技術、フレームワーク、ライブラリ、ツールまとめ

https://qiita.com/disc99/items/727b51dbe737602a5c91

こういったものをうまく使うと、簡潔に処理を記述できます。
敷居は高いかもしれませんが、小さいサンプルなどで勉強していき検討してみると学べる点が多くあると思います。

  • Hibernateで学ぶJPA入門の要点をまとめる

https://qiita.com/Maruo110/items/4dc4a49aedd6323ebfdb

  • データベースを簡単にーJavaSEでもオブジェクト指向データベース(JPA)

https://qiita.com/tkxlab/items/11bd9bd93fc0636ee8e8

投稿2018/12/27 04:24

katoy

総合スコア22324

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

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

lianprivate

2018/12/27 05:22

これは良いことを聞きました!現場で利用できるかは別として、知識として今から勉強してみます! ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問