ビュー名を返すだけのControllerなら、Controllerは別にいらないらしいよ!

ログインフォームに誘導しようとした際、View名返すだけのControllerを作らなきゃいけません。
そんなとき、以下のようなConfigクラスを作ればこのControllerが必要ないんです!

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("login").setViewName("login/login-form");
    }
}

ちなみに、Controllerを実装した場合はこんな感じ。

@Controller
@RequestMapping("/login")
public class LoginController {

    @RequestMapping
    public String login() {
        return "login/login-form";
    }
}

これだけ見てみるとそんなにコード量が変わらないというかむしろController作った方が少なそうだけど。笑

Postgresの初期設定(ユーザの作成)

仕事ではMySQLばかりであまり使うことのないPostgres。
コマンドがまるで違うので備忘録として!

psql経由でデータベースログイン

mbp-Ryosuke:~ ryosuke$ psql -d postgres -U [ユーザ名]
psql (9.5.1)
Type "help" for help.

postgres=#
  • -d:データベースの指定
  • -U:ユーザ名の指定(特にスーパーユーザを指定していない場合は、PCのログインユーザ名がスーパーユーザになります)

なお、Postgresでは、ユーザのことをロールと呼びます。

ユーザの作成

postgres=# CREATE ROLE mrs LOGIN
ENCRYPTED PASSWORD 'xxxxxxxxxxxxxxxxxxxx'
NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION;
  • CREATE ROLEに続けて作成するロールの名前を入力します。ここでは「mrs」というロールを作成するようにしています。
  • ロール名に続けてオプションの指定を行います。「LOGIN」を指定すると、データベースに接続可能なユーザになります。
  • パスワードに続けてユーザのパスワードを指定します。PASSWORDの前に「ENCRYPTED」と指定すると暗号化されたパスワードが、「UNENCRYPTED」と指定すると生のパスワードが保存されます。
  • パスワードの続けてロールをスーパーユーザに設定するか有無かを指定します。「SUPERUSER」と指定すると、スーパーユーザが、設定されます。指定しない場合は「NOSUPERUSER」となります。
  • INHERITは、ロールがそのロールが属するロールの権限を"継承"するかどうかを決定します。(詳しく理解できてないです)
  • NOCREATEDBは、そのロールにはデータベースを作成する権限が与えられないようにするときに使用する。
  • NOCREATEROLEは、このロールが新しいロールを作成できないようにするために指定します。(デフォルト値もNOCREATEROLE)
  • NOREPLICATIONは、ロールがストリーミングレプリケーションを初期化でき、システムをバックアップモードとの遷移が可能かどうかを決定する。NOREPLICATIONは、これをさせたくないときに指定する。

Postgresのインストール方法(Mac)

postgresを使用する場面に遭遇したので備忘録として。

// postgresをインストール
ryosuke $ brew install postgresql
// 文字コードをutf-8で初期化
ryosuke $ initdb /usr/local/var/postgres/ -E utf8
// バージョンの確認
ryosuke $ postgers --version
// postgresqlの起動
ryosuke $ brew services start postgresql
// データベースの一覧を取得
ryosuke $ psql -l

データの入れ方等は次回ってことで!

Mac用のActive Directoryのパスワード変更スクリプト作ってみた!

会社でActive Directoryを使用しているんですが、パスワード変更するのが非常に面倒くさい。。。
VMWindows起動して、パスワード変更だなんて。たったこれだけの作業のために時間使いたくないと思い、スクリプト作っちゃいました。

#!/bin/bash

echo -n "ユーザ名を入力してください。 > ";
read NAME;
read -sp "古いパスワードを入力してください。 > " OLD_PASSWD;
echo
read -sp "新しいパスワードを入力してください。 > " NEW_PASSWD;
echo
read -sp "新しいパスワードを入力してください。(確認用) > " NEW_PASSWD_RE;
echo

if [ ${NEW_PASSWD} != ${NEW_PASSWD_RE} ]; then
	echo "### 新しいパスワードが一致しません。 ###";
	exit 1;
fi

sudo dscl /Active\ Directory/[ドメイン名]/All\ Domains/ -passwd /Users/${NAME} ${OLD_PASSWD} ${NEW_PASSWD} 1>/dev/null 2>/dev/null;
RESULT=$?;
if [ ${RESULT} = 0 ]; then
	echo "### パスワードが変更されました。 ###";
elif [ ${RESULT} = 11 ]; then
	echo "### パスワードの変更に失敗しました。 ###";
	exit 11;
elif [ ${RESULT} = 185 ]; then
	echo "### ユーザが存在しません。###";
	exit 185;
else
	echo "### パスワードの変更に失敗しました。 ###";
	exit 1;
fi

※[ドメイン名]のところはよしなに変更してください!
スクリプト起動してユーザ名、旧パスワード、新パスワード、新パスワード(再)を順に入力するだけです!

以下のコマンドで確認できます。パスワードを入力して「>」が表示されれば成功です。

sudo dscl -u [ユーザ名] /Active\ Directory/[ドメイン名]/All\ Domains/

Lazy/Eager Fetch

データベースへのクエリのタイミングを定義するとき、大きく分けて2つ方式がある。

  • Lazy Fetch:関連するコレクションをDBから呼びこまない。Persistentオブジェクトにコレクションを取得するメソッドが呼ばれたときにSQLを発行してDBからレコードを読み込む。都度問い合わせをする。
  • Eager Fetch:関連するコレクションをDBから読み込む。DBから該当のEntityだけでなく関連するEntityも全て読み込むので、DBへの問い合わせが1回で済む。

□Lazy

@OneToMany(mappedBy = "product", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<OrderDetails> orderDetailses = new ArrayList<>();

□Eager

@OneToMany(mappedBy = "product", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private List<OrderDetails> orderDetailses = new ArrayList<>();

□関連とFetchの設定
@OneToMany, @ManyToManyのデフォルトのFetch設定はLAZY
@ManyToOne, @OneToOneのデフォルトのFetch設定はEAGER

※Eager設定は、基本的にパフォーマンスのボトルネックとなるので、極力避ける

1対多

1対多については、単方向・双方向・JoinTableの3つの方式がある。
□単方向
OrdersオブジェクトからProductオブジェクトに対してのみアクセスする状態

public class Orders implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer ordersId;
    
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "orders_id")
    private Set<Product> products = new HashSet<>();
}

□双方向
双方向関連は、@OneToManyと@ManyToOneの両方のアノテーションが併用されている状態

public class Orders implements Serializable {
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "orders")
    private List<Product> products = new ArrayList<>();
}
public class Product implements Serializable {
    @ManyToOne(optional = false)
    private Orders orders;
}

この表記では、mappedByというパラメータを持つOrdersが被所有者側となる。

□1対多の双方向関連:JoinTable
1対多の双方向関連で間に結合テーブルを挟む場合は@JoinTableを使う

public class Orders implements Serializable {
    @OneToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "orders_product")
    private List<Product> products = new ArrayList<>();
}

orders_productという結合テーブルが生成される。