ITエンジニアぽむのブログ

IT系で気になったことを書き留めておく備忘録です。仕事でよく使っているJavaと自宅で使っているLinuxについて書いていこうと思っています。同じお悩みをお持ちの方のお役に立てたら嬉しいです。

新規登録と編集登録を1画面でできる画面を作ってみよう!

こんにちは、ぽむです!

今回はjQueryを駆使した新規登録画面とStruts2フレームワークでの画面遷移をご紹介したいと思います。

はじめに

テーブルのデータをリスト表示した画面に新規ボタンを追加し、新規登録画面に遷移するまでの流れを見ていきたいと思います。

テーブルのデータを画面上に表示するプログラムについては下記サイトで書いているので、よかったら参考にして下さいね。

pom2019.hatenablog.com

javascriptの処理を簡素化するために、本プログラムはjQueryCDNを使っています。

CDNとは、Content Delivery Networkの略で、プログラム本体をダウンロードせずにネットワーク上のプログラムを読みにいくことです。

jQueryCDNについては、jQuery本家よりGoogleCDNの方がアクセスし易いみたいなので、今回はGoogleCDNを使用します。GoogleCDNについてはリンクを載せておくので、よかったら参考にして下さいね。

developers.google.com

編集ボタンと削除ボタンは、今回使用しません。ご注意下さい。

開発環境

開発環境は下記の通りです。

Struts22.5.14.1
Hibernate4.3.0.Final
MySQL8.0.16

画面の作成

新規ボタンの追加

  1. ボタンの設置
    ボタンタグを入力して、新規ボタンを設定します。(20行目)
  2. 新規ボタンのアクション追加
    新規ボタンを押した際のアクション設定を追加します。ここでは、「/dispModify」アクションを呼び出しています。(42-45行目)
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <title>家電リスト</title>
        <style>
    table {
        border-collapse: collapse;
    }
    td {
        border: 1px solid gray;
        padding: 3px 8px;
    }
    </style>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<h2>家電リスト</h2>

<p>
    <button id="btnNew">新規</button>
</p>

<table>
    <tr>
        <td>id</td>
        <td>家電名</td>
        <td>購入日時</td>
        <td colspan="2">アクション</td>
    </tr>
    <s:iterator value="list">
        <tr>
            <td><s:property value="id"/></td>
            <td><s:property value="householdAppliancesName"/></td>
            <td><s:date name="purchaseDate" format="yyyy/MM/dd"/></td>
            <td><button id="btnEdit">編集</button></td>
            <td><button id="btnDelete">削除</button></td>
        </tr>
    </s:iterator> 
</table>

<script>
   $(function() {
       //新規ボタン
       $('#btnNew').on('click', function() {
           //クエリ文字列で新規登録フラグを立てます
           location.href = "${pageContext.request.contextPath}/dispModify?isNew=true";
       });
   });
</script>
</body>
</html>

新規登録画面の作成

  1. 登録用テーブルの作成
    id、家電名、購入日時を入力できるテーブルを作成します。idは自動採番なので入力できません。(32-51行目)
  2. 新規登録フラグで分岐
    新規登録フラグが立っているかどうかで表示を切り替えます。(36-41行目)
  3. 日付ピッカーの設置
    jQuery UIを使い、日付の入力間違いを防止します。
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <title>家電情報の登録</title>
    <style>
    table {
        border-collapse: collapse;
    }
    td {
        border: 1px solid gray;
        padding: 3px 8px;
    }
    .grayStyle {
        background: lightgray;
    }
    </style>
    <%-- jQuery --%>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <%-- jQuery UI --%>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/themes/base/jquery-ui.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
    <%-- jQuery UI(日本語ライブラリ) --%>
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/i18n/jquery.ui.datepicker-ja.min.js"></script>
</head>
<body>
<h2>家電情報の登録</h2>

<p>
    <button id="btnBack">戻る</button>
    <button id="btnSave">保存</button>
</p>

