スポンサーリンク

2016年8月31日

[Java]泣く泣く復習するJava(二日目)

Goal

  • Java8+Maven3+MyBatisでCRUD操作をする

Dev-Environment

OS: Windows8.1
PostgreSQL: 9.4.4
Java: v1.8.0_102
Maven: v3.3.9
MyBatis: v3.4.1
JDBC: postgresql v9.1-901-1.jdbc4

Prerequisite: Java、Maven、PostgreSQLに関してはインストール済み、解凍済み、環境変数設定済みであること…

Note: JDBCはいらないような記事とか情報があったが、ないと動かなかったので入れます。

Context

一日目の続きです。
さてさて、何の因果かJavaをやることになってしった怠惰のアルケミスト…とりあえず、ぼちぼちByBatisを今日はいじるのであった。
MyBatis(+JDBC)の導入から、(DAOなし)CRUD操作までを掲載しています。
多分、この記事が一番わかりやすい。DAOもやってくれているので是非参考にしてみてください~
参考: Getting Started with MyBatis 3: CRUD Operations Example with XML Mapper
仕方ないからやっていきますか…(*´・д・)=3
あぁそうそう、アノテーションを使わない面倒な方のパターンです。
「xmlいやじゃ!」って人はブラウザバックを推奨します。
まずは、DBを作りましょう。
MigrationツールとしてFlywayとかってのがあるらしいですが、今回利用はしません。
面倒くさいとかってわけじゃにゃいです!

Example:

> psql -U [user_name]
ユーザ [user_name] のパスワード: ****

## DB作成
=# CREATE DATABASE mybatis_demo;

## DB接続
=# \c mybatis_demo

