Kohei Nozaki's blog 

動かしてみる


Posted on Tuesday Jan 21, 2014 at 07:57AM in Technology


何をするの?

開発環境を設定して、JPAを叩くCDI管理Beanと、それを叩くサーブレットを作って動かしてみます。

環境

  • WildFly8.0.0CR1
  • Eclipse Kepler SR1
  • PostgreSQL 9.2.4
  • Oracle JDK7u51

準備

プロジェクトを作る

  1. まずこの要領で空っぽのプロジェクトjpahelloを作ります
  2. Project Facetsを開き、CDIとJPAにチェックを入れてOKを押します

  3. 何故かbeans.xmlが出来ないので作ります。web-resourcesを右クリックしてNew→File beans.xmlを選択

  4. フォルダを「jpahello/src/main/webapp/WEB-INF」にしてFinish

  5. persistence.xmlとbeans.xmlができた事を確認します。

データベース作成とデータソース定義

このへんを参考にすると良いかも

persistence.xmlの設定をする

Persistence provider

先ほど作ったpersistence.xmlをダブルクリックして開いてみましょう

Persistence providerを設定します。WildFlyにはHibernateが入っているので

org.hibernate.ejb.HibernatePersistence
になります。

Connection

次はデータソースの設定です。画面下部のConnectionタブを押して画面を切り替えます

JTA data sourceにAPサーバに登録してあるデータソースのJNDI名を入力します

Schema Generation

次はDDL自動生成の設定です。画面下部のSchema Generationタブを押して画面を切り替えます

Database actionをDrop and createにしておきます。こうするとデプロイの度にDROPとCREATEが走ります。ちょっといじりたいだけなのでこれで。

Sourceを確認

画面下部のSourceタブを押して画面を切り替えるとpersistence.xmlが確認出来ます。こんな感じになってるのを確認したら保存しましょう。

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
	<persistence-unit name="jpahello">
		<provider>org.hibernate.ejb.HibernatePersistence</provider>
		<jta-data-source>java:jboss/jdbc/TestDS</jta-data-source>
		<properties>
			<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
		</properties>
	</persistence-unit>
</persistence>

エンティティを作る

  1. src/main/javaで右クリック→New→JPA Entityを選択

  2. Java packageとClass nameを埋めてFinish

  3. 内容はこんな感じで

  4. package com.example.entity;
    
    import java.io.Serializable;
    import java.util.Date;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.NamedQueries;
    import javax.persistence.NamedQuery;
    import javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    
    @Entity
    @NamedQueries({ @NamedQuery(name = "findHogeEntityAll", query = "SELECT e FROM HogeEntity e") })
    public class HogeEntity implements Serializable {
    
    	private static final long serialVersionUID = 1L;
    
    	public HogeEntity() {
    		super();
    	}
    
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	@Column(nullable = false)
    	private Long id;
    
    	@Column
    	@Temporal(TemporalType.TIMESTAMP)
    	private Date hogeDate;
    
    	public Long getId() {
    		return id;
    	}
    
    	public void setId(Long id) {
    		this.id = id;
    	}
    
    	public Date getHogeDate() {
    		return hogeDate;
    	}
    
    	public void setHogeDate(Date hogeDate) {
    		this.hogeDate = hogeDate;
    	}
    
    }
    

Dao的なクラスを作る

package com.example.dao;

import java.util.Date;
import java.util.List;

import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;

import com.example.entity.HogeEntity;

@Named
public class HogeEntityDao {

	@PersistenceContext
	private EntityManager em;

	@Transactional
	public void save() {
		HogeEntity e = new HogeEntity();
		e.setHogeDate(new Date());
		em.persist(e);
	}

	public List<HogeEntity> findAll() {
		return em.createNamedQuery("findHogeEntityAll", HogeEntity.class).getResultList();
	}
}

サーブレットを作る

package com.example.servlet;

import java.io.IOException;
import java.io.Writer;

import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.example.dao.HogeEntityDao;
import com.example.entity.HogeEntity;

@WebServlet("/HogeServlet")
public class HogeServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Inject
	HogeEntityDao dao;

	public HogeServlet() {
		super();
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		dao.save();
		try (Writer w = response.getWriter()) {
			for (HogeEntity e : dao.findAll()) {
				w.write("id=" + e.getId() + ", hogeDate=" + e.getHogeDate() + "\n");
			}
		}
	}
}

作った資源を確認

5つ全部あるか確認しましょう。

デプロイしてみる

コンソールにこんなのが流れるはず

17:05:24,199 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-14) JBAS015876: Starting deployment of "jpahello.war" (runtime-name: "jpahello.war")
17:05:24,219 INFO  [org.jboss.as.jpa] (MSC service thread 1-3) JBAS011401: Read persistence.xml for jpahello
17:05:24,227 INFO  [org.jboss.as.jpa] (ServerService Thread Pool -- 264) JBAS011409: Starting Persistence Unit (phase 1 of 2) Service 'jpahello.war#jpahello'
17:05:24,227 INFO  [org.hibernate.jpa.internal.util.LogHelper] (ServerService Thread Pool -- 264) HHH000204: Processing PersistenceUnitInfo [
	name: jpahello
	...]
17:05:24,236 INFO  [org.jboss.weld.deployer] (MSC service thread 1-15) JBAS016002: Processing weld deployment jpahello.war
17:05:24,247 INFO  [org.jboss.weld.deployer] (MSC service thread 1-9) JBAS016005: Starting Services for CDI deployment: jpahello.war
17:05:24,249 INFO  [org.jboss.weld.deployer] (MSC service thread 1-16) JBAS016008: Starting weld service for deployment jpahello.war
17:05:24,252 INFO  [org.jboss.as.jpa] (ServerService Thread Pool -- 264) JBAS011409: Starting Persistence Unit (phase 2 of 2) Service 'jpahello.war#jpahello'
17:05:24,425 INFO  [org.hibernate.dialect.Dialect] (ServerService Thread Pool -- 264) HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL9Dialect
17:05:24,426 INFO  [org.hibernate.engine.jdbc.internal.LobCreatorBuilder] (ServerService Thread Pool -- 264) HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
17:05:24,428 INFO  [org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory] (ServerService Thread Pool -- 264) HHH000397: Using ASTQueryTranslatorFactory
17:05:24,437 INFO  [org.hibernate.dialect.Dialect] (ServerService Thread Pool -- 264) HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL9Dialect
17:05:24,443 WARN  [org.hibernate.jpa.internal.schemagen.GenerationTargetToDatabase] (ServerService Thread Pool -- 264) Unable to execute JPA schema generation drop command [drop table HogeEntity cascade]
17:05:24,443 WARN  [org.hibernate.jpa.internal.schemagen.GenerationTargetToDatabase] (ServerService Thread Pool -- 264) Unable to execute JPA schema generation drop command [drop sequence hibernate_sequence]
17:05:24,663 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-8) JBAS017534: Register web context: /jpahello
17:05:24,671 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 1) JBAS018559: Deployed "jpahello.war" (runtime-name : "jpahello.war")

DBはどうなっているかというと

testdb=# \d
                 List of relations
 Schema |        Name        |   Type   |  Owner   
--------+--------------------+----------+----------
 public | hibernate_sequence | sequence | postgres
 public | hogeentity         | table    | postgres
(2 rows)

testdb=# \d hogeentity
             Table "public.hogeentity"
  Column  |            Type             | Modifiers 
----------+-----------------------------+-----------
 id       | bigint                      | not null
 hogedate | timestamp without time zone | 
Indexes:
    "hogeentity_pkey" PRIMARY KEY, btree (id)

testdb=# \d hibernate_sequence 
     Sequence "public.hibernate_sequence"
    Column     |  Type   |        Value        
---------------+---------+---------------------
 sequence_name | name    | hibernate_sequence
 last_value    | bigint  | 1
 start_value   | bigint  | 1
 increment_by  | bigint  | 1
 max_value     | bigint  | 9223372036854775807
 min_value     | bigint  | 1
 cache_value   | bigint  | 1
 log_cnt       | bigint  | 0
 is_cycled     | boolean | f
 is_called     | boolean | f

testdb=# 

自動で作ってくれると楽ですね

アクセスしてみる

リロードするたびに増えていきます。

テーブルも見てみましょう

testdb=# select * from hogeentity ;
 id |        hogedate         
----+-------------------------
  1 | 2014-01-20 17:09:57.694
  2 | 2014-01-20 17:09:58.091
  3 | 2014-01-20 17:09:59.28
  4 | 2014-01-20 17:09:59.475
  5 | 2014-01-20 17:09:59.629
  6 | 2014-01-20 17:09:59.812
  7 | 2014-01-20 17:09:59.966
  8 | 2014-01-20 17:10:03.878
(8 rows)

testdb=# 

ちゃんと動いているようですね

参考文献


Mavenプロジェクトにライブラリを追加してみる


Posted on Tuesday Jan 21, 2014 at 07:51AM in Technology


何をするの?

EclipseからMavenを使ってライブラリを追加してみます。

環境

  • Eclipse Kelper SR1
  • OS X 10.9.1
  • ここで作ったプロジェクトが対象

Commons Langを追加してみる

何がうれしいの

Commons Langのサイトに限らずJavaで書かれたライブラリのWebサイト等をみるとこういう表記を見かける事が有ります