<table>
    <tr>
        <td>id</td>
        <td id="id" class="grayStyle">
            <s:if test='"true".equals(isNew)'>
                idは自動採番されます。
            </s:if>
            <s:else>
                <s:property value="id"/>
            </s:else>
        </td>
    <tr>
        <td>家電名</td>
        <td><input id="householdAppliancesName" type="text" value="<s:property value='householdAppliancesName'/>"/></td>
    </tr>
    <tr>
        <td>購入日時</td>
        <td><input id="purchaseDate" type="text" value="<s:date name='purchaseDate' format='yyyy/MM/dd'/>" readonly="readonly"/></td>
    </tr>
</table>

<script>
   $(function() {
       //日付ピッカーの設定
       $('#purchaseDate').datepicker({
           dateFormat: 'yy/mm/dd',
           changeYear: true,
           changeMonth: true
       });
       
       //戻るボタン
       $('#btnBack').on('click', function() {
           history.back();
       });
   });
</script>
</body>
</html>

ロジックの作成

モデルの追加

「isNew」を新規登録フラグとして使用するため、モデルに追加します。

package com.pom2019.Struts2Web.model;

import java.util.List;

import com.pom2019.Struts2Web.entities.HouseholdAppliances;

public class IndexModel {
    private List<HouseholdAppliances> list;
    //新規登録フラグ
    private String isNew;

    //ゲッター、セッター
    public List<HouseholdAppliances> getList() {
        return list;
    }
    public void setList(List<HouseholdAppliances> list) {
        this.list = list;
    }
    public String getIsNew() {
        return isNew;
    }
    public void setIsNew(String isNew) {
        this.isNew = isNew;
    }
}

アクションの追加

登録画面に遷移するアクションを追加します。

   @Action(value = "dispModify", results = {
            @Result(name = "success", location = "/WEB-INF/content/displayModify.jsp")
    })
    public String dispModify() {
        return ActionSupport.SUCCESS;
    }

実行結果

家電リスト画面を表示します。

f:id:pom2019:20190907163302p:plain

新規ボタンをクリックして、新規登録画面を表示します。

f:id:pom2019:20190907163337p:plain

日付ピッカーも表示できています。 f:id:pom2019:20190907163359p:plain

おわりに

フレームワークが間を取り持つ細かな処理を受け持ってくれているので、画面作成と簡単なアクションを書けば、簡単に実装することができます。

最後までお読み頂きありがとうございました。

Struts2を使ってテーブルのデータを表で表示してみよう!

データベースに格納されているテーブルのデータを画面上に表として表示するプログラムをご紹介したいと思います。

下記サイトでテーブルのデータをリストデータとして取得する方法を書いているので、よかったら参考にして下さいね。

iteng-pom.com

はじめにセッションファクトリーを使って、データベースに格納されているデータにアクセスする、DAOをご紹介したいと思います。セッションファクトリーを取得する方法については、リンクを載せておきますので、よかったら参考にして下さいね。作成するDAOは、データ... 今回扱うJavaフレームワークは「Struts2」です。

Struts2ではモデルとしてリストデータを渡してあげれば、繰り返し処理を使って(s:iterator)、データを表示することができます。

モデルとは、MVC(Model View Controller)デザインパターンのモデルのことです。

MVCとは、プログラムをModel(データそのものやデータ操作)とView(画面)とController(MとVの橋渡し役もしくは司令塔的な役割)の3つに分けて作成しようという考え方です。

今回で言うと、コントローラがモデルからビューにデータを渡すイメージです。

本ページ引っ越しのご案内

本ページは引っ越しました。

お手数ですが、続きは下記URLまでアクセスください。

iteng-pom.com

テーブルを全検索するDAOを作ってみよう!

まえがき

セッションファクトリーを使って、データベースに格納されているデータにアクセスする、DAOをご紹介したいと思います。

セッションファクトリーを取得する方法については、リンクを載せておきますので、よかったら参考にして下さいね。

pom2019.hatenablog.com

作成するDAOは、データベースに格納されているテーブル内のデータを全検索しようというものです。

DAOとは、Data Access Objectsの略でデータ操作をまとめたプログラムのことです。

開発環境

開発環境は下記の通りです。

Struts22.5.14.1
Hibernate4.3.0.Final
MySQL8.0.16

DAOの作成

DAO作成の手順は、下記の通りになります。

  1. セッションファクトリーの設定
    コンストラクタの引数にセッションファクトリーを指定して、DAO内でセッションファクトリーを使用できるようにしています。
  2. セッションのオープン
    1.で取得したセッションファクトリーを使って、セッションをオープンしています。
  3. クエリの実行
    HQLを使い、HouseholdAppliancesテーブルを全検索しています。ここで指定しているHouseholdAppliancesは、エンティティ名です。


実装例は、下記の通りになります。

package com.pom2019.Struts2Web.entities.dao;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.pom2019.Struts2Web.entities.HouseholdAppliances;

public class HouseholdAppliancesDao {

    private SessionFactory sf;

    public HouseholdAppliancesDao() {
        super();
    }

    public HouseholdAppliancesDao(SessionFactory sf) {
        super();
        this.sf = sf;
    }

    @SuppressWarnings("unchecked")
    public List<HouseholdAppliances> findAll() {
        Session ss = sf.openSession();
        return ss.createQuery("from HouseholdAppliances").list();
    }
}

DAOの呼び出し

DAOクラスのインスタンス化とDAOを呼び出してリストを取得する処理は、下記の通りになります。

SessionFactory sf = (SessionFactory) context.getAttribute(HibernateListener.KEY_NAME);
        
HouseholdAppliancesDao hDao = new HouseholdAppliancesDao(sf);
List<HouseholdAppliances> hList = hDao.findAll();
setList(hList);

あとがき

DAOという形でデータ操作に関する処理をまとめれば、メンテナンス性が上がり後から処理の追加や変更が簡単に行なえます。

今回は、テーブルを全検索する方法について説明しましたが、プライマリーキーや特定のカラムでの検索、ソーティング、HQLでないSQLでのデータ取得などDAOで行うメソッドを追加すれば、拡張することができます。

もちろん、データの登録、更新、削除といったデータベース操作もDAOに追加することができます。

最後までお読み頂きありがとうございました。

Webアプリ実行時にセッションファクトリーを取得しよう!

まえがき

サーバ起動時に保存したセッションファクトリーをWebアプリ起動時の変数として取得する方法についてご紹介したいと思います。

サーバ起動時にセッションファクトリーを取得/保存する方法については、前回のブログを参考にして下さいね!

pom2019.hatenablog.com

開発環境

開発環境は下記の通りです。

セッションファクトリーの取得

  1. ServletContextを取得します。

    Struts2では、ServletContextAwareをインプリメントすることでServletContextを取得することができます。

  2. 1.から属性(HibernateListener.KEY_NAME)を取得します。

    SevletContextからHibernateListener.KEY_NAME属性として保持していたSessionFactoryを取得します。

  3. 2.をSessionFactoryでキャストします。

    2.はObject型で返ってくるので、SessionFactoryでキャストしています。

実装例は下記の通りとなります。

package com.pom2019.Struts2Web.actions;

import com.opensymphony.xwork2.ActionSupport;
import com.pom2019.Struts2Web.entities.HouseholdAppliances;
import com.pom2019.Struts2Web.entities.dao.HouseholdAppliancesDao;
import com.pom2019.listener.HibernateListener;

import java.util.List;

import javax.servlet.ServletContext;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.conventiServletContextAwareon.annotation.Result;
import org.apache.struts2.util.ServletContextAware;
import org.hibernate.SessionFactory;

@Namespace("/")
@ParentPackage("struts-default")
public class Index extends ActionSupport implements ServletContextAware {
    private static final long serialVersionUID = -1884587001523422505L;
    ServletContext context;
    private List<HouseholdAppliances> list;
    