## テーブル作成
mybatis_demo=# create table public.user (
mybatis_demo(# id serial PRIMARY KEY,
mybatis_demo(# name varchar(255),
mybatis_demo(# email varchar(255));

## テーブル一覧
mybatis_demo=# \d
               リレーションの一覧
 スキーマ |    名前     |     型     |  所有者
----------+-------------+------------+----------
 public   | user        | テーブル   | postgres
 public   | user_id_seq | シーケンス | postgres
(2 行)

## データインサート
mybatis_demo=# INSERT INTO "user" (name, email) VALUES ('hoge', 'hoge@test.com');
mybatis_demo=# INSERT INTO "user" (name, email) VALUES ('foobar', 'foobar@test.com');

## データセレクト
mybatis_demo=# SELECT * FROM "user";
 id |  name  |      email
----+--------+-----------------
  1 | hoge   | hoge@test.com
  2 | foobar | foobar@test.com
(2 行)
pomファイルへ依存関係を追加します。

File: pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project>
    ....

    <dependencies>
        ...

        <!-- ここから -->
        <!-- Mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!-- PostgreSQL JDBC -->
        <dependency>
            <groupId>postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.1-901-1.jdbc4</version>
        </dependency>
        <!-- ここまで -->
    </dependencies>

    <build>
      ...
    </build>
</project>
MyBatis用のコンフィグファイルを作成します。
(ここで、マッピング用のXMLファイルを指定してますね)

File: src/main/resources/mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="org.postgresql.Driver" />
        <property name="url" value="jdbc:postgresql://localhost:5432/mybatis_demo" />
        <property name="username" value="****" />
        <property name="password" value="****" />
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="local/mybatis/mapper/UserMapper.xml"/>
  </mappers>
</configuration>
次は、マッピング用のXMLファイルを作成します。
これは、各モデル毎に用意することになるでしょうね。
(ディレクトリがなければ作成してください)

File: src/main/resources/local/mybatis/mapper/UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="local.mybatis.mapper.UserMapper">
  <select id="all" resultType="local.mybatis.model.User">
    select * from "user"
  </select>
  <select id="get" resultType="local.mybatis.model.User" parameterType="int">
    select * from "user" where id = #{id}
  </select>
  <select id="getByName" resultType="local.mybatis.model.User" parameterType="string">
    select * from "user" where name = #{name}
  </select>
  <insert id="insert" parameterType="local.mybatis.model.User">
    insert into "user" (name, email) values (#{name}, #{email})
  </insert>
  <update id="update" parameterType="local.mybatis.model.User">
    update "user" set name=#{name}, email=#{email} where id = #{id}
  </update>
  <delete id="delete" parameterType="int">
    delete from "user" where id = #{id}
  </delete>
</mapper>
マッピング用のxmlに対応した、Java側のインターフェースを用意します。
インターフェースの実装は中で上手くやってくれるらしいのでいらないみたいです。
(今回、resultMapなんかは用意していないが、名前変更などがあったときのためにやっておいた方がいいと思う)

File: src/main/java/local/mybatis/mapper/UserMapper.java

package local.mybatis.mapper;

import local.mybatis.model.User;
import java.util.List;

public interface UserMapper {
  public List<User> all();
  public User get(int id);
  public User getByName(String name);
  public void insert(User user);
  public void update(User user);
  public void delete(int id);
}
Userのモデルファイルを用意します。
セッター/ゲッターを用意しておけばいい。

File: src/main/java/local/mybatis/model/User.java

package local.mybatis.model;

public class User {
  private Integer id;
  private String name;
  private String email;

  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getEmail() {
    return email;
  }

  public void setEmail(String email) {
    this.email = email;
  }
}
あんまりよくない例だけど、テストファイルを用意してJUnitを使って実行できるようにする。
とりあえずの動作検証なので、テスト分けろよとか長いとかは聞きたくない…
(TDDのかけらも存在していない(汗))

File: src/test/java/local/MybatisTest.java

package local;

import junit.framework.TestCase;

import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import local.mybatis.model.User;
import local.mybatis.mapper.UserMapper;

/**
 * 
 */
public class MybatisTest extends TestCase {

    public void testMybatis() throws Exception {
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory session_factory = new SqlSessionFactoryBuilder().build(in);
        SqlSession session = session_factory.openSession();

        try {
          UserMapper mapper = session.getMapper(UserMapper.class);

          // select all
          List<User> all_user = mapper.all();
          assertEquals(all_user.size(), 2);
          System.out.println("all:" + all_user);

          // select
          User hoge = mapper.get(1);
          assertEquals(hoge.getName(), "hoge");
          assertEquals(hoge.getEmail(), "hoge@test.com");

          // insert
          User insertParameter = new User();
          insertParameter.setName("huge");
          insertParameter.setEmail("huge@test.com");
          mapper.insert(insertParameter);
          session.commit();

          User insertUser = mapper.getByName("huge");
          assertEquals(insertUser.getName(), "huge");
          assertEquals(insertUser.getEmail(), "huge@test.com");

          // update
          User updateParameter = new User();
          updateParameter.setId(insertUser.getId());
          updateParameter.setName("updatehuge");
          updateParameter.setEmail("updatehuge@test.com");
          mapper.update(updateParameter);
          session.commit();

          User update_user = mapper.getByName("updatehuge");
          assertEquals(update_user.getName(), "updatehuge");
          assertEquals(update_user.getEmail(), "updatehuge@test.com");

          // delete
          mapper.delete(insertUser.getId());
          session.commit();
          assertEquals(mapper.all().size(), 2);
        } finally {
          session.close();
        }
    }
}
一度作れば少し楽ができるけど、やっぱり導入の段階で色々面倒が多い。
(もう少し何とかならんのだろうかね…)

Note: 自分の力のなさを言語やツールのせいにするのはやめましょう~

しかし、なんでかJavaでは気持ちよくプログラムできない…いちいちプログラムじゃないところで止まって、むしろ疲れる。
(気持ちよく軽快にプログラムしたいだけの人生だった…)
お疲れ様です。これで今日の分は終了です。(-_-)ノシ・・・ハァ・・・

Bibliography

2016年8月30日

[Java]泣く泣く復習するJava(一日目)

Goal

  • Java8+Maven3+Struts2+Tomcat7で「struts2-archetype-starter」プロジェクトを構築し、ページを表示する

Dev-Environment

OS: Windows8.1
Java: v1.8.0_102
Maven: v3.3.9
Struts2: v2.5.2
Tomcat7: tomcat7-maven-plugin v2.2

Prerequisite: Java、Mavenに関してはインストール済み、解凍済み、環境変数設定済みであること…

Context

はてさて、何の因果かJavaをやることになってしまいまして…。
ただ、Javaを使っていたのはJava5かJava6くらいで、もう数年前になります。
おかげで、さっぱり今のやり方が分からないので、仕方なく…そう仕方なく、渋々Javaを復習することにしました。
とりあえず、ダウンロードできる最新っぽい奴を適当に組み合わせて、
「struts2-archetype-starter」のプロジェクトを構築し、最初のページまでを表示します。
(Eclipseについては使わないのであしからず~)
Javaの最低限の文法はこの二つで間に合うかと…
早速、Mavenのプロジェクトを作っていく。

Example:

> java -version
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)

> mvn -v
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T01:41:47+09:00)
Maven home: C:\MyWorkSpaces\tools\java\maven\apache-maven-3.3.9\bin\..
Java version: 1.8.0_102, vendor: Oracle Corporation
Java home: C:\MyWorkSpaces\tools\java\jdk8u102\jre
Default locale: ja_JP, platform encoding: MS932
OS name: "windows 8.1", version: "6.3", arch: "amd64", family: "dos"

> cd path/to/workspace

> mkdir example
> cd example

> mvn archetype:generate
...

色々と処理が流れているが下記の文言が出るまで放置。
番号かフィルタを選択しろって出てくるので、「struts2」と入力し、Enter!

Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 828: struts2
Choose archetype:
1: remote -> br.com.address.archetypes:struts2-archetype (an archetype web 3.0 + struts2 (bootstrap + jquery) + JPA 2.1 with struts2 login system)
2: remote -> br.com.address.archetypes:struts2-base-archetype (An Archetype with JPA 2.1; Struts2 core 2.3.28.1; Jquery struts plugin; Struts BootStrap plugin; json Strut
Login System using Session and Interceptor)
3: remote -> com.jgeppert.struts2.jquery:struts2-jquery-archetype-base (This Archetype provides a Webapp Configuration ready for the Struts2 jQuery Plugin.)
4: remote -> com.jgeppert.struts2.jquery:struts2-jquery-archetype-mobile (This Archetype provides a Webapp Configuration ready for the Struts2 jQuery Mobile Plugin.)
5: remote -> com.jgeppert.struts2.jquery:struts2-jquery-bootstrap-archetype-grid (This Archetype provides a Webapp Configuration ready for the Struts2 jQuery Grid Plugin
ruts2
        Bootstrap Plugin.)
6: remote -> org.apache.struts:struts2-archetype-angularjs (-)
7: remote -> org.apache.struts:struts2-archetype-blank (-)
8: remote -> org.apache.struts:struts2-archetype-convention (-)
9: remote -> org.apache.struts:struts2-archetype-dbportlet (-)
10: remote -> org.apache.struts:struts2-archetype-plugin (-)
11: remote -> org.apache.struts:struts2-archetype-portlet (-)
12: remote -> org.apache.struts:struts2-archetype-starter (-)

同じ文言が出てくるので、次は番号を選択する。
今回、構築するプロジェクトは「struts2-archetype-starter」なので、「12」を選択する。

Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 12
Choose org.apache.struts:struts2-archetype-starter version:
1: 2.0.11.2
2: 2.2.1
3: 2.2.1.1
4: 2.2.3
5: 2.2.3.1
6: 2.3.7
7: 2.3.8
8: 2.3.12
9: 2.3.14
10: 2.3.14.1
11: 2.3.14.2
12: 2.3.14.3
13: 2.3.15
14: 2.3.15.1
15: 2.3.15.2
16: 2.3.15.3
17: 2.3.16
18: 2.3.16.1
19: 2.3.16.2
20: 2.3.16.3
21: 2.3.20
22: 2.3.20.1
23: 2.3.20.3
24: 2.3.24
25: 2.3.24.1
26: 2.3.24.3
27: 2.3.28
28: 2.3.28.1
29: 2.3.29
30: 2.3.30
31: 2.5-BETA1
32: 2.5-BETA2
33: 2.5-BETA3
34: 2.5
35: 2.5.1
36: 2.5.2

Maven3.3.9で利用できるStruts2のバージョン一覧が出てくる。
とりあえず、最新でいいので「36」を選択する。

Choose a number: 36: 36

グループID、アーティファクトID、バージョン、パッケージの順に入力するよう出力される。

Define value for property 'groupId': : local
Define value for property 'artifactId': : example
Define value for property 'version':  1.0-SNAPSHOT: : (入力なしでEnter)
Define value for property 'package':  local: : (入力なしでEnter)

入力内容を確認し、「y」を入力し、Enter!

Confirm properties configuration:
groupId: local
artifactId: example
version: 1.0-SNAPSHOT
package: local
 Y: : y

プロジェクトが下記のとおり生成されたとメッセージが出力される。

[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: struts2-archetype-starter:2.5.2
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: local
[INFO] Parameter: artifactId, Value: example
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: local
[INFO] Parameter: packageInPathFormat, Value: local
[INFO] Parameter: package, Value: local
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: groupId, Value: local
[INFO] Parameter: artifactId, Value: example
[INFO] project created from Archetype in dir: C:\...\java_space\example\example
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 06:35 min
[INFO] Finished at: 2016-08-30T15:04:42+09:00
[INFO] Final Memory: 14M/175M
[INFO] ------------------------------------------------------------------------
ちょっと長くなってしまったが、これでプロジェクトの作成は完了。
さて、さっそく実行して、ページを確認したいと思うのだが、残念ながら今の段階ではいくつかエラーが発生する。
これからその修正をしていくが、その前に一応エラーを確認してみる。

Example:

> cd example

> mvn test
[INFO] Scanning for projects...
[ERROR] [ERROR] Some problems were encountered while processing the POMs:
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-compiler-plugin is missing. @ line 92, column 15
[ERROR] 'dependencies.dependency.version' for org.apache.logging.log4j:log4j-core:jar must be a valid version but is '${log4j2.version}'. @ line 78, column 22
 @
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR]   The project local:example:1.0-SNAPSHOT (C:\MyWorkSpaces\darui_works_local\java_space\example\example\pom.xml) has 1 error
[ERROR]     'dependencies.dependency.version' for org.apache.logging.log4j:log4j-core:jar must be a valid version but is '${log4j2.version}'. @ line 78, column 22
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
まず、下記のエラーを修正する。(こいつは簡単)
[ERROR] 'dependencies.dependency.version' for org.apache.logging.log4j:log4j-core:jar must be a valid version but is '${log4j2.version}'. @ line 78, column 22
pom.xmlを開き、log4j2のversionタグの部分を下記のように修正する。

File: pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>local</groupId>
    <artifactId>example</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>example</name>
    <description>Struts 2 Starter</description>

    <properties>
        <struts2.version>2.5.2</struts2.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        ...

        <!-- Logging -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.5</version> <- Update it!!
        </dependency>

        ...

    <build>
        ...
    </build>
</project>
何で、最新じゃなくてv2.5かって?一番利用件数が多かったからですよ!

Example:

> mvn test
これでテストは実行できました。
一応、Javaのバージョン指定も1.8に変更しておく。

File: pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project>
    ...

    <build>
        <finalName>struts2-archetype-starter</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                   <source>1.8</source> <-- Update it!!
                   <target>1.8</target> <-- Update it!!
                </configuration>
            </plugin>
            <plugin>
                ...
            </plugin>
        </plugins>
    </build>
</project>
次は、Tomcatのプラグインを導入する。
pom.xmlを開いて下記のプラグインの記述を追加する。

File: pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project>
    ...

    <build>
        <finalName>struts2-archetype-starter</finalName>
        <plugins>
            ...

            <!-- Tomcat -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <path>/</path>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Example:

> mvn tomcat7:run
...
実行してページを確認する。

http://localhost:8080/

一応、ページの確認までできたがこれで終わりではない。
まだ、starterで生成されたページで動かない部分がある。

File: src/main/resources/struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
...

<struts>

    ...

    <package name="myPackage" extends="struts-default">

        ...

        <action name="helloWorld" class="local.HelloWorldAction"> <-- Update it!!
            ...
        </action>

    </package>

</struts>
これで、index.actionページのMain Contentの入力部分に適当な文言を入力し、Submitすると、
helloWorld.actionページが表示できるようになる。
ちょっと駆け足及び、雑な部分が多々あるが、
Javaをメインに据える気はまったくないので、最低限実行できるところまでならこれで十分メモになる。
以上、誰にも役に立たないと思うけど、役に立ったら幸いです。

Note: 実はコンソールにロガーのエラーが出ている

ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.

とりあえず動くから今は直さないが...

Bibliography

人気の投稿