📄 index.xtp
字号:
<document> <header> <product>resin</product> <type>tutorial</type> <tutorial-startpage>basic</tutorial-startpage> <title>Using Dependency-Injection with JDBC Databases</title> <description> <p>This tutorial describes the standard patternfor using a database in Resin, following the Dependency-Injection/Inversion-of-Control pattern using WebBeans annotations.</p> </description> </header> <body> <summary/><s1><p>Using a JDBC database is a three step process:</p><ul><li>Configuring the <database> in the resin-web.xml or resin.conf</li><li>Injecting the <code>DataSource</code> to a field with a <code>@javax.webbeans.Id</code> annotation.</li><li>Using a <code>Connection</code> from the <code>DataSource</code>to execute the SQL.</li></ul><p>JDBC database access is based around the Factory pattern.With JDBC, <code>javax.sql.DataSource</code> is the Factory object.The <database> configures the <code>DataSource</code> and stores itin the WebBeans directory. The servlet will retrieve the<code>DataSource</code> and use it as a factory to obtain<code>Connection</code> objects, the main workhorse for using databases.</p></s1><s1 title="Files in this tutorial"><deftable><tr> <td><viewfile-link file="WEB-INF/resin-web.xml"/></td> <td>resin-web.xml configuration</td></tr><tr> <td><viewfile-link file="WEB-INF/classes/example/BasicServlet.java"/></td> <td>The JDBC query servlet.</td></tr></deftable></s1><s1 title="Database Schema"><example>CREATE TABLE jdbc_basic_brooms ( id INTEGER PRIMARY KEY auto_increment, name VARCHAR(128), cost INTEGER);INSERT INTO jdbc_basic_brooms (name, cost) VALUES ('firebolt', 4000)INSERT INTO jdbc_basic_brooms (name, cost) VALUES ('nimbus 2001', 500)INSERT INTO jdbc_basic_brooms (name, cost) VALUES ('nimbus 2000', 300)INSERT INTO jdbc_basic_brooms (name, cost) VALUES ('cleansweep 7', 150)INSERT INTO jdbc_basic_brooms (name, cost) VALUES ('cleansweep 5', 100)INSERT INTO jdbc_basic_brooms (name, cost) VALUES ('shooting star', 50)</example></s1><s1 title="Database Configuration"><p>In Resin 3.0, the <database> tag configures the databasepool and driver and saves the connection factory (DataSource) inthe Resin WebBeans directory. WebBeans is an IoC (inversion-of-control)configuration system, making it straightforward to separate resourceconfiguration from the application code.</p><p>The <driver> tag configures the database driver. The databasevendor will make the driver classes available and describe theconfiguration variables. The <a href="doc|db-thirdparty.xtp">thirdparty database page</a> describesseveral important database configurations.</p><p>The <type> tag is the most important driver configuration item.It specifies the main Java driver class. For many drivers, you willhave a choice of different drivers following different internal JDBCAPIs. If you have a choice, you should try the drivers in thefollowing order, after checking your database vendor's recommendations:</p><ol><li>JCA - Java Connection Architecture - this is a common driverinterface for more than just JDBC. If possible, it's generally thebest to choose.</li><li>ConnectionPoolDataSource - JDBC driver which has extra hooks tohelp Resin pool the connections.</li><li>Driver - old-style JDBC driver. Its main benefit is that it'sgenerally always available as a fallback.</li></ol><example><web-app xmlns="http://caucho.com/ns/resin"> <database jndi-name="jdbc/basic"> <driver type="com.caucho.db.jca.ConnectionFactory"> <url>resin:WEB-INF/db</url> </driver> </database></web-app></example><p>The <url> specifies the location of the database. Eachdatabase driver will have a unique URL formal. In this case,the <url> specifies a directory for the database files. Otherdatabases may specify a host and port.</p><s2 title="com.caucho.db.jca.ConnectionFactory"><p>The specific driver for this example,<code>com.caucho.db.jca.ConnectionFactory</code> is a simple databaseintended for examples and testing.</p></s2></s1><s1 title="Servlet Initialization"><p>The servlet is configured with a <code>DataSource</code> toaccess JDBC. Resin allows two styles of configuration: Dependency Injectionusing WebBeans injection and standard servlet <init-param>configuration with JNDI lookups. The Dependency Injection style issimpler, cleaner and makes the application more testable and robust.</p><example>import javax.webbeans.In;public class BasicServlet extends HttpServlet { @In private DataSource _ds; ...}</example><s2 title="Dependency Injection configuration"><p>Using dependency injection to configure servlets has some advantagesover the init-param method:</p><ol><li>The configuration is type-safe. Resin's dependency injection willcheck the DataSource type before injecting the value. Resin will alsoinform you of any conflicts, e.g. configuration of multiple matchingdatabases.</li><li>The servlet initialization code is simpler.The servlet doesn't need JNDI code.</li><li>The configured values can be more complicated than the string-limitation of <init-param>.</li><li>The DataSource itself isn't tied to JNDI, although JNDI will certainlyremain the primary registry.</li></ol><p>Enabling the Dependency Injection pattern is trivial: justadd the <code>@javax.webbeans.In</code> annotation to your<code>DataSource</code> field.</p><example title="resin-web.xml"><servlet servlet-name="my-servlet" servlet-class="example.BasicServlet"></servlet></example></s2></s1><s1 title="Using the Database"><p>The most important pattern when using JDBC is thefollowing try/finally block. All database access should follow this pattern.Because connections are pooled, it's vital to close the connection nomatter what kind of exceptions may be thrown So the<code>conn.close()</code> must be in a finally block.</p><example title="Connection try ... finally block">Connection conn = _ds.getConnection();try { ...} finally { conn.close();}</example><p>The full example splits the database access into two methods toclarify the roles. The <code>service</code> retrieves the outputwriter from the servlet response and wraps any checked exceptionsin a <code>ServletException</code>. Splitting the servlet methodsimplifies the <code>doQuery</code> method, so it can concentrateon the database access.</p><example>public void service(HttpServletRequest req, HttpServletResponse res) throws java.io.IOException, ServletException{ PrintWriter out = res.getWriter(); try { doQuery(out); } catch (SQLException e) { throw new ServletException(e); }}private void doQuery(PrintWriter out) throws IOException, SQLException{ Connection conn = _ds.getConnection(); try { String sql = "SELECT name, cost FROM jdbc_basic_brooms ORDER BY cost DESC"; Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); out.println("<table border='3'>"); while (rs.next()) { out.println("<tr><td>" + rs.getString(1)); out.println(" <td>" + rs.getString(2)); } out.println("</table>"); rs.close(); stmt.close(); } finally { conn.close(); }}</example></s1><s1 title="See also"><ul> <li><a href="doc|config-database.xtp">Database configuration</a> reference</li> <li><a href="doc|db-thirdparty.xtp">Sample configurations</a> for several database drivers</li> <li>Using <a href="../db-jdbc-ioc/index.xtp">Dependency Injection for Databases</a></li> <li>The <a href="../ioc-injection/index.xtp">Dependency Injection</a> (or Assembly Line) pattern.</li></ul></s1> </body></document>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -