かえでBlog

色々なことを徒然と……

JAVA EE+Mybatis+GlassFishで動かしてみる。

      2015/01/06

NetBeansを利用してJava EE+Mybatis+GlassfishでWebアプリを構築しようと思います。

MySQLにてDBを構築し、Java EEより実際にDBにアクセスする方法をメモ書きとして掲載します。

JAVA+Struts1とibatisは経験済みですが、今回初めてJAVA EEに挑戦しようと思います。

使用情報

Java EE 7

Mybatis 3.2.8

JDBC(Mysql) 5.1.34

Glass Fish 4.1

作業開始

プロジェクトを作成し、各ファイルを作成していきます。

プロジェクトの作成

Netbeansにてプロジェクトを作成します。

netbeans 新規プロジェクト

新規プロジェクトにてMaven⇒Webアプリケーションで新規プロジェクトを作成します。

 

netbeans 新規プロジェクト2

各情報を入力します。

 

netbeans 新規プロジェクト3

GlassFish4.1に設定します。

 

プロジェクトに作成したものができたらOKです。

 

pom.xmlの設定

プロジェクトを作成したらpom.xmlに追記します。

<?xml version="1.0" encoding="UTF-8"?>
・
[中略]
・
<dependencies>
・
[中略]
・
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.8</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
 ・
 [中略]
 ・
<build>
 ・
 [中略]
 ・
         <!-- XMLファイルをビルドするように(ibatisエラー対策)-->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <filtering>true</filtering>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>
</project>

commons-langはStringUtilsやNumberUtils等利用する際に必要の為入れております。

中略が多くわかりにくいので全体のXML情報も掲載しておきます。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>jp.kaede</groupId>
    <artifactId>test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>test</name>

    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.8</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
    </dependencies>

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${endorsed.dir}</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>7.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <!-- XMLファイルをビルドするように(ibatisエラー対策)-->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <filtering>true</filtering>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>

</project>

sun-resources.xmlの作成

DBを利用するためにjdbc-resource及びjdbc-connection-poolを記述します。

GlassFishサーバ自体で設定することも可能ですが、今回はプロジェクトで設定します。

\src\main\setup\sun-resources.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Resource Definitions //EN" "http://www.sun.com/software/appserver/dtds/sun-resources_1_3.dtd">
<resources>
  <jdbc-resource enabled="true" jndi-name="jdbc/myDatasource" object-type="user" pool-name="connectionPool">
    <description/>
  </jdbc-resource>
  <jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="connectionPool" non-transactional-connections="false" pool-resize-quantity="2" res-type="javax.sql.DataSource" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">
    <description>MySQL</description>
    <property name="URL" value="jdbc:mysql://192.168.1.**:3306/test?relaxAutoCommit=true"/>
    <property name="User" value="test"/>
    <property name="Password" value="test"/>
  </jdbc-connection-pool>
</resources>

XMLで直で書く他に新規ファイルで設定することも可能です。

netbeans 新規プロジェクト4

JDBC接続プール及びJDBCリソースより設定可能です。

beans.xmlの作成

CDIを有効にするために必要。

\src\main\webapp\WEB-INF\web.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       bean-discovery-mode="annotated">
</beans>

faces-config.xmlの作成

JSFにて使用。なくてもいいみたいです。

\src\main\webapp\WEB-INF\faces-config.xml

<?xml version="1.0"?>
<faces-config version="2.0"
              xmlns="http://java.sun.com/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2.0.xsd">
     
</faces-config>

glassfish-web.xmlの作成

\src\main\webapp\WEB-INF\glassfish-web.xml

リソース設定に必要。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
  <class-loader delegate="true"/>
  <jsp-config>
    <property name="keepgenerated" value="true">
      <description>Keep a copy of the generated servlet class' java code.</description>
    </property>
  </jsp-config>
</glassfish-web-app>

sun-web.xmlの作成

リソース設定に必要。

\src\main\webapp\WEB-INF\sun-web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Servlet 2.5//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd">
<sun-web-app error-url="">
  <context-root>/test</context-root>
  <class-loader delegate="true"/>
  <jsp-config>
    <property name="keepgenerated" value="true">
      <description>Keep a copy of the generated servlet class' java code.</description>
    </property>
  </jsp-config>
</sun-web-app>

web.xmlの作成

リソース設定に必要。

\src\main\webapp\WEB-INF\sun-web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	 version="3.1">
    <display-name>test</display-name>
    <!-- JSF -->
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>10</session-timeout>
    </session-config>
</web-app>

 

テーブル作成

Mybatisと連携するために今回はMySQLを利用することにしました。

サンプルテーブルとしてusersテーブルを作成します。

CREATE TABLE test.users
(
    id                          BIGINT NOT NULL,
    user_id                     VARCHAR(64) NOT NULL,
    user_pass                   VARCHAR(128) NOT NULL,
    user_name                   VARCHAR(128) NOT NULL,
    mail                        VARCHAR(256),
    CONSTRAINT PRIMARY KEY (id)
);

コードの自動生成

こちらにてMybatis Generatorでコードの自動生成を行います。

ソースコード記述開始

上記でサーバ起動に必要な情報を記載しました。以後にソースコードを記述していきます。

SessionUtil.javaの作成

DB接続用のソースを記述します。

\src\main\test\mybatis\util\SessionUtil.java

package jp.kaede.test.mybatis.util;


import javax.naming.InitialContext;
import javax.sql.DataSource;

import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;

/**
 *
 * @author 渉猟
 */
public class SessionUtil {

    private SessionUtil() {
    }

    public static SqlSession createSession() {
        SqlSession session = null;
        SqlSessionFactory ssf = null;

        try {
            DataSource dataSource = InitialContext.doLookup("jdbc/myDatasource");
            TransactionFactory transactionFactory = new JdbcTransactionFactory();
            Environment environment = new Environment("development", transactionFactory, dataSource);
            Configuration configuration = new Configuration(environment);
            configuration.addMappers("jp.kaede.test.mybatis.cmn.mapper");
            ssf = new SqlSessionFactoryBuilder().build(configuration);
            session = ssf.openSession(false);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return session;
    }
}

UserSearch.javaの作成

\src\main\test\UserSearch.java

メインソース。入力した値を元にuserテーブルを検索するソースです。

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package jp.kaede.test;

import java.io.Serializable;
import java.util.List;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import jp.kaede.test.mybatis.cmn.mapper.UsersMapper;
import jp.kaede.test.mybatis.cmn.model.UsersKey;
import jp.kaede.test.mybatis.util.SessionUtil;
import jp.kaede.test.mybatis.cmn.model.Users;
import jp.kaede.test.mybatis.cmn.model.UsersExample;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.ibatis.session.SqlSession;

/**
 *
 * @author 渉猟
 */
@Named
@SessionScoped
public class UserSearch implements Serializable {

    private String userId;

    private String userName;

    private String userName2;

    private String userId2;

    private static UsersMapper usersMapper;

    private List<Users> userList;

    public String getUserId() {
        return userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    /**
     * @return the userList
     */
    public List<Users> getUserList() {
        return userList;
    }

    /**
     * @param aUserList the userList to set
     */
    public void setUserList(List<Users> aUserList) {
        userList = aUserList;
    }

    public String search() {
        if (!NumberUtils.isNumber(userId)) {
            return null;
        }
        // セッション作成
        SqlSession session = SessionUtil.createSession();
        //Mapperの取得
        usersMapper = session.getMapper(UsersMapper.class);
        try {
            UsersKey usersKey = new UsersKey();
            usersKey.setId(Long.parseLong(userId));
            Users users = usersMapper.selectByPrimaryKey(usersKey);

            //users = session.selectOne("jp.kaede.test.mybatis.cmn.mapper.UsersMapper.selectByPrimaryKey", 1L);
            if (users != null) {
                userName = users.getUserName();
            } else {
                userName = "ユーザは存在しません。";
            }
        } finally {
            session.rollback();
            session.close();
        }
        return null;
    }

    public String search2() {
        // セッション作成
        SqlSession session = SessionUtil.createSession();
        //Mapperの取得
        usersMapper = session.getMapper(UsersMapper.class);
        try {
            UsersExample usersExample = new UsersExample();
            usersExample.createCriteria().andUserNameEqualTo(userName2);
            List<Users> userses = usersMapper.selectByExample(usersExample);
            if (!userses.isEmpty()) {
                setUserList(userses);
            }else{
                
            }

        } finally {
            session.rollback();
            session.close();
        }
        return null;
    }

    /**
     * @return the userName2
     */
    public String getUserName2() {
        return userName2;
    }

    /**
     * @param userName2 the userName2 to set
     */
    public void setUserName2(String userName2) {
        this.userName2 = userName2;
    }

    /**
     * @return the userId2
     */
    public String getUserId2() {
        return userId2;
    }

    /**
     * @param userId2 the userId2 to set
     */
    public void setUserId2(String userId2) {
        this.userId2 = userId2;
    }

}
            

test.xhtmlの作成

ユーザ情報を検索しする画面表示用のソース。

IDにてユーザ名を検索することや、ユーザ名よりユーザID、ユーザ名、メールアドレスを表示します。

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

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://xmlns.jcp.org/jsf/passthrough"
      xmlns:jsf="http://xmlns.jcp.org/jsf">
    <head>
        <title>TODO supply a title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    </head>
    <body>
        <div>呼出テスト</div>
      <form jsf:id="form">
            <div>
                <p>ID検索</p>
                <input type="text" jsf:id="userId" jsf:value="#{userSearch.userId}" p:placeholder="ユーザID"/>
                <br/>
                ユーザ名:#{userSearch.userName}<br/>
                <h:commandButton id="SearchButton" value="検索" action="#{userSearch.search}" />
            </div>
            <div>
                <p>名前検索</p>
                <input type="text" jsf:id="userName" jsf:value="#{userSearch.userName2}" p:placeholder="ユーザ名" />
                <br/>
                <h:commandButton id="SearchButton2" value="名前検索" action="#{userSearch.search2}" />
                <br/>
                <div jsfc="ui:repeat" value="#{userSearch.userList}" varStatus="loop">
                    ID:#{userSearch.userList[loop.index].id}<br/>
                    ユーザID:#{userSearch.userList[loop.index].userId}<br/>
                    ユーザ名:#{userSearch.userList[loop.index].userName}<br/>
                    メールアドレス:#{userSearch.userList[loop.index].mail}<br/>
                </div>
                
            </div>
                
</form>
</body>
</html>

            

あとはプロジェクトを右クリック⇒実行を押します。

ブラウザにて【http://localhost:8080/test/test.jsf】で開くと下の画像が表示されます。

テストプロジェクト 結果

データ未挿入時は何も表示されませんが、データを挿入すると表示されます。

テストプロジェクト 結果2

Mybatisの接続方法をJAVAのみで設定していますが、xmlにて設定することもできるようです。(私の場合上手くいきませんでしたが…)

Mybatisを動かすまでに結構悪戦苦闘しましたがなんとか動くことができましたので、これで先に進めそうです。

 - 開発, JAVA, JAVA EE , ,