javaからpostgresqlに接続する

とりあえずのメモですなと。

 

1.インストール手順(Windows10 64bit)

(1)「postgresql-X.X.X-X-windows.exeを実行

・Instration Directory→インストールされるディレクト

C:Program Files (x86)PostgreSQLX.X

・Data Directory→実際に使ったデータの保存先

C:Program Files (x86)PostgreSQLX.Xdata

・Password postgres

・Port 5432

・Locale Japanesejapan

 

2.デバック・動作確認http://si.comp.ae.keio.ac.jp/web_app_dev_material/simple/dev_db/dev_db_java/index.html

 

3.JavaPostgresql接続時エラーと解決策

(1)エラーの文字化け

■事象

エラー内容が文字化けしてしまう。

■解決策

postgresql.confファイルを開く

②lc_messages = 'Japanese_Japan.932'をコメントアウト

③lc_messages = 'C'を追加

PostgreSQL を再起動する

 ・ [コントロールパネル]-[管理ツール]-[サービス] を選択

 ・「postgresql-x64-X.X」 を右クリックし「再起動」を選択

<https://blogs.yahoo.co.jp/dk521123/33325738.html>

 

(2)パスワード権限の失敗

■事象

Class.forName("org.postgresql.Driver");Connection connection =   

DriverManager.getConnection("jdbc:postgresql://localhost/postgres", "postgres", "");

Statement statement = connection.createStatement();

■解決策

Class.forName("org.postgresql.Driver");Connection connection =  

DriverManager.getConnection("jdbc:postgresql://localhost/postgres", "postgres",

"postgres");

Statement statement = connection.createStatement();

<https://blogs.yahoo.co.jp/dk521123/33327164.html>

 

(3)デフォルトのResultSetが巻き戻し不可

■事象

Class.forName("org.postgresql.Driver");Connection connection =

DriverManager.getConnection("jdbc:postgresql://localhost/postgres", "postgres",

"postgres");Statement statement = connection.createStatement();

-----------------------------------

【コンソール出力】

org.postgresql.util.PSQLException: Operation requires a scrollable ResultSet, but this ResultSet is FORWARD_ONLY. at org.postgresql.jdbc2.AbstractJdbc2ResultSet.checkScrollable(AbstractJdbc2ResultSet.java:236)

at org.postgresql.jdbc2.AbstractJdbc2ResultSet.first(AbstractJdbc2ResultSet.java:318)

at test.UserDB.executeSelect(UserDB.java:117)

at test.UserDB.execute(UserDB.java:100)

at test.UserDB.main(UserDB.java:31)

-----------------------------------

■解決策

Class.forName("org.postgresql.Driver");Connection connection =  

DriverManager.getConnection("jdbc:postgresql://localhost/postgres", "postgres",

"postgres");

Statement statement =

connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE ,

ResultSet.CONCUR_READ_ONLY);

-----------------------------------

【コンソール出力】

id: 1, name: 1, password: 1

id: 2, name: 2, password: 2

-----------------------------------

 

3.JavaPostgresqlSQL周りのエラー

(1)id列がnot null制約違反と言われる。

■事象