    @Action(value = "display", results = {
            @Result(name = "success", location = "/WEB-INF/content/displayList.jsp")
    })
    public String execute() {
        SessionFactory sf = (SessionFactory) context.getAttribute(HibernateListener.KEY_NAME);
        
        HouseholdAppliancesDao hDao = new HouseholdAppliancesDao(sf);
        List<HouseholdAppliances> hList = hDao.findAll();
        setList(hList);
        
        return ActionSupport.SUCCESS;
    }

    public List<HouseholdAppliances> getList() {
        return list;
    }
    public void setList(List<HouseholdAppliances> list) {
        this.list = list;
    }

    public void setServletContext(ServletContext context) {
        this.context = context;
    }
}

あとがき

セッションファクトリーが1行(25行目)で取得できました。

セッションファクトリーはDao内で使うので、ソースコードが大きくなる程、簡単に取得できる利便性を感じられると思います。

最後までお読み頂きありがとうございました。

セッションファクトリーの便利な保存方法!

まえがき

SessionFactoryは、O/RマッパでEntityを取得するために必要になります。

(Entity操作を行うDaoは、すべてSessionFactoryをベースとして実装されています。他にEntityManagerを使う方法がありますが、ここではSessionFactoryにフォーカスしてお伝えしたいと思います。)

そのSessionFactoryをサーバ起動時に取得しておこうというのが今回の趣旨となります。

Dao使用時に毎回SessionFactoryを生成してしまうと、Daoを作成した分だけSessionFactory生成処理が必要になってきます。

その分、余分な処理が必要になってくるというわけです。

サーバ起動時に1度、SessionFactoryを生成しておけば、そのSessionFactoryを使い回すことで、余分な処理が必要なくなります!

ServletContextListenerの作成

ServletContextListenerを作成して、サーバ起動時にSessionFactoryをServletContextに保存する処理を追加します。

  • ServletContextListenerをインプリメントしてサーブレットコンテキストを取得しています。
  • hibernate.cfg.xmlから設定内容を読み込んでいます。
  • 設定内容からセッションファクトリーを取得しています。
  • サーブレットコンテキストにセッションファクトリーを保存しています。
package com.pom2019.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

public class HibernateListener implements ServletContextListener {
    private SessionFactory sessionFactory;