ここに書かれた表記をpom.xmlに追記すれば、自動的にjarファイルをダウンロードしてきてプロジェクトの設定を更新してくれます。依存関係があったり数が多かったりすると自力でjarファイルを集めるのはとても大変なのですが、少しコピペするだけで済むのはすごくうれしい。

pom.xmlを編集する

まずEclipseでpom.xmlを開いてpom.xmlタブをクリックします

pom.xmlが表示されます

既にあるdependency要素の直後に、Commons Langのサイトに書いてあった内容を追記します(選択部分)。

保存すると右下の処理中インジケータが動き出します。処理が終わったらMaven Dependenciesを開いてみると

追加されていますね。自分でダウンロードしてゴニョゴニョとやるよりもだいぶ楽です。

参考文献


JUnitを動かしてみる


Posted on Tuesday Jan 21, 2014 at 07:48AM in Technology


何をするの?

EclipseからJUnitテストを動かしてみます

環境

  • Eclipse Kelper SR1
  • OS X 10.9.1
  • ここで作ったプロジェクトが対象

JUnitの設定

プロジェクトのプロパティを開いて、Java Build Pathを選ぶと何故かテスト用ディレクトリがおかしな事になっています。×印がついています。missingだそうです。

どうもディレクトリが無いようなので作ります。こんな感じ

作ったらプロジェクトをリフレッシュ

再度Java Build Pathを見てみましょう。×印が消えました。

テストを書いてみる

テストクラスを作る

jbatchのところで作ったクラスを対象にテストを書いてみましょう。右クリックしてNew→Otherを選びます

junitと検索すると現れるJUnit Test Caseを選んでNext

Source Folderは先ほど作ったテスト用のディレクトリに変更し、その他必要事項を入れてFinish

OK

テストクラスができました。

走らせてみる

メニューからRunを選びます

JUnit Testを選んでOKを押します

失敗なのが切ないですが動きましたね。Shift+Cmd+F11がショートカットなので使うと楽です。

参考文献


軽いUMLエディタ「Umlet」を使ってみる


Posted on Tuesday Jan 21, 2014 at 07:45AM in Technology


何をするの?

Javaで作られたUMLエディタUmletでUMLダイアグラムを書いてみます

環境

  • Umlet 12.2
  • Oracle JRE7 u51
  • OS X 10.9.1

Eclipseプラグイン版も存在するようですが、私はスタンドアロン版のumlet_12.2.zipというやつを取ってきました。

起動してみる

zipを展開してumlet.shを叩くと立ち上がります。

クラス図を描いてみる

クラスを一つ描いてみる

  1. 画面右上の部分にあるSimpleClassを画面左側にドラッグして持っていきます
  2. 右下のPropertiesの部分を編集してクラスの名前を変えたりメンバを追加していきます。編集するとリアルタイムで反映されます

他のツールと異なり非常にシンプルですがその分軽いです。

関連を描いてみる

  1. もう一つクラスを作ります

  2. 画面右上にある集約をダブルクリックします ちなみに画面左側でもダブルクリックでオブジェクトをコピーできます

  3. 画面左に新しく集約が作られます

  4. マウスで位置と長さを調節します

  5. カーディナリティを入れてみます

  6. ltの<を一つ追加してコンポジションに変えてみます

<の数で端の形が変わります。

  • 2つで継承

  • 1つで矢印

  • 0でただの線

Exportしてみる

どうやるの?

FileメニューからExport as...を選ぶと出来ます

PDF出力してみる

まあ普通ですね

日本語をPDF出力してみる

こんなのをPDFにすると

うーん何故か日本語が消えてしまいます

日本語をPNG出力してみる

PNGだと大丈夫

日本語をSVG出力してみる

SVGでもOKですね

その他

  • 矩形選択はCmd+ドラッグ
  • 折れ線は線の上の何も無いところでドラッグ

クラス図の他は?

いろいろ描けるみたいです。

参考文献


ロール、DB、権限、テーブルを定義してみる


Posted on Tuesday Jan 21, 2014 at 07:42AM in Technology


環境

  • PostgreSQL 9.2.6
  • CentOS 6.5
  • ここに書いた作業をした後

何をするの?

  • ロールの定義
  • データベースの作成
  • 権限の割当
  • テーブルの作成

ロールの定義

どんなロールが必要か?

こんなものだろうか

  1. 何でもできるスーパーユーザ
  2. データベースを作ったりは出来ないが、テーブルの読み書きとDDLも流せる人力メンテ用のユーザ
  3. テーブルの読み書きできるけどDDLは流せないアプリ用のユーザ

スーパーユーザでログインする

別に作らなくてもインストールしただけでpostgresというユーザが用意されている。こうするとログインできる

sudo -i -u postgres psql

createuserコマンドのオプション