ERROR: null value in column "id" violates not-null constraint Detail: Failing row contains (null, `1 , 1 , 2018-08-27, null).

■解決策

対象テーブルのカラムidにserialを明示的に設定する。(そうしないと、暗黙的にnullが設定されるらしい。)
create table tablename (
colname serial
);

■備考
・まず、postgresqlのserialとは、いわゆる、連番の自動採番のこと。
サロゲートキー(人工キー)です。連番かつ一意ということ。
 http://argius.hatenablog.jp/entry/20120607/1339077696
・serial指定したカラムはinsert文発行時に自動採番される。
 http://developpp.blog.jp/archives/8224244.html

 

(2)serial指定したカラムがResultSetに見つからないと言われる。

■事象

The column name id was not found in this ResultSet.

■解決策
serial指定してるんだから無視してくれよって感じ。
nextval関数を指定…って無理か。。。諦めました。とりあえず、自動採番はやめ。
https://qiita.com/5zm/items/da82cec73e097d2a97d0

再開するなら、ここからだけど、もうこの事象で疲れ果てたので、いったん諦めます。。。。。。
http://si.comp.ae.keio.ac.jp/web_app_dev_material/simple/dev_servlet/dev_servlet_prac/index.html

【作成中】日付と時刻を扱うクラス

■Calenderクラス(java.util.Calender)
・mutable(可変)オブジェクト
・月は0始まり

■LocalDateクラス(java.time.LocalDate)
日付を扱うクラス(Java SE8以上で対応)
・immutable(不変)オブジェクト→参照が変わらない限り、日付が一定。
・月が1始まり

■LocalTimeクラス(java.time.LocalTime)
時刻を扱うクラス(Java SE8以上で対応)
・immutable(不変)オブジェクト→参照が変わらない限り、時刻が一定。
・24時間で時間を扱う。
・午前/午後の区別なし。

■LocalDateTimeクラス(java.time.LocalDateTime)
日付と時刻を扱うクラス(Java SE8以上で対応)

■Durationクラス()
(Java SE8以上で対応)

■Periodクラス()
(Java SE8以上で対応)

immutableとmutable

【mutableオブジェクト】
■概要
可変オブジェクト、可変クラス。
何度でもフィールドセットできる。
オブジェクトやクラスの状態(フィールド)を変更できる。基本原則はmutable。
つまり、例外のimmutableをおさえりゃいい。

【immutableオブジェクト】
■概要
不変オブジェクト、不変クラス
一度セットしたフィールドの値を二度と変更できない。

■代表例
java.lang.String
java.io.File

■実装方法
・クラスをfinalで宣言する。
→メソッドがオーバーライドされない=サブクラスからの変更を防ぐ
・フィールドを全てprivateで修飾する。
・オブジェクトの内部に可変オブジェクトを定義している場合、そのオブジェクトを提供しない
→getterメソッドなどは提供しない
・オブジェクトの内部状態を変更できるメソッドを提供しない
→setterメソッドなどは提供しない

■メリット
・オブジェクトの値の変更有無確認不要
・スレッドセーフ
・データ複製不要
・データ共有可能(複数クライアント間)

【作成中】基本APIの利用

【文字列操作】

java.lang.String

java.lang.StringBuilder

javaの備忘録(StringクラスとStringBuilderクラス)

https://jioatips.hatenablog.com/entry/2018/07/24/013433)

 

【日時操作】

java.util.Calender

java.util.Date

java.util.SimpleDateFormat

Java SE8以降で使用可能↓

java.time.LocalTime

java.time.LocalDate

java.time.LocalDateTime

Java SE8以降で使用可能↑

【コレクション操作】

java.util.ArrayList

 

関数型インタフェースとラムダ式

https://www.casleyconsulting.co.jp/blog/engineer/114/

 

Java SE8で新しく追加されたラムダ式

正直よく分かってない。何がよくわかっていないか。それは使い道だ。これを使ってどんなメリットを享受できるのかが分からない。

オブジェクト指向と双璧をなす設計思想に関数型インタフェースがあるとか。
これ使えるにはオブジェクト指向の理解もいるのかと考える。勉強継続する。

【関数型インタフェース】
実装が必要な抽象メソッドを1つだけ持つインタフェース
Java SE8から、よく使うであろう関数型インタフェースは「java.util.function」として提供されている。

ラムダ式
・匿名クラスの代替
・関数型インタフェースとセットで使う。

■基本構文
関数型インタフェースの型 変数名 = (引数) -> {処理;};
・引数の宣言
・アロー演算子
・処理ブロック

ラムダ式の省略ルール
中カッコがある場合
・複数の処理が書ける
・戻り値を戻すreturn省略不可
中カッコがない場合
・1つの処理しか書けない
・戻り値を戻すreturn省略可能

ラムダ式の変数のスコープ
ラムダ式を囲むブロックと同じスコープになる。
ラムダ式から式を宣言しているメソッドのローカル変数にアクセスできる。ただし、実質的にfinalなローカル変数でなければならない。
---------------------------------------
public class Test{
public static void main(String[]args){
String str = "こんにちは";
Function f = () -> {
sysout(val);
};
×→str = "さようなら";
f.test();

---------------------------------------

正規表現(Patternクラス、Matcherクラス)

※好みとよく使いそうなもののみ記載しているので、全量じゃない点に注意。ただ、書いていないものは使い道が分からなんだ。

 

➀文字クラス

・[abc]…a、b、またはc【単純クラス】

・[^abc]…a、b、c以外の文字【否定】

・[a-zA-Z]…a-zまたはA-Z【範囲】

・[a-d[m-p]]…a-dまたはm-p = [a-dm-p]【結合】

・[a-z&&[def]]…d、e、またはf【交差】

・[a-z&&[^bc]]…a-z(bとcを除く) = [ad-z]【減算】

・[a-z&&[^m-p]]… a-z(m-pを除く) = [a-lq-z]【減算】

 

②定義済み文字クラス

・¥d…[0-9] = 数字

・¥D…[^¥d] = 数字以外

・¥s…[¥t¥nx0B¥f¥r] = 空白文字

・¥S…[^¥s] = 空白文字以外

・¥w…[a-zA-Z0-9] = 単語構成文字

・¥W…[¥w] = 単語構成文字以外

 

③境界正規表現エンジン

^…行の先頭

$…行の末尾

 

④数量子(最長一致数量子)
・X?…X、1または0回
・X*…X、0回以上
・X+…X、1回以上
・X{n}…X、n回
・X{n,}…X、n回以上
・X{n,m}…X、n回以上m回以下

 

【参考】

・【Java正規表現】文字列をチェックするパターンの書き方とサンプル

https://www.sejuku.net/blog/13215

・忘れっぽい人のための正規表現チートシート

https://qiita.com/tossh/items/635aea9a529b9deb3038

Java SE8リファレンス

-java.util.regex.Patter

https://docs.oracle.com/javase/jp/8/docs/api/java/util/regex/Pattern.html

-java.util.regex.Matcher

https://docs.oracle.com/javase/jp/8/docs/api/java/util/regex/Matcher.html

StringクラスとStringBuilderクラス

【文字列の考え方】

■位置と範囲 "abcde"

・位置の場合、aが0

・範囲の場合、aの前が0

■StringとStringBuilder

String(java.lang.String)

immutable(不変)オブジェクト

:一度セットしたフィールドの値を二度と変更できない。

StringBuilder(java.lang.StringBuilder)

mutable(可変)オブジェクト

:何度でもフィールドセットできる。

 
インスタンス生成方法】

■String(java.lang.String)

String str = new String("こんにちは");

String str = "こんにちは";

String str = String.valueOf("こんにちは");

■StringBuilder(java.lang.StringBuilder)

StringBuilder sb = new StringBuilder("abcde");

StringBuilder sb = new StringBuilder();

sb.append("abcde");


【Stringクラスのメソッド】

Java API リファレンス

https://docs.oracle.com/javase/jp/8/docs/api/java/lang/String.html

※クラス定義とエントリーポイント省略

 

(1)replaceメソッド

対象の文字列を置換後の文字列に変換する。

--------------------

String str = "abcde";String result = str.replace("abcde","12345");System.out.println(result);

--------------------

実行結果12345


(2)replaceAllメソッド

対象の正規表現文字列を置換後の文字列に変換する。

正規表現を使用しない場合

--------------------

String str = "abcde";

String result = str.replaceAll("abcde","12345");

System.out.println(result);

--------------------

実行結果12345
正規表現を使用した場合

--------------------

String str = "abcde";

String result = str.replaceAll("[a-z]","1");

System.out.println(result);

--------------------

実行結果11111


(3)charAtメソッド【位置】

引数で指定した位置の文字を戻す。
➀範囲内の場合

--------------------

String str = "abcde";

System.out.println(str.charAt(0));

--------------------

実行結果a
②範囲外の場合

--------------------

String str = "abcde";

System.out.println(str.charAt(5));

--------------------

実行結果

java.jang.StringIndexOutOfBoundsException


(4)indexOfメソッド【位置】

引数で指定した文字または文字列の開始文字位置を返す。

オーバーロードされているので、引数にStringも指定できる。
➀引数に文字(char)を指定した場合

--------------------

String str = "abcde";

System.out.println(str.indexOf(c));

--------------------

実行結果

2
②引数に文字列(String)を指定した場合

--------------------

String str = "abcde";

System.out.println(str.indexOf(bc));

--------------------

実行結果

1
③引数に存在しない文字(文字列)を指定した場合

--------------------

String str = "abcde";

System.out.println(str.indexOf(abcdef));

--------------------

実行結果

-1


(5)substringメソッド【範囲】

文字列から、指定した範囲の文字列を抽出する。

--------------------

String str = "abcde";

System.out.println(str.substring(2,4));

--------------------

実行結果

cd


(6)trimメソッド文字列の前後にある空白を除去する。

代表的な空白とは…

スペース(\s)

タブ文字(\t)

改行(\n)(\r)

--------------------

String str = " a b cde \t";

System.out.println(trim(str));

--------------------

実行結果

a b cde


(7)lengthメソッド【範囲】

文字列の文字数を戻す。

--------------------

String str = "abcde";

System.out.println(charAt(str.length()));

--------------------

実行結果

java.lang.StringIndexOutOfBoundsException


(8)startsWithメソッド

文字列が引数で指定された文字で始まる場合、trueを返す。

--------------------

String str = "abcde";

System.out.println(str.startsWith("a"));

--------------------

実行結果true


(9)endsWithメソッド

文字列が引数で指定された文字で終わる場合、trueを返す。

--------------------

String str = "abcde";

System.out.println(str.endsWith("d"));

--------------------

実行結果

false


(10)splitメソッド

文字列を指定した正規表現に一致する位置で分割する。

--------------------

String str = "abcde";

System.out.println(str.endsWith("d"));

--------------------

実行結果

false


(11)concataメソッド

文字列と引数で渡された文字列を連結する。

--------------------

String str = "abcde";

System.out.println(str.concata("fghij"));

--------------------

実行結果

abcdefghij

 

【StringBuilderクラスのメソッド】

Java API リファレンス

https://docs.oracle.com/javase/jp/7/api/java/lang/StringBuilder.html

※クラス定義とエントリーポイント省略

(0)capacityメソッド
現在の容量を返却する。(capacity+16)
--------------------
StringBuilder sb = new StringBuilder("abcde");
System.out.println(sb.capacity());
--------------------
実行結果
21

(1)appendメソッド
文字列に新しい文字列を追加する。
--------------------
StringBuilder sb = new StringBuilder();
sb.append(true);
sb.append(1);
sb.append('a');
sb.append("bcde",1,3);
char[] array = {'a', 'b', 'c', 'd', 'e',};
sb.append(array);

System.out.println(sb.toString());
--------------------
実行結果
true1acdabcde

(2)insertメソッド【範囲】
文字列を任意の場所に挿入する。
--------------------
StringBuilder sb = new StringBuilder("abc");
//メソッドチェイン
sb.append("de").insert(2,"f");
System.out.println(sb);
--------------------
実行結果
abfcde

(3)deleteメソッド【範囲】
引数で指定した範囲の文字列を削除する。
--------------------
StringBuilder sb = new StringBuilder("abcde");
sb.delete(1,2);
System.out.println(sb);
--------------------
実行結果
acde

(4)deleteCharAtメソッド【位置】
引数で指定した位置の文字を削除する。
--------------------
StringBuilder sb = new StringBuilder("abcde");
sb.deleteCharAt(2);
System.out.println(sb);
--------------------
実行結果
abde

(5)reverseメソッド
文字列を反転する。
--------------------
StringBuilder sb = new StringBuilder("abcde");
sb.reverse();
System.out.println(sb);
--------------------
実行結果
edcba

(6)replaceメソッド【範囲】
引数(第1、第2)で指定した範囲の文字列を第3引数の文字列に置換する。
--------------------
StringBuilder sb = new StringBuilder("abcde");
sb.replace(1,3,"a");
System.out.println(sb);
--------------------
実行結果
aaade

(7)substringメソッド【範囲】
引数(第1、第2)で指定した範囲の文字列を抽出する。
--------------------
StringBuilder sb = new StringBuilder("abcde");
sb.substring(1,3);
System.out.println(sb);
--------------------
実行結果
bc

(8)subSequenceメソッド【範囲】
引数(第1、第2)で指定した範囲の文字列を抽出する。
※内部的にはsubstringメソッドを呼び出しているため、
substringメソッドと全く同じ。
--------------------
StringBuilder sb = new StringBuilder("abcde");
sb.subSequence(1,3);
System.out.println(sb);
--------------------
実行結果
bc