kagamihogeの日記

kagamihogeの日記です。

GlassFish4でOracle11gXEのJDBC接続をつくる

GlassFishの管理コンソールを使用してOracleデータベースへの接続をつくりJPAで接続テスする。

やったこと

ojdbc6.jarをコピーする

%GLASSFISH_ROOT%\glassfish\lib に ojdbc6.jar をコピペする。なんかまぁ直接配置するとか間違ってるような気がしないでもないけど……マニュアル見てもよくわかんなかったので今回はとりあえずこの方法でやる。

JDBC接続プールの作成

GlassFishを起動して管理コンソール http://localhost:4848 にアクセスする。左側ツリーのJDBCを選んで、右側に表示されたJDBC接続プールを選ぶ。

新規ボタンを押す。

プール名は適当な名前を入力する。リソースタイプはjavax.sql.DataSourceにする。データベースドライバーのベンダーはOracleにする。

ここの画面の上の方は特に変更無し。Pingはチェックを入れる。コレにチェックを入れておくと、設定入力完了後に、入力した接続設定でDBに実際に接続できるかどうかのチェックをやってくれる。

スクロールしていくと各種プロパティ設定の入力項目がある。Oracleに接続するためのID、パスワード、URLとかとか。ココが間違ってると当然接続できない。

で、入力ミスがあったまま終了ボタンを押すと、Pingが失敗してエラーが表示される。↑のキャプチャを見ると分かるんですがURLがカラのままなのが原因。

入力ミスを修正するため、JDBC接続プール -> Oracle11gPool の追加プロパティタブを選ぶ。URLにJDBC URLを入力する。

一般タブに戻ってPingボタンを押す。接続に成功すれば下記キャプチャのようになる。これでJDBC接続プールの設定は完了。

JDBCリソースの作成

先ほど作成したJDBC接続プールと、JNDIを関連付ける。
左側ツリーのJDBCを選んで、右側に表示されたJDBCリソースを選び、新規ボタンを押す。

適当なJNDI名を入力して、プール名のボックスからからさっき作ったJDBC接続プールを選ぶ。これで準備完了。

接続確認

とりあえず極めて適当なJNDI経由でコネクション取得してSQL発行するServletを作る。ブラウザからアクセスしてOracleのバージョンテキストが表示されればOK.

package glassfish4test;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

@WebServlet("/hoge")
public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        try {
            Context ctx = new InitialContext();
            DataSource ds = (DataSource)ctx.lookup("jdbc/Oracle11gXE");
            try (Connection connection = ds.getConnection();
                    PreparedStatement sql = connection.prepareStatement("select * from v$version");
                    ResultSet r = sql.executeQuery();) {
                while (r.next()) {
                    String banner = r.getString(1);
                    System.out.println(banner);
                    resp.getWriter().write(banner);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }
}

JPA経由でアクセスの接続確認する。

適当なテーブルを作り適当なデータを数件いれる。

CREATE TABLE USERS 
(
  ID INTEGER NOT NULL 
, NAME VARCHAR2(20) 
, EMAIL VARCHAR2(20) 
, CONSTRAINT USERS_PK_ID PRIMARY KEY 
  (
    ID 
  )
  ENABLE 
);
insert into users(id, name, email) values (1, 'aaa', 'aaa@hoge');
insert into users(id, name, email) values (2, 'bbb', 'bbbb@hoge');
insert into users(id, name, email) values (3, 'ccc', 'ccccccc@hoge');
commit;

META-INF/persistence.xmlを作る。

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
	xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
	<persistence-unit name="glassfish4test"
		transaction-type="JTA">
		<jta-data-source>jdbc/Oracle11gXE</jta-data-source>
		<class>glassfish4test.model.User</class>
	</persistence-unit>
</persistence>

EclipseJPA Entities from TablesでEntityつくる。

package glassfish4test.model;

import java.io.Serializable;
import javax.persistence.*;

/**
 * The persistent class for the USERS database table.
 * 
 */
@Entity
@Table(name = "USERS")
@NamedQuery(name = "User.findAll", query = "SELECT u FROM User u")
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    private long id;

    private String email;

    private String name;

    public User() {
    }

    public long getId() {
        return this.id;
    }

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

    public String getEmail() {
        return this.email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

JPA経由でデータベースアクセスするコードを書く。

package glassfish4test;

import glassfish4test.model.User;

import java.io.IOException;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/hoge")
public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
      EntityManagerFactory emf = Persistence.createEntityManagerFactory("glassfish4test");
      EntityManager em = emf.createEntityManager();
      Query q = em.createNamedQuery("User.findAll");
      List<User> list = q.getResultList();
      for (User u : list) {
          System.out.println(u.getName());
      }
      em.close();
      emf.close();
    }
}

EntityManagerのインスタンス自分で作るのもアレなので、DIしてもらうように修正する。

package glassfish4test;

import glassfish4test.model.User;

import java.io.IOException;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/hoge")
public class TestServlet extends HttpServlet {
    
    @PersistenceContext(unitName="glassfish4test")
    private EntityManager em;
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
      Query q = em.createNamedQuery("User.findAll");
      List<User> list = q.getResultList();
      for (User u : list) {
          System.out.println(u.getId() + ":" + u.getName() + ":" + u.getEmail());
      }
    }
}