| Linux下J2EE简易高效三层模式实现 |
| [ 作者:佚名 转贴自:网络转载 阅读次数:63 更新时间:2007-4-25 13:52:00 录入:刘光勇 ] 热 |
|
|
|
本案以 Fedora core 5(ftp://falkor.skane.se/pub/mirrors/fedora/core/5/i386/iso/) JDK 5.0 (http://java.sun.com/j2se/1.5.0/download.jsp) Tomcat 5.5.17 (http://www.apache.org/dist/tomcat/tomcat-5/v5.5.17/bin/) PostgreSQL 8.1.4 (http://www.postgresql.org/ftp/source/v8.1.4/,此开源项目在95年左右由华裔接手,个人比较中意) PostgreSQL JDBC (http://jdbc.postgresql.org/download.html 选择8.1-407 JDBC 3版本) 为例。 首先,在PC机上安装好Fedora core 5,如果想要自己拿源码包编译安装PostgreSQL,注意C编译器一定要装全,HD空间允许的话建议完全安装。 接着配置好此机网卡,开通ssh,以便远程在Win上远程访问。 现在可以在Win上ssh远程登陆到Fedora,同时利用Win下的WinSCP工具(类似FTP客户端)把JDK,Tomcat,PostgreSQL等相关软件上传到Fedora的/opt目录下(本人习惯放在此目录下)。
一、 数据层 准备工作: A. 准备数据库 可以用Fedora自带的rpm包的PostgreSQL,也可自己用源码包编译安装,(我习惯用源码包编译安装同时卸载OS自带的rpm包) 1) [root@FC5 /]# rpm -aq|grep postgres //查询系统自带的PostgreSQL的rpm包 postgresql-x.x.x-1 postgresql-libs-x.x.x-1 ...... 2) [root@FC5 ]# rpm -e postgresql-x.x.x-1 postgresql-x.x.x-1 ......//将列出的rpm包全部删除,如果存在依赖关系可以使用--nodeps选项开强行卸载 3) 把获得的PostgreSQL源码包postgresql-8.1.4.tar.gz复制到/opt目录下,然后解开此源码包 [root@FC5 /]# cd /opt/ [root@FC5 opt]# tar zxvf ./postgresql-8.1.4.tar.gz 4) 为PostgreSQL添加相应系统用户 [root@FC5 /]# useradd postgres -d /opt/postgresql-8.1.4 [root@FC5 /]# chown -R postgres. postgres /opt/postgresql-8.1.4 [root@FC5 /]# su - postgres 5) 预编译 [postgres@FC5 ~]$ ./configure --prefix=/opt/postgresql-8.1.4 --localstatedir=/opt/postgresql-8.1.4/data --enable-nls --prefix参数是指定PostgreSQL的安装目录 --localstatedir是指定postgres数据的存放目录 --enable-nls是能够识别本地语言(enable Native Language Support) 6) 编译,安装 [postgres@FC5 ~]$ make [postgres@FC5 ~]$ make install 7) 安装完成后需要创建初始数据库 [postgres@FC5 ~]$ ./bin/initdb -U postgres -D ./data -W -E UNICODE –U 指定数据库管理员名称 -D指定数据存放目录 -W给数据库管理员设置密码 -E设定存放记录的编码 8) 启动/停止数据库 [postgres@FC5 ~]$ pg_ctl start(stop) -D ./data -l ./db.log -o -i -D 将要打开的数据库目录 -l 输出日志到指定文件 -o 传递给 postmaster 的命令行选项 -i 打开 TCP/IP 联接 9) 创建要用到的数据库 [postgres@FC5 ~]$ createdb test_db B. 准备好JDK JDK的安装非常简单,只需要解开JDK包即可 [root@FC5 /]# cd /opt [root@FC5 opt]# sh ./jdk-1_5_0_07-linux-i586.bin 输入yes接受license即可 这样JDK就安装到/opt/jdk1.5.0_07目录下了
开始数据层配置工作,此层基本是由容器来完成,我们只需要把数据库的JDBC驱动放在tomcat/common/lib/下(放在此目录下可以被Tomcat启动的时候自动加载,而不需要额外指定类路径), 同时配置数据库连接池相关文件就可以。 开始配置文件(以配置全局连接池名称为例) 1 编辑tomcat/conf/server.xml文件 [root@FC5 /]# vi /opt/apache-tomcat-5.5.17/conf/server.xml
<!-- Global JNDI resources --> <GlobalNamingResources> ...... <!--以下是要添加的内容--> <Resource name="your_db_pool" auth="Container" type="javax.sql.DataSource" driverClassName="org.postgresql.Driver" url="jdbc:postgresql://127.0.0.1:5432/test_db" username="postgres" password="" maxActive="20" maxIdle="10" maxWait="-1"/> <!--添加完毕--> ...... </GlobalNamingResources> 以上添加的配置内容指定了 1) 在java程序中需要连接数据库的时候,寻找的数据连接名称为your_db_pool 2) 数据库的驱动程序为org.postgresql.Driver 3) 该数据连接名称对应的物理数据库是本机(127.0.0.1)的5432监听端口上名为test_db的物理数据库 4) 连接该数据库的用户名是postgres,密码为空 5) toncat运行时对此数据源开启的最大连接数是20,空闲连接数是10,不限制最大等待连接 2 编辑tomcat/conf/context.xml文件 [root@FC5 /]# vi /opt/apache-tomcat-5.5.17/conf/context.xml <!-- The contents of this file will be loaded for each web application --> <Context> <!-- Default set of monitored resources --> <WatchedResource>WEB-INF/web.xml</WatchedResource> <!-- Uncomment this to disable session persistence across Tomcat restarts --> <!-- <Manager pathname="" /> --> <!--以下是添加的内容--> <ResourceLink global="your_db_pool" name="your_db_pool" type="javax.sql.DataSource"/> <!--添加完毕--> </Context>
现在已经可以启动Tomcat了,但是为了方便我喜欢自己写一个shell来启动和停止tomcat [root@FC5 /]# vi /opt/apache-tomcat-5.5.17/bin/opt_tomcat.sh #!/bin/sh export JAVA_HOME=/opt/jdk1.5.0_07 case "$1" in 'start') # Start the Tomcat Server: cd /opt/apache-tomcat-5.5.17/bin $PWD/startup.sh >> ../logs/running.log 2>&1 & echo ;; 'stop') # Stop the Tomcat Server: cd /opt/apache-tomcat-5.5.17/bin $PWD/shutdown.sh ;; 'restart') # Restart the Tomcat Server: stop sleep 2 start ;; *) echo "Usage: daemon.sh { start | stop | restart }" exit 1 esac exit 0
要想直接运行刚才编写的shell脚本,记着要给该脚本文件赋予可执行权限 [root@FC5 /]# chmod 755 /opt/apache-tomcat-5.5.17/bin/opt_tomcat.sh 现在可以通过带参数来实现启动/停止/重启tomcat了 [root@FC5 /]# /opt/apache-tomcat-5.5.17/bin/opt_tomcat.sh start(stop/restart) 二、业务处理层 此层需要2个java类,一个用于取连接,一个用于执行SQL语句并返回结果
1 取数据连接的类 ConnectionUtil.java
package com.db;
import java.sql.*; import javax.naming.*; import javax.sql.*;
public class ConnectionUtil { private static Object poolLock = new Object(); private static DataSource connectionPool; private Connection conn = null; private Context ctx = null;
public Connection getConnection() {
synchronized (poolLock) { if (connectionPool == null) { try { InitialContext ctx = new InitialContext(); connectionPool = (DataSource) ctx.lookup("your_db_pool"); } catch (Exception e) { //打印错误信息 return null; } } }//synchronized try { conn = connectionPool.getConnection(); conn.setAutoCommit(false); }catch (SQLException e) { //打印错误日志 } }//end getConnection() }
2 执行SQL语句并返回结果的类 SQLExecute.java
package com.db;
import java.sql.*;
public class SQLExecute { ConnectionUtil connectionUtil = new ConnectionUtil(); private Connection conn = connectionUtil.getConnection(); //返回查询(select)结果方法 public ResultSet executeQuery(String sql){ if(conn==null){//没有拿到连接 return null; } ResultSet rs = null; Statement stmt = null; try { //允许记录集指针跳转 rs.last(); rs.previous(); stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); rs = stmt.executeQuery(sql); }catch (SQLException e) { //打印出错日志 return null; } return rs; } //返回执行(insert,update,delete)结果方法 public int executeUpdate(String sql) { int i=0; try { Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); i = stmt.executeUpdate(sql); conn.commit(); }catch (SQLException e) { //打印出错日志 i=-1; } return i; } //事务处理方法 public int executeUpdatePre(String sql) { int i=0; try { Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); i = stmt.executeUpdate(sql); }catch (SQLException e) { //打印出错日志 i=-1; } return i; } //事务提交 public boolean Commit() { boolean b = false; try { if(conn != null) conn.commit(); b = true; }catch (SQLException e) { //打印出错日志 return false; } return b; } //关闭数据连接方法 public boolean closeConn() { boolean b = false; try { if(conn != null) conn.close(); }catch (SQLException e1) { //打印出错日志 return false; } return b; } }
3 在Bean中的调用,bean1.java
package com.app1;
import java.sql.*; import com.db.*;
public class bean1 { /*返回SQL执行的String*/ public static String getSQLString(String sql){ String str=""; SQLExecute sqlExecute=new SQLExecute(); ResultSet rs=sqlExecute.executeQuery(sql); try{ if(rs.next()) str=rs.getString(1); }catch(SQLException e){ //打印出错日志 }finally{ sqlExecute.closeConn(); return str; } } }
4 在Servlet中的调用,servlet1.java 说到servlet不得不提到WEB-INF/web.xml,因为此文件的重要功能之一就是用来配置servlet的类名和http访问的路径的映射关系的 <web-app> <!--先定义类路径为com.app1.servlet1的类的类名为servlet1 --> <servlet> <servlet-name>servlet1</servlet-name> <servlet-class>com.app1.servlet1</servlet-class> </servlet> <!--再定义类名为servlet1的servlet的http访问路径,把此访问路径指向http://ip:port/用户应用项目(若有)/dir1/servlet1.do --> <servlet-mapping> <servlet-name>servlet1</servlet-name> <url-pattern>/dir1/servlet1.do</url-pattern> </servlet-mapping> </web-app>
package com.app1; /** 此servlet用于从数据库中获取某张表的记录集,然后把记录集传递给位于表现层的theJsp.jsp页面 */ import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import com.db.*;
public class servlet1 extends HttpServlet { public void init() throws ServletException { } //Process the HTTP Get request public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { RequestDispatcher dispatcher = null; SQLExecute sqlExecute = new SQLExecute();//此时已经获取数据连接 ResultSet rs=sqlExecute.executeQuery("select * from tab1"); request.setAttribute("theRS", rs); dispatcher = request.getRequestDispatcher("theJsp.jsp"); dispatcher.forward(request, response);//转向上一行指定的jsp页面 sqlExecute.closeConn(); //最后关闭连接 } //Process the HTTP Post request public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } //Clean up resources public void destroy() { } )
三、表现层 在此层中由theJsp.jsp页面接受来自servlet1的数据计算结果,并且在页面中显示出来 <%@page contentType="text/html; charset=GBK" session="true" language="java"%> <%@page import="java.sql.*"%> <% ResultSet theRS = (ResultSet)request.getAttribute("theRS"); while(theRS.next()){ out.print(theRS.getInt(1)+" "+theRS.getString(2)+"<br>"); } %>
以上就是在Linux下一个简单的J2EE三层模式的实现,如有不当之处请严厉指出,同时也希望能对初学者有一些小小的帮助,欢迎各界人事来此论坛交流!
|
|
|
|