-P
作成と同時にパスワードを設定する
-e
作成時に実行されるSQL文を表示する
-S
非スーパーユーザにする(デフォルト)。スーパーユーザにする場合は -s

人力メンテ用のユーザを作る

sudo -i -u postgres createuser -P -e -S kyle

アプリ用のユーザを作る

sudo -i -u postgres createuser -P -e -S wildfly

ユーザ一覧を見る

$ sudo -i -u postgres sh -c "psql -c 'select * from pg_shadow'"
 usename  | usesysid | usecreatedb | usesuper | usecatupd | userepl |               passwd                | valuntil | useconfig 
----------+----------+-------------+----------+-----------+---------+-------------------------------------+----------+-----------
 postgres |       10 | t           | t        | t         | t       |                                     |          | 
 kyle     |    16384 | f           | f        | f         | f       | ***                                 |          | 
 wildfly  |    16385 | f           | f        | f         | f       | ***                                 |          | 
(3 行)

$ 

テーブル単位とか細かい権限制御は別のコマンドを使うのだろう。

データベースの作成

オーナーを指定して作成する

ここでは人力メンテ用のユーザをオーナーにしてデータベースを作ってみましょう。

echo create database articles owner kyle encoding \'UTF8\' TEMPLATE template0 | sudo -i -u postgres psql 

データベース一覧を見る

sudo -i -u postgres sh -c "psql -c '\l'"

出来てますね。

$ sudo -i -u postgres sh -c "psql -c '\l'"
                                        データベース一覧
   名前    |  所有者  | エンコーディング | 照合順序 | Ctype(変換演算子) |      アクセス権       
-----------+----------+------------------+----------+-------------------+-----------------------
 articles  | kyle     | UTF8             | C        | C                 | 
 postgres  | postgres | SQL_ASCII        | C        | C                 | 
 template0 | postgres | SQL_ASCII        | C        | C                 | =c/postgres          +
           |          |                  |          |                   | postgres=CTc/postgres
 template1 | postgres | SQL_ASCII        | C        | C                 | =c/postgres          +
           |          |                  |          |                   | postgres=CTc/postgres
(4 行)

$ 

データベースを削除する

sudo -i -u postgres sh -c "psql -c 'drop database articles'"

権限の割当

いったんpublicスキーマの権限を全て剥奪する

sudo -i -u postgres sh -c "psql articles -c 'REVOKE ALL ON schema public FROM public'"

kyleはDDLを流せるようにする

sudo -i -u postgres sh -c "psql articles -c 'GRANT ALL ON schema public TO kyle'"

wildflyはCRUDのみ許可する

sudo -i -u postgres sh -c "psql articles -c 'GRANT USAGE ON schema public TO wildfly'"
sudo -i -u postgres sh -c "psql articles -c 'grant select, insert, update, delete on all tables in schema public to wildfly'"
sudo -i -u postgres sh -c "psql articles -c 'GRANT SELECT, UPDATE ON ALL SEQUENCES IN SCHEMA public TO wildfly'"

テーブルの作成

psqlコマンドでログインしてみる

psql articles

テーブル一覧を見る

\d

テーブルを作る

CREATE TABLE test_table (
    id          bigint                                 NOT NULL,
    description character varying(128)                 NOT NULL,
    name        character varying(128)          UNIQUE NOT NULL,
    seq         integer                         UNIQUE NOT NULL,
    created     timestamp without time zone            NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated     timestamp without time zone            NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id)
);

テーブル定義を見る

\d test_table

その他

DDLのダンプ

sudo -i -u postgres sh -c "pg_dump --schema-only articles" > dumped.sql

アプリ用ユーザからログインしてみる

sudo -i -u wildfly psql articles

psql実行中にデータベースを切り替える

\c hogedb
\c hogedb hogeuser

ユーザをスーパーユーザにする

ALTER ROLE kyle WITH CREATEROLE SUPERUSER

やってみる

kyle-no-MacBook:~ kyle$ psql -U postgres
Password for user postgres: 
psql (9.2.4)
Type "help" for help.

postgres=# ALTER ROLE kyle WITH CREATEROLE SUPERUSER;
ALTER ROLE
kyle-no-MacBook:~ kyle$ psql
Password: 
psql (9.2.4)
Type "help" for help.

kyle=# 

プロンプトが変わった。

ユーザを非スーパーユーザにする

kyle-no-MacBook:~ kyle$ psql
Password: 
psql (9.2.4)
Type "help" for help.

kyle=# ALTER ROLE kyle WITH CREATEROLE NOSUPERUSER;
ALTER ROLE
kyle=# \q
kyle-no-MacBook:~ kyle$ psql
Password: 
psql (9.2.4)
Type "help" for help.

kyle=> 

プロンプトが元に戻った。

参考文献