假設 Java DB 已建好 db_name 資料庫,帳密為 user/password。
以下展示 Java EE 後台組件如何善用資料來源定義,注入資料來源,定義執行SQL指令,回傳結果集合給前台。
-
- // 定義資料來源
- @DataSourceDefinition(
- name = "java:global/jdbc/db_name",
- className = "org.apache.derby.jdbc.ClientDataSource",
- url = "jdbc:derby://localhost:1527/db_name",
- databaseName = "db_name",
- user = "user",
- password = "password")
-
- @Named("bean")
- @javax.faces.view.ViewScoped
- public class Bean implements Serializable
- {
- // 定義每筆記錄的欄位屬性 f1, f2, f3
-
- // 要求伺服器注入資料來源成為 dataSource 物件
- @Resource(lookup="java:global/jdbc/db_name")
- DataSource dataSource;
-
- // 回傳查詢結果集合
- public ResultSet query() throws SQLException
- {
- // check whether dataSource was injected by the server
- if (dataSource == null)
- {
- throw new SQLException("Unable to obtain DataSource");
- }
-
- // 透過注入的資料來源,從連線池取得連線
- Connection connection = dataSource.getConnection();
-
- // check whether connection was successful
- if (connection == null)
- {
- throw new SQLException("Unable to connect to DataSource");
- }
-
- try
- {
- // 建立查詢指令
- PreparedStatement getRecords = connection.prepareStatement(
- "SELECT * FROM tbl");
-
- // 建立存放結果的快取列集合
- CachedRowSet rowSet =
- RowSetProvider.newFactory().createCachedRowSet();
-
- // 執行查詢指令,將結果填入列集合
- rowSet.populate(getRecords.executeQuery());
-
- // 回傳列集合,供前台呈現
- return rowSet;
- }
- finally
- {
- connection.close(); // return this connection to pool
- }
- }
-
- // 新增一筆記錄,回傳去處網頁名稱
- public String insert() throws SQLException
- {
- // check whether dataSource was injected by the server
- if (dataSource == null)
- {
- throw new SQLException("Unable to obtain DataSource");
- }
-
- // 透過注入的資料來源,從連線池取得連線
- Connection connection = dataSource.getConnection();
-
- // check whether connection was successful
- if (connection == null)
- {
- throw new SQLException("Unable to connect to DataSource");
- }
-
- try
- {
- // 建立帶參數新增記錄指令
- PreparedStatement addEntry =
- connection.prepareStatement("INSERT INTO tbl " +
- "(f1,f2,f3) VALUES (?, ?, ?)");
-
- // 指定欄位值
- addEntry.setString(1, getF1());
- addEntry.setString(2, getF2());
- addEntry.setString(3, getF3());
-
- addEntry.executeUpdate(); // insert the entry
- return ""; // 回傳空字串,停在原頁
- }
- finally
- {
- connection.close(); // 不管發生例外或return,都會關閉連線,歸還給連線池
- }
- }
- }
- 利用 Java EE 後台注入資料來源的好處包括
- 連線池管理,可供連線重複使用,減少頻繁開關連線的成本。
- 資源管理,伺服器可管理連線生命週期,確保連線正常關閉,返回連線池。
- 組態管理,伺服器設定資料庫連線組態細節,程式只要呼叫資料來源即可。
如果願意喪失上述好處,也可採用
A. 單機版如DriverManager操作資料庫作法,一切自己管理,如下。
-
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.sql.Statement;
-
- public class JavaDBExample {
- private static final String DB_URL = "jdbc:derby:myDB;create=true";
- private static final String USER = "user";
- private static final String PASSWORD = "password";
-
- public static void main(String[] args) {
- try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
- Statement stmt = conn.createStatement()) {
-
- // Create a table
- String createTableSQL = "CREATE TABLE addresses (" +
- "id INT PRIMARY KEY, " +
- "firstname VARCHAR(255), " +
- "lastname VARCHAR(255), " +
- "street VARCHAR(255), " +
- "city VARCHAR(255), " +
- "state VARCHAR(255), " +
- "zip VARCHAR(255))";
- stmt.execute(createTableSQL);
-
- // Insert data
- String insertSQL =
- "INSERT INTO addresses VALUES " +
- "(1, 'John', 'Doe', '123 Main St', 'Anytown', 'CA', '12345')";
- stmt.execute(insertSQL);
-
- // Query data
- String querySQL = "SELECT * FROM addresses";
- ResultSet rs = stmt.executeQuery(querySQL);
-
- while (rs.next()) {
- System.out.println("ID: " + rs.getInt("id"));
- System.out.println("First Name: " + rs.getString("firstname"));
- System.out.println("Last Name: " + rs.getString("lastname"));
- System.out.println("Street: " + rs.getString("street"));
- System.out.println("City: " + rs.getString("city"));
- System.out.println("State: " + rs.getString("state"));
- System.out.println("ZIP: " + rs.getString("zip"));
- }
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
或者,
B. 採用單機版Java Persistence API (JPA) 操作資料庫作法,如下。
- // Address.java 住址個體類別
-
- import javax.persistence.Entity;
- import javax.persistence.Id;
- import javax.persistence.Table;
-
- @Entity
- @Table(name = "addresses")
- public class Address {
- @Id
- private int id;
- private String firstname;
- private String lastname;
- String city;
- private String state;
- private String zip;
-
- // Getters and setters
- }
由如下個體管理員建立查詢,取用資料庫:
- // JpaExample.java
-
- import javax.persistence.EntityManager;
- import javax.persistence.EntityManagerFactory;
- import javax.persistence.Persistence;
- import javax.persistence.TypedQuery;
- import java.util.List;
-
- public class JpaExample {
- private static final EntityManagerFactory ENTITY_MANAGER_FACTORY =
- Persistence.createEntityManagerFactory("myPersistenceUnit");
-
- public static void main(String[] args) {
- EntityManager entityManager = ENTITY_MANAGER_FACTORY.createEntityManager();
-
- try {
- // Create a query to fetch addresses
- TypedQuery<Address> query =
- entityManager.createQuery("SELECT a FROM Address a", Address.class);
- List<Address> addresses = query.getResultList();
-
- // Process the result
- for (Address address : addresses) {
- System.out.println("ID: " + address.getId());
- System.out.println("First Name: " + address.getFirstname());
- System.out.println("Last Name: " + address.getLastname());
- System.out.println("Street: " + address.getStreet());
- System.out.println("City: " + address.getCity());
- System.out.println("State: " + address.getState());
- ();
- }
- } finally {
- entityManager.close();
- ENTITY_MANAGER_FACTORY.close();
- }
- }
- }
其中,建立個體管理員時,須要參考如下 META-INF/persistence.xml 持續組態檔,
內含 myPersistenceUnit 持續單元的定義:
- <persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.2">
- <persistence-unit name="myPersistenceUnit">
- <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
- <class>com.example.Address</class>
- <properties>
- <property name="javax.persistence.jdbc.url" value="jdbc:derby:myDB;create=true"/>
- <property name="javax.persistence.jdbc.user" value="user"/>
- <property name="javax.persistence.jdbc.password" value="password"/>
- <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
- <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"/>
- <property name="hibernate.hbm2ddl.auto" value="update"/>
- </properties>
- </persistence-unit>
- </persistence>