菜单

【原创】整合Spring4+Hibernate4+Struts2时NullPointerException问题解决

2018年11月16日 - jQuery

1、开场白

相信SSH初学者肯定遇到过是问题,但是以是百怀念不得其解,明白了今后就是醒。

前言

  以来描写就首笔记之前,去押了同篇别人的美文。自从出道以来,已经记不得有多久没有失去押确实的文学作品了。甚至都都认为那些会逗我们心灵共鸣的篇章对我们的生并没啊作用。毕业的话,我吗从来不放弃看开,但看之题也再度富有功利性,比如《XXX从入门到精通》、《XXX指南》一类似的书写。貌似这仿佛书又有着价值,因为她会表现。不管由于什么样的目的,现在的确能够静下心来欣赏文学作品的人数越来越少。功名利禄,灯红酒绿更会抓住人心。但奇迹静下心来,与心灵对话,也会为咱这种无产阶级短暂之拖压力,产生有幸福感。也许风雨后底彩虹来得太晚,但明天之路还抬高,我莫会见以今虽反而在路上。
  继续我们的成人之同,这个题目就是外常谈,这些技术呢几乎是具备java程序员的基本技能。关于这三单框架的咬合的课已经重重了。但是于系统的、或者说比较详细的以会以爱入坑的地方着重强调的文章却休多。对于如自家这种新家的话,是更为详细越好,最好会以坑多的地方大多开提醒。
  我于描绘就首笔记的时候会尽可能详尽的介绍就三单框架的整合过程,并当我掉坑的地方着重强调,一方面让自己记得再充分,另一方面想对后来者有所帮助。我吧是新师,如发不妥,也指望能够留言指,先行谢过。

2、问题讲述

程序实现过程是UserAction中调用UserService,UserService的落实类似吃调用了DAO类。在程序运行过程被控制台出现NullPointerException的荒唐:

图片 1

调剂时上了InvocationTargetException函数:

图片 2

动Struts框架搭建Web项目

  1、首先下充斥好Struts库(点击下载),在官下载页下载struts-2.5.14.1-all.zip。
  2、创建Web Project:打开Eclipse => File => New => Web
Project。
  3、在 … => struts-2.5.14.1-all.zip => struts-2.5.14.1 =>
lib目录下以如下图的这些库(也可生充斥struts-2.5.14.1-min.zip,其中的库是搭建Struts项目必须使导入的库)拷贝到花色的WebRoot
=> WEB-INF => lib目录下,并补充加到build path

图片 3

image.png

  4、在WEB-INF下创建web.xml文件。
  5、在web.xml文件中布置struts拦截器(专注拦截器不要放错了,新本子的拦截器和原有本子拦截器不同等,具体的得看struts-core.jar下面是不是发生响应的java类):

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
  <display-name>MyWeb</display-name>
  <welcome-file-list>
    <welcome-file>login.jsp</welcome-file>
  </welcome-file-list>
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
  <!-- 新版本struts用下面这个拦截器 -->
    <!--<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter> -->
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>*.action</url-pattern>
  </filter-mapping>
</web-app>

  6、在src目录下创造struts配置文件struts.xml
(记住是src目录,不是WEB-INF目录,如果要是放在WEB-INF目录下,请于WEB-INF目录下创造classes目录,并将struts.xml放在classes目录下。这样做的由来:在编译的时会用src下之文书拷贝到classes目录下,WEB-INF/classes目录下的文本呢还举见面为拷到编译路径的classes目录下,而WEB-INF下之文书未会见于拷贝到classes目录下,在程序运行的时刻默认是以classes目录下查找web.xml和struts.xml)
  7、在com.xxx.action下创建LoginAction类:

package com.xxx.action;

import com.opensymphony.xwork2.ActionSupport;

public class LoginAction extends ActionSupport{

    private String userName;
    private String password;


    public String getUserName() {
        return userName;
    }


    public void setUserName(String userName) {
        this.userName = userName;
    }


    public String getPassword() {
        return password;
    }


    public void setPassword(String password) {
        this.password = password;
    }


    /**
     * 
     */
    private static final long serialVersionUID = 1L;


    @Override
    public String execute() throws Exception {
        if ("test".equals(getUserName()) && "123456".equals(getPassword())) {
            return SUCCESS;
        }
        return ERROR;
    }

}

  8、在WEB-INF/content目录下创办登录成功与失败的来得页success.jsp、error.jsp:

success.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>My JSP 'success.jsp' starting page</title>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>

  <body>
    登录成功!<br>
  </body>