    public static final String KEY_NAME = HibernateListener.class.getName();

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        if (sessionFactory != null) {
            sessionFactory.close();
        }
    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        try {
            //configures settings from hibernate.cfg.xml
            Configuration configuration = new Configuration().configure();
            StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
                    .applySettings(configuration.getProperties());
            SessionFactory sessionFactory = configuration.buildSessionFactory(builder.build());

            //save the Hibernate session factory into serlvet context
            arg0.getServletContext().setAttribute(KEY_NAME, sessionFactory);
            
            //ログの出力
            if (sessionFactory != null) {
                System.out.println("セッションファクトリーを取得できました!");
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

※28行目、29行目、30行目でSessionFactoryが取得できた場合は、ログ出力を行っています。

HibernateListenerをリスナー登録

web.xmlでHibernateListenerをリスナー登録して、サーバ起動時にHibernateListenerを呼び出すようにしています。

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="struts_blank" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>Struts Blank Convention</display-name>

    <listener>
        <listener-class>com.pom2019.Struts2Web.InitListener</listener-class>
    </listener>
    
    <listener>
        <listener-class>com.pom2019.listener.HibernateListener</listener-class>
    </listener>
    
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

実行結果

サーバを再起動して、SessionFactoryを取得できているか確認します。

8 10, 2019 5:30:03 午後 org.apache.catalina.startup.Catalina load
情報: Initialization processed in 2959 ms
セッションファクトリーを取得できました!
8 10, 2019 5:30:10 午後 org.apache.catalina.startup.Catalina start
情報: Server startup in 6482 ms

無事、SessionFactoryを取得できていることが確認できました!

あとがき

SessionFactoryをServletContextに保存しておけば、いつでもSevletContextからSessionFactoryを取得することができます。

Dao操作を頻繁に行う、もしくはコードをシンプルにしたいなどといった場合に有効なので、よかったら活用して下さいね。

最後までお読み頂きありがとうございました。

自動生成したEntityをコンソール上に表示してみよう!

まえがき

自動生成したEntityを使って、テーブルの内容をコンソール上に表示するプログラムをご紹介したいと思います。

Hibernateツールをインストールし、Entityを自動生成する方法については下記リンクを参考にして下さいね。

pom2019.hatenablog.com

Hibernate4.3とMySQLを使ってデータを表示する、自動生成したEntityを使用しない方法については下記リンクを参考にして下さいね。

pom2019.hatenablog.com

開発環境

開発環境は下記の通りです。

Hibernate4.3.0.Final
MySQL8.0.16

hibernate.cfg.xmlの変更

hibernate.cfg.xmlに今回使用するEntityをマッピングします。

※20行目と21行目が今回追加したソースコードです。

※パスワードはマスキングしています。

<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>

        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://127.0.0.1:3306/TESTDB?useUnicode=true&amp;characterEncoding=UTF-8</property>
        <property name="connection.username">test</property>
        <property name="connection.password">****</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>

        <!-- Disable the second-level cache -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
        
        <!-- Mapping file inclusion -->
        <mapping class="com.pom2019.entity.HouseholdAppliances"/>

    </session-factory>
</hibernate-configuration>

Entityクラスの変更

toStringメソッドをオーバーライドして、指定した文字列をコンソールに表示させます。

※追加コメントが今回追加したソースコードです。

package com.pom2019.entity;
// Generated 2019/07/13 21:16:35 by Hibernate Tools 4.3.5.Final

import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

/**
 * HouseholdAppliances generated by hbm2java
 */
@Entity
@Table(name = "HouseholdAppliances", catalog = "TESTDB")
public class HouseholdAppliances implements java.io.Serializable {

    private static final long serialVersionUID = 3713670612166968592L;
    private Integer id;
    private String householdAppliancesName;
    private Date purchaseDate;

    public HouseholdAppliances() {
    }

    public HouseholdAppliances(String householdAppliancesName, Date purchaseDate) {
        this.householdAppliancesName = householdAppliancesName;
        this.purchaseDate = purchaseDate;
    }

    @Id
    @GeneratedValue(strategy = IDENTITY)

    @Column(name = "id", unique = true, nullable = false)
    public Integer getId() {
        return this.id;
    }

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

    @Column(name = "HouseholdAppliancesName", length = 100)
    public String getHouseholdAppliancesName() {
        return this.householdAppliancesName;
    }

    public void setHouseholdAppliancesName(String householdAppliancesName) {
        this.householdAppliancesName = householdAppliancesName;
    }

    @Temporal(TemporalType.DATE)
    @Column(name = "PurchaseDate", length = 10)
    public Date getPurchaseDate() {
        return this.purchaseDate;
    }

    public void setPurchaseDate(Date purchaseDate) {
        this.purchaseDate = purchaseDate;
    }

    /**
    * !!!追加!!!
    */
    @Override
    public String toString() {
        return "id:"+id+"\thouseholdAppliancesName:"+householdAppliancesName+"\tpurchaseDate:"+purchaseDate;
    }
}

メインメソッドの変更

最後にメインメソッドを変更して、HQLで取得したEntityをコンソール上に表示します。

package com.pom2019;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

import com.pom2019.entity.HouseholdAppliances;

public class App {

    public static void main(String[] args) {
        // configures settings from hibernate.cfg.xml
        Configuration configuration = new Configuration().configure();
        StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
                .applySettings(configuration.getProperties());
        SessionFactory sf = configuration.buildSessionFactory(builder.build());

        Session ss = sf.openSession();
        @SuppressWarnings("unchecked")
        List<HouseholdAppliances> result = ss.createQuery("FROM HouseholdAppliances").list();
        for (HouseholdAppliances r : result) {
            System.out.println(r);
        }

        if (sf != null) {
            sf.close();
        }
    }
}

出力結果

AppクラスをJavaアプリケーションで実行します。

7 20, 2019 9:18:19 午後 org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
7 20, 2019 9:18:19 午後 org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.0.Final}
7 20, 2019 9:18:19 午後 org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
7 20, 2019 9:18:19 午後 org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
7 20, 2019 9:18:19 午後 org.hibernate.cfg.Configuration configure
INFO: HHH000043: Configuring from resource: /hibernate.cfg.xml
7 20, 2019 9:18:19 午後 org.hibernate.cfg.Configuration getConfigurationInputStream
INFO: HHH000040: Configuration resource: /hibernate.cfg.xml
7 20, 2019 9:18:19 午後 org.hibernate.cfg.Configuration doConfigure
INFO: HHH000041: Configured SessionFactory: null
7 20, 2019 9:18:19 午後 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!)
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
7 20, 2019 9:18:19 午後 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://127.0.0.1:3306/TESTDB?useUnicode=true&characterEncoding=UTF-8]
7 20, 2019 9:18:19 午後 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=test, password=****}
7 20, 2019 9:18:19 午後 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
7 20, 2019 9:18:19 午後 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 1 (min=1)
7 20, 2019 9:18:19 午後 org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
7 20, 2019 9:18:20 午後 org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
7 20, 2019 9:18:20 午後 org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Hibernate: select householda0_.id as id1_0_, householda0_.HouseholdAppliancesName as Househol2_0_, householda0_.PurchaseDate as Purchase3_0_ from TESTDB.HouseholdAppliances householda0_
id:1    householdAppliancesName:冷蔵庫   purchaseDate:2008-12-01
id:2    householdAppliancesName:電子レンジ purchaseDate:2015-08-01
id:3    householdAppliancesName:オーブントースター purchaseDate:2015-08-01
id:4    householdAppliancesName:クーラー    purchaseDate:2011-06-01
id:5    householdAppliancesName:洗濯機   purchaseDate:2012-04-01

あとがき

無事、自動生成したEntityをコンソール上に表示することができました。

自動生成したEntityを使うことで、ソースの見通しが良くなって保守性が上がるし、テーブル名やカラム名を直書きしないといけないSQLよりもクラス名やフィールド名を使ったHQLを使う方がテーブルの内容の変更にも柔軟に対応できて開発しやすいと思います。

O/Rマッパーを初めて使ったときの感動が忘れられない!

最後までお読み頂きありがとうございました。

STSにHibernateツールをインストールし、Entityを自動生成する!(後編)

まえがき

O/RマッパでEntityを作成する場合、手書きで作成するのは、すごく大変です。

Entityファイルに大量にあるカラムの設定をしたり、複数プライマリーキーの設定をしたりなど、手作業でするには、ミスもし易いし、こんなところで時間を使いたくないと思ってしまっても仕方がないです。

今回は、Entityを自動生成する(リバースエンジニアリング)手順について説明したいと思います。

HibernateツールをSTSにインストールする手順は、前編を参考にして下さいね。

pom2019.hatenablog.com

コンソール構成の追加

  • STSを立ち上げ、Hibernateツールパースペクティブを開きます。その後、「新規>Hibernateコンソール構成」をクリックします。下記キャプチャで赤枠内クリックでも追加できます。

f:id:pom2019:20190714132629p:plain

  • 赤枠内を入力もしくはチェックします。
  1. 名前:コンソール構成の名前を入力します。(なんでも構いません。)
  2. 型:注釈(jdk1.5+)をクリックし、Hibernateのバージョンを4.3とします。
  3. プロジェクト:参照ボタンからEntityの自動生成を行うプロジェクトを選択します。
  4. データベース接続:「[Hibernate configured connection]」を選択します。
  5. 構成ファイル:セットアップボタンからhibernate.cfg.xmlファイルを選択します。

f:id:pom2019:20190714132704p:plain

  •  適用後、OKボタンをクリックします。

f:id:pom2019:20190714133326p:plain

  • Hibernate4.3のツリーを辿っていくとDBに接続できたことが分かります。

f:id:pom2019:20190714133351p:plain

リバース・エンジニアリング・ファイルの作成

  • Springパースペクティブを開き、「新規>その他」をクリックします。
  • Hibernate>Hibernateリバース・エンジニアリング・ファイル」を選択し、次へをクリックします。

f:id:pom2019:20190714134131p:plain

  • resourcesフォルダを指定し、hibernate.reveng.xmlとデフォルト表示されるので、次へをクリックします。

f:id:pom2019:20190714134254p:plain

  • コンソール構成に先程のhibernate4.3を選択し、リフレッシュボタンをクリックします。その後、データベース・スキーマから自動生成したいテーブルを選択し、インクルードボタンをクリックします。そうすると、テーブル・フィルターにテーブルが追加されるので、完了をクリックします。f:id:pom2019:20190714134538p:plain
  • リバース・エンジニアリング・ファイルが作成されます。

Entityの自動生成

f:id:pom2019:20190714135211p:plain

  • 赤枠内の新規構成をクリックします。

f:id:pom2019:20190714135619p:plain

  • 赤枠内を入力もしくはチェックします。
  1. ハンドリング名前:構成の名前を入力します。(なんでも構いません。)
  2. コンソール構成:コンソール構成で作成した構成を選択します。(ここではhibernate4.3)
  3. 出力ディレクトリ:参照ボタンからjavaファイルのルートパスを選択します。
  4. JDBC接続からリバース・エンジニアリング:チェックします。
  5. パッケージ:Entityを作成するパッケージを入力します。
  6. reveng.xml:セットアップボタンからhibernate.reveng.xmlファイルを選択します。

f:id:pom2019:20190714135804p:plain

  • エクスポータータブで、赤枠内のチェックをチェックします。その後、適用ボタンをクリックし、実行ボタンをクリックします。

f:id:pom2019:20190714140541p:plain

  •  Entityが自動生成されます。

f:id:pom2019:20190714140802p:plain

あとがき

無事、Entityを自動生成することができました。

テーブルの内容はGUIを使って変更し、Entityへの反映は自動生成で行えば、タイプミスも防げるし、大量に変更を行う場合などにかなり有効になってくると思います。ただ、エラーメッセージの設定を行いたい場合は、Entityファイルを直接変更しないといけないため、自動生成するとすべて消えてしまいます。。

用途によって、自動生成と手動作成を使い分けるのがいいと思います。

最後までお読み頂きありがとうございました。

STSにHibernateツールをインストールし、Entityを自動生成する!(前編)

O/RマッパでEntityを作成する場合、手書きで作成するのは、すごく大変です。

Entityファイルに大量にあるカラムの設定をしたり、複数プライマリーキーの設定をしたりなど、手作業でするには、ミスもし易いし、こんなところで時間を使いたくないと思ってしまいます。

今回は、Entityを自動生成するツールをインストールすることで、この問題を解決したいと思います。

まずは、Entityを自動生成するツールであるHibernateツールをSTSにインストールします。

本ページ引っ越しのご案内

本ページは引っ越しました。

お手数ですが、続きは下記URLまでアクセスください。

iteng-pom.com

 

MySQL Connector/Jの最新版について!

こんにちは、ぽむです。

はじめに

前回のブログでは、pom.xmldependencyに「MySQL Connector/J」8.0.16を設定していました。どうして8.0.16を使っているのかを開発者の観点から説明したいと思います。

MySQL Connector/Jとは、「MySQLJavaを繋ぐドライバ」のことです。(データベースとプログラムを繋ぐ橋渡し役!)

本ページ引っ越しのご案内

本ページは引っ越しました。

お手数ですが、続きは下記URLまでアクセスください。 

iteng-pom.com

Hibernate4.3経由でMySQLのデータを表示する!

まえがき

STS3のMavenプロジェクト使って、Hibernate4.3経由でMySQLのテーブルデータを表示したいと思います。

手順は下記の通りとなります。

  1. Mavenプロジェクトを使ってJavaのコンソールプロジェクトを作成します。
  2. Hibernate4.3とMySQL8.0をpom.xmlに追加します。
  3. データを表示するMainメソッドを作成します。

