Upload
misaki-kajiura
View
632
Download
0
Embed Size (px)
Citation preview
2015/08/29 Java女子部
Copyright (C) 2015 Misaki Kajiura All Rights Reserved. 1
『女子部も実践!Java EEハンズオン』メモ帳アプリケーション ソースコード(応用編)
梶浦美咲[@Kaji_ichigo](日本オラクル)
[Contents]
--JPA--
①エンティティ(memo-app/src/java/memo/entity/Memo.java)
--EJB--
②セッション Bean(memo-app/src/java/memo/service/MemoService.java)
--JSF & CDI--
③マネージド Bean(memo-app/src/java/memo/bean/MemoBean.java)
--JSF--
④トップページ(memo-app/web/index.xhtml)
⑤メモ編集ページ(memo-app/web/edit.xhtml)
--デザイン(CSS)--
[参考]memo-app/web/resources/css/style.css
2015/08/29 Java女子部
Copyright (C) 2015 Misaki Kajiura All Rights Reserved. 2
①エンティティ(memo-app/src/java/memo/entity/Memo.java)
package memo.entity;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
@Entity
@Table(name = "MEMO")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Memo.findAll", query = "SELECT m FROM Memo m order by m.createTime desc"), // 修正
@NamedQuery(name = "Memo.findById", query = "SELECT m FROM Memo m WHERE m.id = :id"),
@NamedQuery(name = "Memo.findByTitle", query = "SELECT m FROM Memo m WHERE m.title = :title"),
@NamedQuery(name = "Memo.findBySearchWord", query = "SELECT m FROM Memo m WHERE m.content like :word order by
m.createTime desc"), // 修正
@NamedQuery(name = "Memo.findByCreateTime", query = "SELECT m FROM Memo m WHERE m.createTime = :createTime")})
public class Memo implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "ID")
private Integer id;
@Basic(optional = false)
@NotNull
2015/08/29 Java女子部
Copyright (C) 2015 Misaki Kajiura All Rights Reserved. 3
@Size(min = 1, max = 100, message = "タイトルを 1~100文字で入力してください。") // 修正
@Column(name = "TITLE")
private String title;
@Lob
@Size(max = 32700)
@Column(name = "CONTENT")
private String content;
@Basic(optional = false)
@NotNull
@Column(name = "CREATE_TIME")
@Temporal(TemporalType.TIMESTAMP)
private Date createTime;
public Memo() {
}
public Memo(Integer id) {
this.id = id;
}
public Memo(Integer id, String title, Date createTime) {
this.id = id;
this.title = title;
this.createTime = createTime;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
2015/08/29 Java女子部
Copyright (C) 2015 Misaki Kajiura All Rights Reserved. 4
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Memo)) {
return false;
}
Memo other = (Memo) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
2015/08/29 Java女子部
Copyright (C) 2015 Misaki Kajiura All Rights Reserved. 5
return "memo.model.Memo[ id=" + id + " ]";
}
}
2015/08/29 Java女子部
Copyright (C) 2015 Misaki Kajiura All Rights Reserved. 6
②セッション Bean(memo-app/src/java/memo/service/MemoService.java)
package memo.service;
import java.util.Date;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import memo.entity.Memo;
@Stateless
public class MemoService {
@PersistenceContext // エンティティマネージャをインジェクト
private EntityManager em;
/**
* メモを全件取得
* @return 全件メモリスト
*/
public List<Memo> findAll() {
TypedQuery<Memo> tq = em.createNamedQuery("Memo.findAll", Memo.class);
return tq.getResultList();
}
/**
* 検索語の含まれているメモを全件取得
* @param searchWord 検索語
* @return 検索結果メモリスト
*/
public List<Memo> search(String searchWord) {
TypedQuery<Memo> tq = em.createNamedQuery("Memo.findBySearchWord", Memo.class);
tq.setParameter("word", "%" + searchWord + "%");
return tq.getResultList();
}
/**
2015/08/29 Java女子部
Copyright (C) 2015 Misaki Kajiura All Rights Reserved. 7
* メモを新規作成
* @param memo 登録メモ
*/
public void create(Memo memo) {
memo.setCreateTime(new Date());
em.persist(memo);
}
/**
* 既存メモを更新
* @param memo 更新メモ
*/
public void update(Memo memo) {
memo.setCreateTime(new Date());
em.merge(memo);
}
/**
* 既存メモを削除
* @param memo 削除メモ
*/
public void delete(Memo memo) {
// [注]mergeメソッドで一度対象メモエンティティを管理状態にする必要がある
em.remove(em.merge(memo));
}
}
2015/08/29 Java女子部
Copyright (C) 2015 Misaki Kajiura All Rights Reserved. 8
③マネージド Bean(memo-app/src/java/memo/bean/MemoBean.java)
package memo.bean;
import java.util.List;
import javax.ejb.EJB;
import memo.entity.Memo;
import memo.service.MemoService;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
@Named(value = "memoBean") // ページからアクセスできるようクラスに名前を付ける
@SessionScoped
public class MemoBean implements Serializable {
@EJB // セッション Beanをインジェクト
private MemoService memoService;
private List<Memo> memoList;
private Memo memo;
private String searchWord;
public MemoBean() {
}
/**
* メモリストを生成する ☆ページレンダリング直前にコールされる
*/
public void list() {
if (searchWord == null || searchWord.length() == 0) {
memoList = memoService.findAll();
} else {
memoList = memoService.search(searchWord);
}
}
/**
2015/08/29 Java女子部
Copyright (C) 2015 Misaki Kajiura All Rights Reserved. 9
* メモ新規作成モードでメモ編集ページへ遷移する
* @return 遷移ページ名
*/
public String create() {
memo = new Memo();
return "edit?faces-redirect=true";
}
/**
* メモ更新モードでメモ編集ページへ遷移する
* @param memo 更新対象メモ
* @return 遷移ページ名
*/
public String edit(Memo memo) {
this.memo = memo;
return "edit?faces-redirect=true";
}
/**
* メモを新規登録
* @return 遷移ページ名
*/
public String register() {
memoService.create(memo);
return "index?faces-redirect=true";
}
/**
* メモを更新
* @return 遷移ページ名
*/
public String update() {
memoService.update(memo);
return "index?faces-redirect=true";
}
2015/08/29 Java女子部
Copyright (C) 2015 Misaki Kajiura All Rights Reserved. 10
/**
* メモを削除
* @return 遷移ページ名
*/
public String delete() {
memoService.delete(memo);
return "index?faces-redirect=true";
}
/*
* ***********************************************************
*** 以下自動生成したゲッター・セッター ***************
* ***********************************************************
*/
/**
* @return the searchWord
*/
public String getSearchWord() {
return searchWord;
}
/**
* @param searchWord the searchWord to set
*/
public void setSearchWord(String searchWord) {
this.searchWord = searchWord;
}
/**
* @return the memo
*/
public Memo getMemo() {
return memo;
}
/**
* @param memo the memo to set
*/
public void setMemo(Memo memo) {
2015/08/29 Java女子部
Copyright (C) 2015 Misaki Kajiura All Rights Reserved. 11
this.memo = memo;
}
/**
* @return the memoList
*/
public List<Memo> getMemoList() {
return memoList;
}
}
2015/08/29 Java女子部
Copyright (C) 2015 Misaki Kajiura All Rights Reserved. 12
④トップページ(memo-app/web/index.xhtml)
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>メモ一覧</title>
<!--CSSの適用-->
<h:outputStylesheet name="style.css" library="css"/>
</h:head>
<h:body>
<h:form>
<!--ページレンダリング直前にコールするメソッドを指定-->
<f:event type="preRenderView" listener="#{memoBean.list()}"/>
<h:commandButton value="新規作成" action="#{memoBean.create()}" styleClass="button"/>
<h2>メモ一覧</h2>
<!--メモ検索機能-->
<h:outputLabel value="メモ検索" for="search"/>
<h:inputText value="#{memoBean.searchWord}" id="search"/>
<h:commandButton value="検索" styleClass="button"/>
<!--メモ一覧表示機能-->
<h:dataTable value="#{memoBean.memoList}" var="memo" cellspacing="0" border="1" rules="all"
headerClass="h1" columnClasses="c1, c2" rowClasses="r1">
<h:column>
<f:facet name="header">
<h:outputText value="タイトル"/>
</f:facet>
<h:commandLink value="#{memo.title}" action="#{memoBean.edit(memo)}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="作成・更新日"/>
</f:facet>
<h:outputText value="#{memo.createTime}">
<f:convertDateTime pattern="yyyy/MM/dd HH:mm:ss" timeZone="Japan"/>
</h:outputText>
</h:column>
</h:dataTable>
</h:form>
2015/08/29 Java女子部
Copyright (C) 2015 Misaki Kajiura All Rights Reserved. 13
</h:body>
</html>
2015/08/29 Java女子部
Copyright (C) 2015 Misaki Kajiura All Rights Reserved. 14
⑤メモ編集ページ(memo-app/web/edit.xhtml)
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>メモ編集</title>
<h:outputStylesheet name="style.css" library="css"/>
</h:head>
<h:body>
<!—メモエンティティの作成日時の有無によって新規メモ登録ページ orメモ編集ページを切り替え-->
<h2>
<h:outputText value="新規メモ登録" rendered="#{memoBean.memo.createTime == null}"/>
<h:outputText value="メモ編集" rendered="#{memoBean.memo.createTime != null}"/>
</h2>
<h:form>
<h:panelGrid columns="2">
<h:outputLabel value="タイトル" for="title"/><h:inputText value="#{memoBean.memo.title}" id="title"
size="80"/>
<h:outputLabel value=" 内 容 " for="content"/><h:inputTextarea value="#{memoBean.memo.content}"
id="content" cols="90" rows="20"/>
</h:panelGrid>
<h:commandButton value="登録 " action="#{memoBean.register()}" rendered="#{memoBean.memo.createTime ==
null}" styleClass="button"/>
<h:commandButton value=" 更 新 " action="#{memoBean.update()}" rendered="#{memoBean.memo.createTime !=
null}" styleClass="button"/>
<!--JavaScriptで確認ダイアログを表示-->
<h:commandButton value=" 削 除 " action="#{memoBean.delete()}" rendered="#{memoBean.memo.createTime !=
null}" styleClass="button" onclick="return confirm('削除してよろしいですか?')"/>
<h:button value="戻る" outcome="index" styleClass="button"/>
<!--タイトルに対するエラーメッセージ表示位置を指定-->
<h:message for="title"/>
</h:form>
</h:body>
</html>
2015/08/29 Java女子部
Copyright (C) 2015 Misaki Kajiura All Rights Reserved. 15
[参考]memo-app/web/resources/css/style.css
body{
font-family: メイリオ, Osaka;
margin: 20px 20px 20px 20px;
background-color: #FDF0D5;
}
a {
text-decoration: none;
}
.button{
font-family: メイリオ, Osaka;
background-color: #F0544F;
color: #FDF0D5;
border-radius: 4px;
}
.h1{
text-align: center;
background-color: #D81E5B;
color: #FDF0D5;
}
.c1{
width: 300px;
text-align: left;
padding-left: 10px;
}
.c2{
width: 350px;
text-align: left;
padding-left: 10px;
}
.r1{
background-color: #FFFFFF;
margin: 10px 10px 10px 10px;
}