blog1.mammb.com
前回作成したEJBにJPAによるDB操作を組み込む
DBサーバの起動
glassfish 同梱の Derby を使う。glassfish の asadmin コマンドで
asadmin start-database
とすることで Derby が起動する。DBは以下のフォルダに sun-appserv-samples という名前で作成される
glassfish の管理コンソールで見るとJDBCリソースができてる
POM の編集
pom に JPA の依存関係を定義
<dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>javax.persistence</artifactId> <version>2.0.0</version> <scope>provided</scope> </dependency>
pom は今までのものと合わせて以下
<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>etc9</groupId> <artifactId>webapp001</artifactId> <version>0.1</version> <packaging>war</packaging> <name>webapp001</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>javax</groupId> <artifactId>javaee-web-api</artifactId> <version>6.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.ejb</artifactId> <version>3.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>javax.persistence</artifactId> <version>2.0.0</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.2</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.5.1</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build> </project>
persistence.xml の作成
src/main/resources/META-INF に persistence.xml を作成
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="webapp001PU" transaction-type="JTA"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <jta-data-source>jdbc/__default</jta-data-source> <!-- Glassfish Default Datasource --> <class>etc9.domain.Book</class> <properties> <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/> <property name="eclipselink.logging.level" value="INFO"/> </properties> </persistence-unit> </persistence>
- persistence-unit の名前に webapp001PU を定義して、JPAプロバイダには eclipselink を指定
- jta-data-source には先程起動した Derby のデフォルトデータソース名を指定
- Entity の対象として後で作成する Book を指定
- eclipselink 固有のオプションにてテーブルの自動再作成を指定
<exclude-unlisted-classes>false</exclude-unlisted-classes>
Bookエンティテイの作成
package etc9.domain; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class Book implements Serializable { private static final long serialVersionUID = 1L; private Long id; private String title; private String description; @Id @GeneratedValue public Long getId() { return id; } public void setId(Long id) { this.id = id; } @Column(nullable = false) public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } @Column(length = 1000) public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String toString() { return getClass().getSimpleName() + "[" + getId() + ", " + getTitle() + ", " + getDescription() + "]"; } }
- @Entity にてエンティティ指定
- その他必要に応じてプロパティにアノテーションを付与
EntityManager からのエンティテイ操作
簡単のために EJB に直接 SELECT と INSERT 用のメソッドを作成する。
インターフェースを以下
package etc9.service; import java.util.List; import etc9.domain.Book; public interface BookService { List<Book> findAll(); Book create(Book book); }
インターフェースを EJB で実装
package etc9.service; import java.util.List; import javax.ejb.Local; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.TypedQuery; import etc9.domain.Book; @Stateless @Local(BookService.class) public class BookServiceImpl implements BookService { @PersistenceContext(unitName = "webapp001PU") private EntityManager em; @Override public List<Book> findAll() { TypedQuery<Book> query = em.createQuery("SELECT b from Book b", Book.class); return query.getResultList(); } @Override public Book create(Book book) { em.persist(book); return book; } }
- @PersistenceContext にて persistence.xm で指定したユニット名を指定して EntityManager を DI
サーブレットの追加
とりあえず、WebServlet として検索用と登録用のサーブレットを作成(あとでJSFに変える)
@WebServlet(urlPatterns={"/book/find"}) public class BookFindServlet extends HttpServlet { @EJB private BookService bookService; public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException { PrintWriter pw = res.getWriter(); pw.println("<h1>Book List</h1><br>"); List<Book> books = bookService.findAll(); for (Book b : books) { pw.println(b.toString() + "<br>"); } } }
DB に固定的にレコード入れるサーブレットを作成
@WebServlet(urlPatterns={"/book/create"}) public class BookCreateServlet extends HttpServlet { @EJB private BookService bookService; public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException { Book book = new Book(); book.setTitle("Learning Perl"); book.setDescription("3rd Edition"); book = bookService.create(book); PrintWriter pw = res.getWriter(); pw.println(book.toString()); } }
デプロイと実行
前回までと同じでデプロイ
mvn package asadmin undeploy webapp001-0.1.war asadmin deploy target/webapp001-0.1.war
http://localhost:8080/webapp001-0.1/book/find にアクセス。まだ登録されていない
http://localhost:8080/webapp001-0.1/book/create にアクセス。
http://localhost:8080/webapp001-0.1/book/find にアクセス。DB に登録されている
DBには
ij ij> connect 'jdbc:derby://localhost:1527/sun-appserv-samples'; ij> show tables ij> describe book;
次回は、適当に作ったサーブレットを JSF に変更する
blog1.mammb.com