</html>

error.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'error.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

</head>

<body>
    账户名或密码错误
    <br>
</body>
</html>

  9、打开才创建好之struts.xml文件,开始配备:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
    <package name="xxx" extends="struts-default">
        <action name="login.action" class="com.xxx.action.LoginAction">
            <result name="success">/WEB-INF/content/success.jsp</result>
            <result name="error">/WEB-INF/content/error.jsp</result>
        </action>
    </package>
</struts>    

征:package的name属性是友善沾的,用于管理action,必须使继承extends=”struts-default”。
特别注意:如果你下的是土生土长本子的拦截器,那么在部署的时action的name属性login.action要描绘全(因为后面要的下用底便是以此),如果您以的是新本子的拦截器,那么就需要用action的name属性配置也login就得了(请求时的action
name还是login.action)

  10、创建登录页,在WebRoot目录下创办login.jsp(因为当web.xml文件在设置的welcome-file是login.jsp因此输入网址会直接导航及这个界面),login.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>My JSP 'login.jsp' starting page</title>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>

  <body>
    <form action="login.action">
        用户名:<input type="text" name="userName"><br>
        密码: <input type="password" name="password"><br>
        <input type="submit" value="登录">
    </form>
  </body>
</html>

证实:form的action属性要和struts.xml文件被配置是action的name属性一致(旧本子,如果是新本子,在struts配置的时光要是以.cation结尾,那么去掉.action),input的name属性对承诺LoginAction中之userName属性和password属性,且名字务必保持一致。

  到这个吧的,struts项目即使搭建好了,可以先运行下档,测试运行过程是否正规,如果发问题,在产同样步事先,请保管已经解决。

3、解决方法

Debug中发觉UserService代码在调用Dao的上起了问题:

图片 4

调剂发现,传的参数还是健康的,但是就是在59履行代码报错,而且不克一直上baseDao的get方法。进入了底的InvocationTargetException代码:

图片 5

更为生调试,控制高输出java.lang.NullPointerException错误。

想到以实践baseDao对象的get方法上会调用invoke()方法。

Method invoke()方法源代码:

图片 6

代码中视当传进来的目标为空时,返回NullPointerException()错误。所以可以毫无疑问之是污染进的dao对象是为空的。

扣押一下Spring对一一对象的治本情况,检查代码发现了问题所在,dao没有流入。

图片 7

略知一二了问题所在,解决办法:

添加dao对象到Spring Ioc容器

图片 8

在16实行加上@Resource(name = “baseDao”)注解,告诉Spring,让Spring把创建好的baseDao对象注入给UserService。

诸如此类Spring
NullPointerException,InvocationTargetException的题目得以化解。

 

Spring整合Struts

  首先,下载spring,下载地址http://repo.springsource.org/libs-release-local/org/springframework/spring/。根据需要下载相应的本子,我下载的凡5.0.1本。
  下充斥下来后,解压并找到libs文件夹,将libs下面的有jar文件拷贝到花色的WebRoot/WEB-INF/libs目录下,并且add
to build path。
  修改web.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
  <display-name>MyWeb</display-name>
  <welcome-file-list>
    <welcome-file>login.jsp</welcome-file>
  </welcome-file-list>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <filter>
    <filter-name>struts2</filter-name>
   <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>*.action</url-pattern>
  </filter-mapping>
</web-app>

ContextLoaderListener这个监听器负责寻找spring配置文件并启动spring。context-param用于配置spring配置文件的路,如果非配备,则默认在WEB-INF下找applicationContext.xml文件。
  然后在WEB-INF/目录下(请根据自己于context-param中配备的参数进行修改,路径不对,将寻找不顶spring配置文件),创建applicationContext.xml文件。
  创建LoginService接口:

package com.xxx.service;

public interface LoginService {
    String doLogin(String userName,String password);
}

  创建LoginServiceImpl类:

package com.xxx.service;

import com.opensymphony.xwork2.ActionSupport;

public class LoginServiceImpl implements LoginService{

    private String userName = "xxx";
    private String password = "123456";

    @Override
    public String doLogin(String userName, String password) {
        if (this.userName.equals(userName) && this.password.equals(password)) {
            return ActionSupport.SUCCESS;
        }
        return ActionSupport.ERROR;
    }

}

  修改LoginAction类:

package com.xxx.action;

import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.opensymphony.xwork2.ActionSupport;
import com.xxx.service.LoginService;

public class LoginAction extends ActionSupport{

    private String userName;
    private String password;
    private LoginService loginService;




    public LoginService getLoginService() {
        return loginService;
    }


    public void setLoginService(LoginService loginService) {
        this.loginService = loginService;
    }


    public String getUserName() {
        return userName;
    }


    public void setUserName(String userName) {
        this.userName = userName;
    }


    public String getPassword() {
        return password;
    }


    public void setPassword(String password) {
        this.password = password;
    }


    /**
     * 
     */
    private static final long serialVersionUID = 1L;


    @Override
    public String execute() throws Exception {
        return loginService.doLogin(userName, password);
    }

}

  最终之类别结构:

图片 9

image.png

  现在始配备spring:在applicationContext中安排bean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.springframework.org/schema/beans" 
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">


    <bean id="loginService" class="com.xxx.service.LoginServiceImpl"/>

    <bean id="loginAction" scope="prototype" class="com.xxx.action.LoginAction">
        <property name="loginService" ref="loginService"></property>
    </bean>

</beans>

  修改struts配置文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
    <!-- <constant name="struts.objectFactory" value="spring" />
    <constant name="struts.devMode" value="true" /> -->
    <package name="xxx" extends="struts-default" namespace="/">
        <action name="login" class="loginAction">
            <result name="success">/WEB-INF/content/success.jsp</result>
            <result name="error">/WEB-INF/content/error.jsp</result>
        </action>
    </package>
</struts>    

首要的转变是:login这个action的class属性改化了以applicationContext中的id。这样action的实例的创造以至由spring来治本。
  到这里就截止了呢?当然不是,我们忘记了相同件重要的事。在做的历程遭到还要在一个至关重要的库struts2-spring-plugin-2.5.14.1.jar,加入方法或者拷贝到WEB-INF/lib下,并加入到build
path(注意:这个库房底本子一定要与struts的本相同,否则可能出错)。好了,到此虽可以运行程序了。如果在签到页面输入用户名xxx密码123456力所能及不负众望落实“登录”功能,那么做就着力落实了。
  以此地还补偿某些,如果仍刚才的配置,应该会并发一个ERRO,意思是说并未导入log4j。log4j这个保险背打印日志,对调试程序很有赞助。导入这个包也比较简单,首先导入log4j的jar包:

图片 10

image.png

log4j的担保和谐网上找一下,这里不多说。
下一场在src下开创log4j2.xml文书,用于配置log4j:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/2002/xmlspec/dtd/2.10/xmlspec.dtd">
<Configuration status="warn">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="[%-5p] %d %c - %m%n" />
        </Console>
        <File name="File" fileName="dist/my.log">
            <PatternLayout pattern="%m%n" />
        </File>
    </Appenders>

    <Loggers>
        <Logger name="mh.sample2.Log4jTest2" level="DEBUG">
            <AppenderRef ref="File" />
        </Logger>
        <Root level="INFO">
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>
</Configuration>  

重启应用,如果那个ERRO消失了,那么log4j就安排成功了,如果要来深错误,就设基于错误提示,检查错误可能是呀来头引起的。

整合Hibernate

  到这边真不容易,已经过半了,再坚持一下。该类型已经结合了spring+struts,现在以hibernate也结成进来就可怜功告成!
  首先还是下载hibernate,下载地址(http://hibernate.org/orm/releases/5.2/),点击最右的Download
zip archive下载。
  解压后用…\hibernate-release-5.2.12.Final\hibernate-release-5.2.12.Final\lib\required目录下的满贯jar包拷贝到WEB-INF/lib目录下,并且都加上到build
path中。
  将…\hibernate-release-5.2.12.Final\hibernate-release-5.2.12.Final\lib\optional\c3p0目录下之富有jar文件拷贝到WEB-INF/lib下,并上加都build
path。
  在这里,不要忘记了还有少数只待导入的jar包。一个是AspectJ包,下载地址:https://www.eclipse.org/aspectj/downloads.php。Spring的AOP需要借助是保险。另外一个是MySql的使JDBC
Driver for MySQL
,下载地址:https://www.mysql.com/products/connector/。
  安装MySql,此处不开相信说明,自行百度。
  以MySql的test数据库下开创tb_employee表,通过下的sql创建

CREATE TABLE `tb_employee` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `firstName` varchar(32) NOT NULL DEFAULT '',
  `lastName` varchar(32) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=105 DEFAULT CHARSET=utf8

  创建com.xxx.dao包,创建BaseDao接口:

package com.xxx.dao;

import java.io.Serializable;
import java.util.List;

public interface BaseDao<T> {

    /**
     * 根据实体加载数据
     * @param entityClazz
     * @param id
     * @return
     */
    T get(Class<T> entityClazz,Serializable id);
    /**
     * 保存实体
     * @param entity
     * @return
     */
    Serializable save(T entity);
    /**
     * 更新实体
     * @param entity
     */
    void update(T entity);
    /**
     * 删除实体
     * @param entity
     */
    void delete(T entity);
    /**
     * 根据ID删除实体
     * @param entityClazz
     * @param id
     */
    void delete(Class<T> entityClazz,Serializable id);
    /**
     * 获取所有实体
     * @param entityClazz
     * @return
     */
    List<T> findAll(Class<T> entityClazz);
    /**
     * 获取实体总数
     * @param entityClazz
     * @return
     */
    long findCount(Class<T> entityClazz);
}

  创建BaseDaoHibernate3

package com.xxx.dao;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;

public class BaseDaoHibernate3<T> implements BaseDao<T> {
    private SessionFactory sessionFactory;

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public T get(Class<T> entityClass, Serializable id) {
        return getSessionFactory().getCurrentSession().get(entityClass, id);
    }

    @Override
    public Serializable save(T entity) {
        SessionFactory sf = getSessionFactory();
        @SuppressWarnings("unused")
        Session s = sf.getCurrentSession();
        return getSessionFactory().getCurrentSession().save(entity);
    }

    @Override
    public void update(T entity) {
        getSessionFactory().getCurrentSession().update(entity);
    }

    @Override
    public void delete(T entity) {
        getSessionFactory().getCurrentSession().delete(entity);
    }

    @Override
    public void delete(Class<T> entityClass, Serializable id) {
        getSessionFactory().getCurrentSession()
                .createQuery("delet " + entityClass.getSimpleName() + " en where en.id=?0").setParameter(0, id)
                .executeUpdate();
    }

    @Override
    public List<T> findAll(Class<T> entityClass) {
        return (List<T>) find("select en from " + entityClass.getSimpleName() + " en");
    }

    @SuppressWarnings("unchecked")
    @Override
    public long findCount(Class<T> entityClass) {
        List<Long> list = (List<Long>) find("select count(*) from " + entityClass.getSimpleName() + " en");

        if (list != null && list.size() == 1) {
            return (long) list.get(0);
        }
        return 0;
    }

    /**
     * 分页查询
     * 
     * @param hql
     * @param pageNo
     * @param pageSize
     * @return
     */
    @SuppressWarnings("unchecked")
    protected List<T> findBypage(String hql, final int pageNo, final int pageSize) {
        List<T> list = getSessionFactory().getCurrentSession().createQuery(hql).setFirstResult((pageNo - 1) * pageSize)
                .setMaxResults(pageSize).list();

        return list;

    }

    /**
     * 带占位符的分页查询
     * 
     * @param hql
     * @param pageNo
     * @param pageSize
     * @param params
     * @return
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    protected List<T> findBypage(String hql, int pageNo, int pageSize, Object... params) {
        Query query = getSessionFactory().getCurrentSession().createQuery(hql);

        for (int i = 0; i < params.length; i++) {
            query.setParameter(i, params[i]);
        }
        return query.setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize).list();
    }

    @SuppressWarnings("unchecked")
    protected List<T> find(String hql) {
        return getSessionFactory().getCurrentSession().createQuery(hql).list();

    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    protected List<T> find(String hql, Object... paramas) {
        Query query = getSessionFactory().getCurrentSession().createQuery(hql);
        for (int i = 0; i < paramas.length; i++) {
            query.setParameter(i, paramas[i]);
        }

        return query.list();
    }
}

  创建BaseDaoHibernate4

package com.xxx.dao;

import java.io.Serializable;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.query.Query;
import org.springframework.orm.hibernate5.HibernateCallback;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

public class BaseDaoHibernate4<T> extends HibernateDaoSupport implements BaseDao<T>{



    @Override
    public T get(Class<T> entityClass, Serializable id) {
        return getHibernateTemplate().get(entityClass, id);
    }

    @Override
    public Serializable save(T entity) {
        return getHibernateTemplate().save(entity);
    }

    @Override
    public void update(T entity) {
        getHibernateTemplate().update(entity);
    }

    @Override
    public void delete(T entity) {
        getHibernateTemplate().delete(entity);
    }

    @Override
    public void delete(Class<T> entityClass, Serializable id) {
        getHibernateTemplate().delete(get(entityClass, id));
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<T> findAll(Class<T> entityClass) {
        return (List<T>) getHibernateTemplate().find("select en from " + entityClass.getSimpleName() + " en");
    }

    @SuppressWarnings("unchecked")
    @Override
    public long findCount(Class<T> entityClass) {
        List<Long> list = (List<Long>) getHibernateTemplate().find("select count(*) from " + entityClass.getSimpleName()+" en");

        if (list != null && list.size() == 1) {
            return (long) list.get(0);
        }
        return 0;
    }


    /**
     * 分页查询
     * 
     * @param hql
     * @param pageNo
     * @param pageSize
     * @return
     */
    @SuppressWarnings("unchecked")
    protected List<T> findBypage(final String hql,final int pageNo,final int pageSize) {
        List<T> list =  getHibernateTemplate().execute(new HibernateCallback<List<T>>() {

            @Override
            public List<T> doInHibernate(Session session) throws HibernateException {
                List<T> result = session.createQuery(hql).setFirstResult((pageNo - 1) * pageSize)
                .setMaxResults(pageSize).list();
                return result;
            }
        });

        return list;

    }

    /**
     * 带占位符的分页查询
     * 
     * @param hql
     * @param pageNo
     * @param pageSize
     * @param params
     * @return
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    protected List<T> findBypage(final String hql, final int pageNo, final int pageSize, final Object... params) {
        List<T> list = getHibernateTemplate().execute(new HibernateCallback<List<T>>() {

            @Override
            public List<T> doInHibernate(Session session) throws HibernateException {
                Query query = session.createQuery(hql).setFirstResult((pageNo - 1)*pageSize)
                        .setMaxResults(pageSize);

                for (int i = 0; i < params.length; i++) {
                    query.setParameter(i, params[i]);
                }
                 List<T> result = query.list();
                return result;
            }
        });
        return list;
    }
}

  创建实体类Employee

package com.xxx.dao;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "tb_employee")
public class Employee {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    @Column(name = "firstName")
    private String firstName;
    @Column(name = "lastName")
    private String lastName;

    public int getId() {
        return id;
    }

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

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

}

 emsp;创建EmployeeDao

package com.xxx.dao;

public interface EmployeeDao extends BaseDao<Employee>{

}

以此接口看似没有因此,其实暗藏玄机。如果EmployeeDao
有其一定的作业时,可以描绘在这个接口中,一方面满足面向接口编程的极,一方面还要无染BaseDao接口。
  创建EmployeeDaoHibernate

package com.xxx.dao;


public class EmployeeDaoHibernate extends BaseDaoHibernate3<Employee> implements EmployeeDao{

}

色结构截图:

图片 11

image.png

  BaseDaoHibernate3和BaseDaoHibernate4是少栽不同是兑现,更推荐前者,因为前端的代码污染更粗。
  现在来上加一个Action:EmployeeAction。用于应添加Employee请求。

package com.xxx.action;


import org.springframework.beans.factory.annotation.Autowired;

import com.opensymphony.xwork2.ActionSupport;
import com.xxx.dao.Employee;
import com.xxx.service.EmployeeService;

public class EmployeeAction extends ActionSupport {
    @Autowired
    private EmployeeService employeeService;
    private String firstName, lastName;
    private Employee employee;


    public Employee getEmployee() {
        return employee;
    }

    public void setEmployee(Employee employee) {
        this.employee = employee;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public EmployeeService getEmployeeService() {
        return employeeService;
    }

    public void setEmployeeService(EmployeeService employeeService) {
        this.employeeService = employeeService;
    }

    /**
     * 
     */
    private static final long serialVersionUID = -8442995807620521709L;

    @Override
    public String execute() throws Exception {
        Employee employee = new Employee();
//      System.out.println(firstName+lastName);
        employee.setFirstName(firstName);
        employee.setLastName(lastName);
        employeeService.add(employee);
//      System.out.println(id);
        return super.execute();
    }
}

  这个action中真的展开数量存储的是EmployeeService,于是就创建EmployeeService接口和落实类似,实现增长和沾两只方式:
EmployeeService

package com.xxx.service;

import java.io.Serializable;

import com.xxx.dao.Employee;

public interface EmployeeService {
    Serializable add(Employee employee);
    Employee get(Serializable id);
}

EmployeeServiceImpl

package com.xxx.service;

import java.io.Serializable;

import com.xxx.dao.Employee;
import com.xxx.dao.EmployeeDao;

public class EmployeeServiceImpl implements EmployeeService {
    private EmployeeDao employeeDao;



    public EmployeeDao getEmployeeDao() {
        return employeeDao;
    }

    public void setEmployeeDao(EmployeeDao employeeDao) {
        this.employeeDao = employeeDao;
    }

    public Serializable add(Employee employee) {
        return employeeDao.save(employee);
    }

    public Employee get(Serializable id) {
        return employeeDao.get(Employee.class, id);
    }

}

  好了,代码都写了,下面就来部署。
  首先配置applicationContext:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <!--基于 <tx> 和 <aop> 命名空间的声明式事务 -->
    <!-- 配置事务传播特性 -->
    <tx:advice id="TestAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="get*" read-only="true" />
            <tx:method name="*" isolation="DEFAULT" propagation="REQUIRED"
                timeout="5" />
        </tx:attributes>
    </tx:advice>

    <tx:annotation-driven />

    <!-- 配置参与事务的类 -->
    <aop:config>
        <aop:pointcut id="allTestServiceMethod" expression="bean(employeeService)" />
        <aop:advisor pointcut-ref="allTestServiceMethod"
            advice-ref="TestAdvice" />
    </aop:config>




    <!-- *********************************************************** -->

    <!-- hibernate 配置 -->
    <!-- 定义数据源bean 使用c3p0数据源 并注入相关参数 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close" p:driverClass="com.mysql.jdbc.Driver"
        p:jdbcUrl="jdbc:mysql://localhost/test?useSSL=false" p:user="root"
        p:password="194061" p:maxPoolSize="40" p:minPoolSize="2"
        p:initialPoolSize="2" p:maxIdleTime="30" />

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"
        p:dataSource-ref="dataSource">

        <!--annotateClasses用来列出所有持久化类 -->
        <property name="annotatedClasses">
            <list>
                <value>com.xxx.dao.Employee</value>
            </list>
        </property>

        <!-- 定义hibernate sessionFactory的属性 -->
        <property name="hibernateProperties">
            <props>
                <!-- 定义hibernate方言 -->
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                <!-- 是否根据hibernate映射创建数据表 -->
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
            </props>
        </property>
    </bean>
    <!-- ************************************************************* -->


    <bean id="employeeService" class="com.xxx.service.EmployeeServiceImpl"
        scope="prototype">
        <property name="employeeDao" ref="employeeDao"></property>
    </bean>

    <bean id="employeeDao" class="com.xxx.dao.EmployeeDaoHibernate">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>

    <bean id="employeeAction" scope="prototype" class="com.xxx.action.EmployeeAction">
        <property name="employeeService" ref="employeeService"></property>
    </bean>

    <bean id="loginService" class="com.xxx.service.LoginServiceImpl" />

    <bean id="loginAction" scope="prototype" class="com.xxx.action.LoginAction">
        <property name="loginService" ref="loginService"></property>
    </bean>

</beans>

  配置struts.xml文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
    <!-- <constant name="struts.objectFactory" value="spring" /> <constant name="struts.devMode" 
        value="true" /> -->
    <package name="xxx" extends="struts-default" namespace="/">
        <action name="login" class="loginAction">
            <result name="success">/WEB-INF/content/success.jsp</result>
            <result name="error">/WEB-INF/content/error.jsp</result>
        </action>

        <action name="employee" class="employeeAction">
            <result name="success">/WEB-INF/content/success.jsp</result>
            <result name="error">/WEB-INF/content/error.jsp</result>
        </action>
    </package>
</struts>    

  于login.jsp中补充加一个表单用于测试hibernate整合是否中标:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>My JSP 'login.jsp' starting page</title>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">

  </head>

  <body>
    <form action="login.action">
        用户名:<input type="text" name="userName"><br>
        密码: <input type="password" name="password"><br>
        <input type="submit" value="登录">
    </form>
  </body>
  <br>
  <form action="employee.action">
    FristName:<input type="text" name="firstName"/> <br>
    LastName:<input type="text" name="lastName"><br>
    <input type="submit" value="add">
  </form>
</html>

  到这边就做成了,最后之门类布局要图:

图片 12

image.png

图片 13

image.png

  启动服务器,输入firstName、lastName,点击add会跳反到成功页面,打开MySQL
Workbench查看tb_employee表的记录得观看就长的数据:

图片 14

image.png

末尾附上项目下载地址:https://github.com/xudefei/WebTest

相关文章

标签:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图