とあるファミリーマートで逆さ福の置物を見つけました。
福が逆さになっているけど、本当に縁起がいいの?
そんな疑問を解決します。
WordPressのブログを更新しました。
よろしければご覧ください。
こんにちは、ぽむです。
今回は、Ubuntuのローカル環境でGitサーバーを構築する手順をご紹介したいと思います。
Ubuntuのローカル環境でGitサーバーを構築する利点を上げるとすると主に下記3点が思い浮かびます。
ローカル環境でGitを管理するためカスタマイズし易い。
複数人でGitを共有する場合でも人数制限がない。
Gitサーバーを構築することでサーバー構築の勉強になる。
Gitは代表的なバージョン管理ツールです。バージョン管理ツールとはソースの変更履歴を管理するためのツールのことです。
バージョン管理ツールは、SVNやGitなどが有名です。
本ページは引っ越しました。
お手数ですが、続きは下記URLまでアクセスください。
こんにちは、ぽむです。
今回は、Spring5とHibernate5.2を使ってMySQL内のテーブルデータを一覧表示させるプログラムをご紹介したいと思います。
開発環境は下記の通りです。
Spring | 5.2.1.RELEASE |
Hibernate | 5.2.10.Final |
MySQL | 8.0.16 |
前回ご紹介させていただいたブログでSessionFactoryをBeanとして登録する方法を書かせていただいたのですが、今回はこのSessionFactoryを使って、MySQL内のテーブルからデータを取ってきてそのデータを画面上に表示させるプログラムをご紹介したいと思います。
前回ご紹介させていただいたブログについては下記リンクをご参照下さい。
今回のポイントは、MySQL内のテーブルからデータを取ってくる処理をサービスとしてまとめることです。このサービスをアクションメソッドから呼び出せばアクションメソッドをきれいに書くことができます。
Springフレームワークには、DIコンテナに登録するBeanとして、「@Component、@Controller、@Service、@Repository」などがありますが、DAOといったデータ操作に関するBeanはサービスとして登録する決まりがあります。
それぞれの違いは下記URLに詳しく載っているので、よかったら参考にして下さい。KevinFQさんありがとうございます。
package com.pom2019.service; import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.ComponentScan; import org.springframework.stereotype.Service; import com.pom2019.entity.HouseholdAppliances; @Service @ComponentScan("com.pom2019.config") public class HouseholdAppliancesDao { @Autowired private SessionFactory sf; public HouseholdAppliancesDao() { super(); } @SuppressWarnings("unchecked") public List<HouseholdAppliances> findAll() { Session ss = sf.openSession(); return ss.createQuery("from HouseholdAppliances").list(); } }
package com.pom2019.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.ComponentScan; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.pom2019.entity.HouseholdAppliances; import com.pom2019.service.HouseholdAppliancesDao; @Controller @ComponentScan("com.pom2019.service") public class IndexController { @Autowired private HouseholdAppliancesDao service; @RequestMapping(value="/getList", method = RequestMethod.GET) public String execute(Model model) { List<HouseholdAppliances> list = service.findAll(); model.addAttribute("list", list); return "displayList"; } }
<%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <html> <head> <title>家電リスト</title> <style> table { border-collapse: collapse; } td { border: 1px solid gray; padding: 3px 8px; } </style> </head> <body> <h2>家電リスト</h2> <p> <button id="btnNew">新規</button> </p> <table> <tr> <td>id</td> <td>家電名</td> <td>購入日時</td> <td colspan="2">アクション</td> </tr> <c:forEach var="data" items="${list}"> <tr> <td class="id"><c:out value="${data.id}"/></td> <td><c:out value="${data.householdAppliancesName}"/></td> <td><fmt:formatDate value="${data.purchaseDate}" type="DATE" pattern="yyyy/MM/dd"/></td> <td><button class="btnEdit">編集</button></td> <td><button class="btnDelete">削除</button></td> </tr> </c:forEach> </table> </body> </html>
mvc-config.xml内でコントローラクラスをコンポネートスキャンするように設定後、実行します。
(注意)新規/編集/削除ボタンは今回使用しておりません。
MySQL内のテーブルデータを無事表示することができました。
Springフレームワークを使ってそれぞれのクラスをBeanとして部品化すれば、ベタ書きのJavaで書いていたような(フレームワークを使わないJDBCを使ったJavaのような)長い処理は書かなくていいし、全体の見通しも良くなると思います。
今回のプログラムが参考になりましたら、皆様もぜひ活用して下さいね!
最後までお読み頂きありがとうございました。
こんにちは、ぽむです。
年末年始は時間の空いてるときに、過去のブログを更新していました。誤字脱字、言葉の表現がおかしいところなどをまとめて修正しました。日本語ってホント難しいです。。
令和2年ものろのろしたペースでブログを更新していきたいと思っています。本年もよろしくお願い申し上げます。
今回は、Spring5フレームワークとO/RマッパであるHibernate5.2を使ってSessionFactoryをBeanとして取得する方法をご紹介したいと思います。
SessionFactoryは、データベースのデータを操作する際にWebアプリケーションとデータベースの橋渡し役として必要になります。
SessionFactory is an interface. SessionFactory can be created by providing Configuration object, which will contain all DB related property details pulled from either hibernate.cfg.xml file or hibernate.properties file. SessionFactory is a factory for Session objects.
We can create one SessionFactory implementation per database in any application. If your application is referring to multiple databases, then you need to create one SessionFactory per database.
※下記リンクを引用させて頂きました。ありがとうございます。
What is SessionFactory in Hibernate? - Hibernate Tutorials
データの操作とは、主にデータベースのデータを取得・保存・更新・削除することです。データを操作するプログラムを集めたものをDAO(Data Access Objectsの略)といいます。
引用元にある通り(英語の引用元でごめんなさい。。僕は簡単な英語、見たことのある専門用語なら分かります!)、SessionFactoryを取得するにはhibernate.cfg.xmlファイルもしくはhibernate.propertiesファイルに関連付けられたデータベースから取得できます。
今回は、hibernate.cfg.xmlファイルからSessionFactoryを取得する方法をご紹介したいと思います。
開発環境は下記の通りです。
Spring | 5.2.1.RELEASE |
Hibernate | 5.2.10.Final |
MySQL | 8.0.16 |
hibernate.cfg.xmlファイル内で下記の設定を行っています。
リソースフォルダに配置すれば、自動的に認識してくれます。
<!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.cj.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://127.0.0.1:3306/TESTDB?useUnicode=true&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>
※パスワードはマスキングしています。
詳細は下記の通りとなっています。
Configurationアノテーション→設定ファイルとしてSpringが認識してくれます。ここでは絶対パスとなっていますが、これはHibernateのConfigurationクラスとクラス名が被っているからです。
Beanアノテーション→BeanクラスとしてSpringが認識してくれます。
SessionFactoryの取得→hibernate.cfg.xmlファイルから設定を読み込みSessionFactoryを取得しています。SessionFactoryが取得できたら、取得できたことをコンソールに出力しています。
package com.pom2019.config; import org.hibernate.SessionFactory; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.springframework.context.annotation.Bean; @org.springframework.context.annotation.Configuration public class HibernateConfig { @Bean public SessionFactory sessionFactory() { SessionFactory sessionFactory = null; try { //registryの作成 StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build(); //MetadataSourcesの作成 MetadataSources sources = new MetadataSources(registry); //Metadataの作成 Metadata metadata = sources.getMetadataBuilder().build(); //SessionFactoryの作成 sessionFactory = metadata.getSessionFactoryBuilder().build(); //ログの出力 if (sessionFactory != null) { System.out.println("セッションファクトリーを取得できました!"); } } catch (Exception e) { System.out.println(e.getMessage()); } return sessionFactory; } }
HibernateConfigファイルをComponentScanの対象にして、サーバーを起動します。
1 04, 2020 2:49:53 午後 org.apache.catalina.startup.Catalina load
情報: Initialization processed in 2646 ms
INFO ContextLoader - Root WebApplicationContext: initialization started
INFO ContextLoader - Root WebApplicationContext initialized in 419 ms
INFO DispatcherServlet - Initializing Servlet 'dispatcherServlet'
INFO Version - HHH000412: Hibernate Core {5.2.10.Final}
INFO Environment - HHH000206: hibernate.properties not found
INFO Version - HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
WARN pooling - HHH10001002: Using Hibernate built-in connection pool (not for production use!)
INFO pooling - HHH10001005: using driver [com.mysql.cj.jdbc.Driver] at URL [jdbc:mysql://127.0.0.1:3306/TESTDB?useUnicode=true&characterEncoding=UTF-8]
INFO pooling - HHH10001001: Connection properties: {user=test, password=****}
INFO pooling - HHH10001003: Autocommit mode: false
INFO DriverManagerConnectionProviderImpl - HHH000115: Hibernate connection pool size: 1 (min=1)
INFO Dialect - HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
セッションファクトリーを取得できました!
INFO DispatcherServlet - Completed initialization in 4332 ms
1 04, 2020 2:50:01 午後 org.apache.catalina.startup.Catalina start
情報: Server startup in 7681 ms
SessionFactoryが無事取得できました。
SessionFactoryがBeanとして取得できたので、SessionFactoryを使いたいときにこのBeanを注入(Autowired)してあげれば、いつでもSessionFactoryを使うことができます。
最後までお読み頂きありがとうございました。
こんにちは、ぽむです。
今回はこれまでご紹介したデータベースのインストールからStruts2での簡単なWebアプリケーション作成までを、一覧できるようにまとめてご紹介したいと思います。
Struts2は、「アパッチストラッツプロジェクトがオープンソースとして開発したJavaのWebアプリケーションフレームワーク」です。
以前に一世を風靡したStrutsは、同じプロジェクトが開発したフレームワークですが、Struts2とは構造が全く別物のようです。 現在はStrutsの更新(セキュリティパッチ)は行われておらず、WebサイトでStrutsをダウンロードすることができますが、今も更新が行われているStrus2をダウンロードするように推奨されています。
Struts2は、アノテーションによる設定ファイルの削減、POJOによるアクションファイルの作成、OGNL (Object-Graph Navigation Language) と呼ばれる式言語による動的パラメータの作成などができるようになっています。
詳しくは下記サイトをご参照下さい。
統合開発環境のインストールと日本語化、ブランクプロジェクトの作成については、下記リンクを参考にして下さい。
MySQLのインストール、MySQLワークベンチのインストール、テーブルの作成などデータベースに関する内容については、下記リンクを参考にして下さい。
O/Rマッパの使用方法、Entityの自動生成、自動生成したEntityの表示方法などO/Rマッパに関する内容については、下記リンクを参考にして下さい。
DBとWebアプリケーションを紐付けるセッションファクトリーに関する内容については、下記リンクを参考にして下さい。
CRUD操作を行う簡単なWebアプリケーションについては、下記リンクを参考にして下さい。 CRUD操作とは、データベースの基本操作であるCreate(新規に作成する)、Read(データを選択する)、Update(更新する)、Delete(削除する)を行う処理のことを言います。
データベースのインストールから簡単なWebアプリケーションの作成までをご紹介してきましたが、いかがでしたでしょうか?
Struts2フレームワークを使えば、フレームワークを使わないサーブレットでWeb.xmlにすべて設定内容を書いていたのようなめんどくさいことはしなくていいし、アクションファイルもPOJOで書けるのでソース管理もし易いし、開発者にとって優しい感じがします。
皆様にもぜひStruts2の便利さ、使い易さを体感して頂きたいです。
最後までお読み頂きありがとうございました。
こんにちは、ぽむです。
デュアルブートのUbuntuがある日突然起動しなくなりました。
簡単な設定変更で問題解決することができたので、今回はその解決方法をお伝えしようと思います。
その時はある日突然起こりました。。
いつものようにパソコンを立ち上げるとパソコンが起動しない。。
何度かパソコンを立ち上げてみるもブラックスクリーンのままです。。
BIOSさえ立ち上がらないので泣きそうになりましたね。。
電源長押しで再度立ち上げてを繰り返すこと数回、やっとWindowsが立ち上がりました。
(立ち上がった原因は不明。。)
本ページは引っ越しました。
お手数ですが、続きは下記URLまでアクセスください。
前回まで取り上げていたStruts2でも同じことができるのですが、今回は今一番ホットなSpringで、jsonを返すREST APIを作成したいと思います。
また、REST APIには、jsonを返すパターンとxmlを返すパターンがあるのですが、それぞれ得意不得意な表現があり、どちらを使えばいいか一概に言えませんが、今回はjsonを返すプログラムで作成していきます。
jsonは、「JavaScript Object Notaion」の略でどのようなデータを持つかを示すデータ定義言語です。
本ページは引っ越しました。
お手数ですが、続きは下記URLまでアクセスください。
こんにちは、ぽむです。
今回は、Struts2フレームワークを使ってO/Rマッパ経由で家電情報を削除するプログラムをご紹介したいと思います。
前回までで、O/Rマッパを使った新規保存と編集を見てきました。
今回は、O/Rマッパを使った削除をお伝えしたいと思います。
前回までの表示(SELECT文)と新規保存(INSERT文)と編集(UPDATE文)、今回お伝えする削除(DELETE文)を合わせると、テーブルの4つの基本操作をO/Rマッパですべてご紹介できたことになります。
開発環境は下記の通りです。
Struts2 | 2.5.14.1 |
Hibernate | 4.3.0.Final |
MySQL | 8.0.16 |
javascript 削除ボタンをクリックした場合の処理を追加しました。
<%@ 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 class="id"><s:property value="id"/></td> <td><s:property value="householdAppliancesName"/></td> <td><s:date name="purchaseDate" format="yyyy/MM/dd"/></td> <td><button class="btnEdit">編集</button></td> <td><button class="btnDelete">削除</button></td> </tr> </s:iterator> </table> <script> $(function() { //新規ボタン $('#btnNew').on('click', function() { //クエリ文字列で新規登録フラグを立てます location.href = "${pageContext.request.contextPath}/dispModify?isNew=true"; }); //編集ボタン $('.btnEdit').on('click', function() { var id = $(this).parents("tr").find(".id").html(); //クエリ文字列でidを渡します location.href = "${pageContext.request.contextPath}/dispModify?id=" + id; }); //削除ボタン $('.btnDelete').on('click', function() { //削除する行のidを取得 var id = $(this).parents("tr").find(".id").html(); //フォームデータの取得 var fd = new FormData(); //フォームデータの追加 fd.append("id", id); //urlの設定 var url = "${pageContext.request.contextPath}/delete"; //AJAX通信 $.ajax({ url: url, type: 'POST', data: fd, processData: false, contentType: false }) //Ajaxリクエストが成功した時発動 .done( (data) => { //一覧画面を再表示する location.href = "${pageContext.request.contextPath}/display"; }) //Ajaxリクエストが失敗した時発動 .fail( (data) => { }) //Ajaxリクエストが成功・失敗どちらでも発動 .always( (data) => { }); }); }); </script> </body> </html>
編集時に既にidを追加していたため、今回は変更していません。
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; //登録用 private String id; private String householdAppliancesName; private String purchaseDate; //ゲッター、セッター 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; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getHouseholdAppliancesName() { return householdAppliancesName; } public void setHouseholdAppliancesName(String householdAppliancesName) { this.householdAppliancesName = householdAppliancesName; } public String getPurchaseDate() { return purchaseDate; } public void setPurchaseDate(String purchaseDate) { this.purchaseDate = purchaseDate; } }
今回使用するメソッドは、下記の通りになります。
findById idから検索して削除する家電データ(オブジェクト)を取得します。
delete 引数に与えられた家電データ(オブジェクト)を実際に削除します。
package com.pom2019.Struts2Web.entities.dao; import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; 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(); } @SuppressWarnings("unchecked") public List<HouseholdAppliances> findById(String id) { Session ss = sf.openSession(); return ss.createQuery("from HouseholdAppliances " + "where id = " + id).list(); } public boolean save(HouseholdAppliances h) { Session ss = sf.openSession(); Transaction trans = null; try { trans = ss.beginTransaction(); ss.save(h); trans.commit(); } catch (Exception e) { trans.rollback(); return false; } finally { ss.close(); } return true; } public boolean update(HouseholdAppliances h) { Session ss = sf.openSession(); Transaction trans = null; try { trans = ss.beginTransaction(); ss.update(h); trans.commit(); } catch (Exception e) { trans.rollback(); return false; } finally { ss.close(); } return true; } public boolean delete(HouseholdAppliances h) { Session ss = sf.openSession(); Transaction trans = null; try { trans = ss.beginTransaction(); ss.delete(h); trans.commit(); } catch (Exception e) { trans.rollback(); return false; } finally { ss.close(); } return true; } }
今回追加したアクションは、下記の通りになります。
delete idから家電データ(オブジェクト)を取得して、削除処理を実行しています。
package com.pom2019.Struts2Web.actions; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.pom2019.Struts2Web.entities.HouseholdAppliances; import com.pom2019.Struts2Web.entities.dao.HouseholdAppliancesDao; import com.pom2019.Struts2Web.model.IndexModel; import com.pom2019.listener.HibernateListener; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; 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.convention.annotation.Result; import org.apache.struts2.util.ServletContextAware; import org.hibernate.SessionFactory; @Namespace("/") @ParentPackage("struts-default") @Action(value = "delete", results = { @Result(name = "success", location = "/WEB-INF/content/displayList.jsp") }) public String delete() { //パラメータの取得 String id = indexModel.getId(); //削除用インスタンスの取得 SessionFactory sf = (SessionFactory) context.getAttribute(HibernateListener.KEY_NAME); HouseholdAppliancesDao hDao = new HouseholdAppliancesDao(sf); HouseholdAppliances h = hDao.findById(id).get(0); //削除処理 hDao.delete(h); //エラー回避用に空変数をセット indexModel.setList(new ArrayList<HouseholdAppliances>()); return ActionSupport.SUCCESS; } public class Index extends ActionSupport implements ServletContextAware, ModelDriven<IndexModel> { private static final long serialVersionUID = -1884587001523422505L; ServletContext context; private IndexModel indexModel = new IndexModel(); @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(); indexModel.setList(hList); return ActionSupport.SUCCESS; } @Action(value = "dispModify", results = { @Result(name = "success", location = "/WEB-INF/content/displayModify.jsp") }) public String dispModify() { String id = indexModel.getId(); //idがパラメータとして存在した場合(編集の場合) if (id != null && !"".equals(id)) { SessionFactory sf = (SessionFactory) context.getAttribute(HibernateListener.KEY_NAME); HouseholdAppliancesDao hDao = new HouseholdAppliancesDao(sf); List<HouseholdAppliances> hList = hDao.findById(id); if (hList.size() > 0) { //編集する家電情報を取得する HouseholdAppliances h = hList.get(0); indexModel.setHouseholdAppliancesName(h.getHouseholdAppliancesName()); indexModel.setPurchaseDate(new SimpleDateFormat("yyyy/MM/dd").format(h.getPurchaseDate())); } } return ActionSupport.SUCCESS; } @Action(value = "save", results = { @Result(name = "success", location = "/WEB-INF/content/displayModify.jsp") }) public String save() { //パラメータの取得 String householdAppliancesName = indexModel.getHouseholdAppliancesName(); String purchaseDate = indexModel.getPurchaseDate(); //保存用インスタンスの生成 HouseholdAppliances h = new HouseholdAppliances(); //家電名の設定 h.setHouseholdAppliancesName(householdAppliancesName); //購入日時の設定 Date d = new Date(); try { d = new SimpleDateFormat("yyyy/MM/dd").parse(purchaseDate); } catch(ParseException e) {} h.setPurchaseDate(d); //保存処理 SessionFactory sf = (SessionFactory) context.getAttribute(HibernateListener.KEY_NAME); HouseholdAppliancesDao hDao = new HouseholdAppliancesDao(sf); hDao.save(h); return ActionSupport.SUCCESS; } @Action(value = "update", results = { @Result(name = "success", location = "/WEB-INF/content/displayModify.jsp") }) public String update() { //パラメータの取得 String id = indexModel.getId(); String householdAppliancesName = indexModel.getHouseholdAppliancesName(); String purchaseDate = indexModel.getPurchaseDate(); //編集用インスタンスの取得 SessionFactory sf = (SessionFactory) context.getAttribute(HibernateListener.KEY_NAME); HouseholdAppliancesDao hDao = new HouseholdAppliancesDao(sf); HouseholdAppliances h = hDao.findById(id).get(0); //家電名の設定 h.setHouseholdAppliancesName(householdAppliancesName); //購入日時の設定 Date d = new Date(); try { d = new SimpleDateFormat("yyyy/MM/dd").parse(purchaseDate); } catch(ParseException e) {} h.setPurchaseDate(d); //更新処理 hDao.update(h); return ActionSupport.SUCCESS; } @Action(value = "delete", results = { @Result(name = "success", location = "/WEB-INF/content/displayList.jsp") }) public String delete() { //パラメータの取得 String id = indexModel.getId(); //削除用インスタンスの取得 SessionFactory sf = (SessionFactory) context.getAttribute(HibernateListener.KEY_NAME); HouseholdAppliancesDao hDao = new HouseholdAppliancesDao(sf); HouseholdAppliances h = hDao.findById(id).get(0); //削除処理 hDao.delete(h); //エラー回避用に空変数をセット indexModel.setList(new ArrayList<HouseholdAppliances>()); return ActionSupport.SUCCESS; } public void setServletContext(ServletContext context) { this.context = context; } @Override public IndexModel getModel() { return indexModel; } }
idが6のデータを削除します。
idが6のデータが削除されました。
4つの基本操作を知っていれば、ちょっとしたシステムを構築できるようになります。
ここをスタート地点として、複数プライマリキーのテーブルを扱ったり、テーブル数を増やしていけば、扱える処理も増えていくことになります。
最後までお読み頂きありがとうございました。
こんにちは、ぽむです。
今回は、Struts2フレームワークを使ってO/Rマッパ経由で家電情報テーブルを編集するプログラムをご紹介したいと思います。
前回までで、家電情報テーブルにデータを新規保存する方法を見てきました。
今回は、Struts2を使って元あるテーブルのデータを編集する方法について見ていきたいと思います。
開発環境は下記の通りです。
Struts2 | 2.5.14.1 |
Hibernate | 4.3.0.Final |
MySQL | 8.0.16 |
画面 編集モードの場合、編集するidが表示されます。
Javascript 編集モードの場合、フォームデータにidをセットして、更新用のアクションを呼び出しています。
※編集モードは、パラメータisNewにtrueがセットされているかどうかで判断しています。
<%@ 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:property value='purchaseDate'/>" readonly="readonly"/></td> </tr> </table> <%-- 隠しパラメータ --%> <input id="isNew" type="hidden" value="<s:property value='isNew'/>"> <script> $(function() { //日付ピッカーの設定 $('#purchaseDate').datepicker({ dateFormat: 'yy/mm/dd', changeYear: true, changeMonth: true }); //戻るボタン $('#btnBack').on('click', function() { history.back(); }); //保存ボタン $('#btnSave').on('click', function() { //フォームデータの取得 var fd = new FormData(); var url; var isNew = $('#isNew').val(); if (isNew && isNew == "true") { //保存の場合 url = '${pageContext.request.contextPath}/save'; } else { //編集の場合 fd.append("id", $('#id').html()); url = '${pageContext.request.contextPath}/update'; } //フォームデータの追加 fd.append("householdAppliancesName", $('#householdAppliancesName').val()); fd.append("purchaseDate", $('#purchaseDate').val()); //AJAX通信 $.ajax({ url: url, type: 'POST', data: fd, processData: false, contentType: false }) //Ajaxリクエストが成功した時発動 .done( (data) => { location.href = "${pageContext.request.contextPath}/display"; }) //Ajaxリクエストが失敗した時発動 .fail( (data) => { }) //Ajaxリクエストが成功・失敗どちらでも発動 .always( (data) => { }); }); }); </script> </body> </html>
編集するためにidを連携しないといけないため、モデルにidを追加しています。
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; //登録用 private String id; private String householdAppliancesName; private String purchaseDate; //ゲッター、セッター 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; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getHouseholdAppliancesName() { return householdAppliancesName; } public void setHouseholdAppliancesName(String householdAppliancesName) { this.householdAppliancesName = householdAppliancesName; } public String getPurchaseDate() { return purchaseDate; } public void setPurchaseDate(String purchaseDate) { this.purchaseDate = purchaseDate; } }
今回追加したメソッドは、下記の通りになります。
findById idから家電データを検索します。 編集するデータを特定するために使っています。
update 家電データを更新します。
package com.pom2019.Struts2Web.entities.dao; import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; 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(); } @SuppressWarnings("unchecked") public List<HouseholdAppliances> findById(String id) { Session ss = sf.openSession(); return ss.createQuery("from HouseholdAppliances " + "where id = " + id).list(); } public boolean save(HouseholdAppliances h) { Session ss = sf.openSession(); Transaction trans = null; try { trans = ss.beginTransaction(); ss.save(h); trans.commit(); } catch (Exception e) { trans.rollback(); return false; } finally { ss.close(); } return true; } public boolean update(HouseholdAppliances h) { Session ss = sf.openSession(); Transaction trans = null; try { trans = ss.beginTransaction(); ss.update(h); trans.commit(); } catch (Exception e) { trans.rollback(); return false; } finally { ss.close(); } return true; } }
今回編集もしくは追加したアクションは、下記の通りになります。
dispModify idから家電データを検索し、検索されたデータをモデルにセットしています。
update モデルから家電データを取得し、テーブルを更新しています。
@Action(value = "dispModify", results = { @Result(name = "success", location = "/WEB-INF/content/displayModify.jsp") }) public String dispModify() { String id = indexModel.getId(); //idがパラメータとして存在した場合(編集の場合) if (id != null && !"".equals(id)) { SessionFactory sf = (SessionFactory) context.getAttribute(HibernateListener.KEY_NAME); HouseholdAppliancesDao hDao = new HouseholdAppliancesDao(sf); List<HouseholdAppliances> hList = hDao.findById(id); if (hList.size() > 0) { //編集する家電情報を取得する HouseholdAppliances h = hList.get(0); indexModel.setHouseholdAppliancesName(h.getHouseholdAppliancesName()); indexModel.setPurchaseDate(new SimpleDateFormat("yyyy/MM/dd").format(h.getPurchaseDate())); } } return ActionSupport.SUCCESS; } @Action(value = "update", results = { @Result(name = "success", location = "/WEB-INF/content/displayModify.jsp") }) public String update() { //パラメータの取得 String id = indexModel.getId(); String householdAppliancesName = indexModel.getHouseholdAppliancesName(); String purchaseDate = indexModel.getPurchaseDate(); //編集用インスタンスの取得 SessionFactory sf = (SessionFactory) context.getAttribute(HibernateListener.KEY_NAME); HouseholdAppliancesDao hDao = new HouseholdAppliancesDao(sf); HouseholdAppliances h = hDao.findById(id).get(0); //家電名の設定 h.setHouseholdAppliancesName(householdAppliancesName); //購入日時の設定 Date d = new Date(); try { d = new SimpleDateFormat("yyyy/MM/dd").parse(purchaseDate); } catch(ParseException e) {} h.setPurchaseDate(d); //更新処理 hDao.update(h); return ActionSupport.SUCCESS; }
idが6のデータを編集します。
編集画面に遷移しました。
データを編集後、保存ボタンをクリックします。
データが編集されました。
新規保存の際と変わったことは、DAOで「ss.save(h);」を呼ぶのではなく、「ss.update(h);」を呼んでいる点です。
「ss.update(h);」にセットしているエンティティhは、もちろん存在するエンティティを指定しないとエラーとなってしまいます。
存在するエンティティを取得するために、findByIdメソッドを使っていたのです。
逆に「ss.save(h);」にセットしているエンティティhは、家電情報テーブルに存在しない新規インスタンスをセットしなければエラーとなってしまいます。
最後までお読み頂きありがとうございました。