ServletFilter+ThreadLocal+DAO,10分钟Hibernate再体验

论坛上关于如何管理session的讨论已经很多了,但是因为没有一个完整的可以run的例子,很多人在这点上还是感到迷惑。今天有时间,就把自己做过的一个小例子贴出来,希望能节省后来者的学习时间。

这个例子实现了:
1. 用ThreadLocal管理session,保证了在一个thread中使用同一个session(connection)
2. 在ServletFilter中initSessionFactory和closeSession,保证一个应用中只有一个SessionFactory并做到了session-per-request, instead of session-per-operation
3. DAO的粗略实现

菜菜鸟可以先参考一下本人写的第一个例子,Tomcat+Mysql+UltraEdit,10分钟Hibernate初体验
http://forum.javaeye.com/viewtopic.php?t=4077 Smile

1. 保证你的Mysql工作正常。

java代码: 


CREATE TABLE cat (
    cat_id varchar(20) NOT NULL,
    name varchar(20) NOT NULL,
    sex char(1),
    weight float,
    PRIMARY KEY (cat_id)
);

insert cat values('1', 'ada', 'F', 5);
insert cat values('2', 'belinda', 'F', 10);
commit;



2. 保证你的Tomcat工作正常。Then stop Tomcat。
在{TOMCAT_HOME}/conf/server.xml中加入:
java代码: 


<Context path="/hellohibernate" docBase="hellohibernate" reloadable="true">
    <Resource name="jdbc/hellohibernate" scope="Shareable" type="javax.sql.DataSource"/>
    <ResourceParams name="jdbc/hellohibernate">
        <parameter>
            <name>factory</name>
            <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
        </parameter>

        <!-- DBCP database connection settings -->
        <parameter>
            <name>url</name>
            <value>jdbc:mysql://localhost:3306/test</value>
        </parameter>
        <parameter>
            <name>driverClassName</name><value>com.mysql.jdbc.Driver</value>
        </parameter>
        <parameter>
            <name>username</name>
            <value>yourusername</value>
        </parameter>
        <parameter>
            <name>password</name>
            <value>yourpassword</value>
        </parameter>

        <!-- DBCP connection pooling options -->
        <parameter>
            <name>maxWait</name>
            <value>3000</value>
        </parameter>
        <parameter>
            <name>maxIdle</name>
            <value>100</value>
        </parameter>
        <parameter>
            <name>maxActive</name>
            <value>10</value>
        </parameter>
    </ResourceParams>
</Context>



3. 将附件hellohibernate.zip更名为hellohibernate.war,扔到{TOMCAT_HOME}/webapps下,重新启动Tomcat。

4. 你会发现hellohibernate已经被自动部署了,copy下列文件到{TOMCAT_HOME}/webapps/hellohibernate/WEB-INF/lib下:
hibernate2.jar
log4j-1.2.8.jar
commons-collections-2.1.jar
commons-logging-1.0.3.jar
dom4j-1.4.jar
cglib-2.0-rc2.jar
odmg-3.0.jar
ehcache-0.6.jar
jta.jar
(其实我本可以把它们打包到war里面的,但是这样war文件就到了2M,现在才12K)

5.
http://localhost:9090/hellohibernate/servlet/HelloHibernateServlet
参看HelloHibernateServlet.java,你会发现我们做了以下操作:
a. create了罗宾猫,得力猫和胖子猫
b. delete了阿达猫和柏林达猫
c. update了胖子猫
d. select了所有猫

6. 代码分析

web.xml
java代码: 


    <filter>
        <filter-name>HelloHibernateFilter</filter-name>
        <filter-class>com.xanada.HelloHibernateFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>HelloHibernateFilter</filter-name>
        <url-pattern>
/*</url-pattern> //Filter对所有的请求都响应
    </filter-mapping>



HelloHibernateFilter.java
java代码: 


    //init在整个servlet的生命周期中只做一次,在这里它初始化了SessionFactory,从而保证了SessionFactory在整个进程中只有一个实例
    public void init(FilterConfig filterConfig)
        throws ServletException {
        try {
            HibernateSessionFactory.init();
        } catch (HibernateException e) {
            e.printStackTrace();
        }
    }

    //session是从DAO中得到的,但是做完一个operation后并不close,而是在整个request完成后在doFilter的finally里面close
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
        throws ServletException, IOException {
        try {
            chain.doFilter(req, res);
        } finally {
            try {
                HibernateSessionFactory.closeSession();
            } catch (HibernateException e) {
                e.printStackTrace();
            }
        }
    }


其实你若不愿用filter,完全可以把这两段代码放在相应的servlet.init()和servlet.execute()的finally里。

HibernateSessionFactory
java代码: 


    //sessionFactory是一个singleton
    private static SessionFactory sessionFactory;

    //init在filter.init()中被调用
    public static void init() throws HibernateException

    //currentSession被DAO中被调用
    public static Session currentSession() throws HibernateException

    //closeSession在filter.doFilter()的finally中被调用
    public static void closeSession() throws HibernateException



CatDAOImpl
java代码: 


    //注意:这里的session用完之后并不close,而只flush一下
    public void delCat(String strCatId) {
        try {
            Session s = HibernateSessionFactory.currentSession();

            Object cat = s.load(Cat.class, strCatId);
            s.delete(cat);
            s.flush();
        } catch (HibernateException e) {
            e.printStackTrace();
        }
    }



CatDAO
java代码: 


    //对Cat的CRUD的封装
    public interface CatDAO {
        public void creatCat(Cat cat);
        public List readCats();
        public void updateCat(Cat cat);
        public void delCat(String strCatId);
    }



这里只是对DAO做了最粗略的封装,实际应用中还要加一层DAOFactory。关于DAO pattern,可以在这里得到详细资料:http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html


PS:del方法中要在load之前判断一下哪个object是否存在。不然...........

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值