表示するデータは、前回のブログで作成したテーブルを使用します。

データを作成していない方は下記リンクを参考にして下さいね! pom2019.hatenablog.com

Mavenプロジェクトの作成

必要ファイルの作成

<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/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.pom2019</groupId>
    <artifactId>HibernateTest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Archetype - HibernateTest</name>
    <url>http://maven.apache.org</url>

    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.0.Final</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>
    </dependencies>

</project>
  • resoucesフォルダ配下に「hibernate.cfg.xml」を作成します。 f:id:pom2019:20190622152930p:plain
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>

        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://127.0.0.1:3306/TESTDB?useUnicode=true&amp;characterEncoding=UTF-8</property>
        <property name="connection.username">test</property>
        <property name="connection.password">****</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>

        <!-- Disable the second-level cache -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

    </session-factory>
</hibernate-configuration>

※パスワードは「****」としていますが、それぞれの環境のパスワードを入力して下さい。

  • メイン文を含むクラスを作成します。 f:id:pom2019:20190622153913p:plain
package com.pom2019;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

public class App {

    public static void main(String[] args) {
        // configures settings from hibernate.cfg.xml
        Configuration configuration = new Configuration().configure();
        StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
                .applySettings(configuration.getProperties());
        SessionFactory sf = configuration.buildSessionFactory(builder.build());

        Session ss = sf.openSession();
        @SuppressWarnings("unchecked")
        List<Object[]> result = ss.createSQLQuery("SELECT * FROM HouseholdAppliances").list();
        for (Object[] r : result) {
            for (Object o : r) {
                System.out.print(o + "\t");
            }
            System.out.println();
        }

        if (sf != null) {
            sf.close();
        }
    }
}

実行結果

  • App.javaを右クリックし、「実行>2.Javaアプリケーション」をクリックします。
6 22, 2019 2:59:55 午後 org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
6 22, 2019 2:59:55 午後 org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.0.Final}
6 22, 2019 2:59:55 午後 org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
6 22, 2019 2:59:55 午後 org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
6 22, 2019 2:59:55 午後 org.hibernate.cfg.Configuration configure
INFO: HHH000043: Configuring from resource: /hibernate.cfg.xml
6 22, 2019 2:59:55 午後 org.hibernate.cfg.Configuration getConfigurationInputStream
INFO: HHH000040: Configuration resource: /hibernate.cfg.xml
6 22, 2019 2:59:55 午後 org.hibernate.cfg.Configuration doConfigure
INFO: HHH000041: Configured SessionFactory: null
6 22, 2019 2:59:55 午後 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!)
6 22, 2019 2:59:55 午後 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://127.0.0.1:3306/TESTDB?useUnicode=true&characterEncoding=UTF-8]
6 22, 2019 2:59:55 午後 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=test, password=****}
6 22, 2019 2:59:55 午後 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
6 22, 2019 2:59:55 午後 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 1 (min=1)
6 22, 2019 2:59:56 午後 org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
6 22, 2019 2:59:56 午後 org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
6 22, 2019 2:59:56 午後 org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
6 22, 2019 2:59:56 午後 org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000227: Running hbm2ddl schema export
6 22, 2019 2:59:56 午後 org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000230: Schema export complete
Hibernate: SELECT * FROM HouseholdAppliances
1   冷蔵庫   2008-12-01  
2   電子レンジ 2015-08-01  
3   オーブントースター 2015-08-01  
4   クーラー    2011-06-01  
5   洗濯機   2012-04-01  

あとがき

家電テーブルの内容が無事表示されました!

ここでは、SQLを直接実行する(ss.createSQLQuery)ことでデータを表示させていますが、エンティティを設定をすれば、HQLで実行させる(ss.createQuery)ことができます。

HQLとはHibernate Query Languageの略で、SQLオブジェクト指向風にラッピングした言語のことです。

今回、MySQLのバージョンになぜ8.0.16を使用したかについては、下記リンクに書いているのでよかったら参考にして下さいね! pom2019.hatenablog.com

最後までお読み頂きありがとうございました。