• SSH整合


    我这里使用的是spring4.2.2+struts2的 2.3.24+hibernate 5.0.7 进行的SSH整合

    注意: struts2和hibernate的核心jar包中都有一个jar包 版本不一样 叫javassist 这个会导致报错  需要删掉一个 

    导入jar包什么的就不说了 直接说说配置  首先spring配置文件

    <!-- 配置扫描包  我spring能使用注解 尽量都是使用注解 -->
    <context:component-scan base-package="包名"></context:component-scan>

    <!-- 配置数据源  我这里配的是C3P0连接池  -->
    <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="连接驱动类路径" />
    <property name="jdbcUrl" value="连接字符串"/>
    <property name="user" value="用户名"/>
    <property name="password" value="密码"/>
    </bean>

    <!-- 这里将原本hibernate的配置信息 全部整合到spring里面来了  -->

    <!-- 创建hibernate的session工厂对象 -->

    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <!-- 注入连接池 -->
    <property name="dataSource" ref="dataSource"/>

    <!-- 设置hibernate配置信息 -->
    <property name="hibernateProperties">
    <props>
    <!-- 设置hibernate连接数据库方言   我这里使用的是mysql -->
    <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
    <!-- 设置hibernate打印执行的sql语句 -->
    <prop key="hibernate.show_sql">true</prop>
    <!-- 设置hibernate将打印的sql语句格式化 -->
    <prop key="hibernate.format_sql">true</prop>
    <!-- 设置hibernate设置自动建表 -->
    <prop key="hibernate.hbm2ddl.auto">update</prop>
    </props>
    </property>


    <!-- 引入映射文件 -->
    <property name="mappingResources">
    <list>
    <value>src目录下的映射文件的路径  如果多个映射文件就添加多个value标签即可  </value>
    </list>
    </property>
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <!-- 配置 事务管理 开始(事务感觉使用xml配置之后比使用注解方便 不用一个一个去加那个注解)-->
    <!-- 配置通知 -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
    <tx:method name="query*" read-only="true"/> <!-- query开头的任意方法 为只读方法 提高性能 -->
    <tx:method name="*" rollback-for="java.lang.Exception"/>
    </tx:attributes>
    </tx:advice>
    <!-- 配置切面 -->
    <aop:config>
    <aop:pointcut expression="execution(* com.包名.包名..*(..))" id="pointcut"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
    </aop:config>
    <!-- 配置 事务管理 结束-->

    由于所有dao实现类都直接或间接继承了HibernateDaoSupport类 使用这个类的HibernateTemplate对象操作数据库  要注入sessionFactory实例才能操作数据库

    但是这个类不是自己编写的  只能通过xml方式 交给spring管理 才能注入sessionFactory实例

    <bean name="userDao" class="完整类名">
    <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>

    我已经将hibernate的配置已经整合到了spring配置文件中 然后struts2的action也是要交给spring管理了 

    只需要在action类上加这两个注解

    @Controller("action简短类名首字母小写 比如UserAction 就是 userAction 其实也可以随便取 在struts2的配置中要用到这个名字")
    @Scope("prototype") 

     这个是设置bean的作用域  设置为这个值 代表每一次spring都会创建一个新的实例 默认是只有一个实例 因为action是多例的 每次请求都是一个新的实例 不写会报错 有问题

    然后在struts2配置文件中 配置action时 class属性的值就是action类上@Controller()注解里面的值  剩下struts2的所有配置和正常使用没区别

    --------------------------------------------------------------------------------

    框架的配置文件说完了  在说一下web.xml的配置

    <!-- 配置Spring的核心监听器 -->
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- 容器初始化加载spring配置文件 -->
    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring配置文件路径</param-value>
    </context-param>

    <!-- 解决hibernate延迟加载 由于session已关闭 无法查询关联对象值

    因为hibernate默认查询一个对象,有关联对象时是生成代理对象 而不是立即发送语句查询 这是为了提高性能 只有实际使用这个对象时 才会立即去查

    但是hibernate默认在dao层操作完数据库就关闭了session连接 那么在其他地方 使用到关联对象 想去查询时 session已关闭 就会报错 

    -->
    <filter>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <url-pattern>*.action</url-pattern>
    </filter-mapping>

    <!-- Struts2的核心过滤器 -->
    <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>

    web.xml配置基本上就这些

    ----------------------------------------------------------

    由于hibernate是自动化很高的orm框架 可以定义一个通用的dao接口 有通用的增删改查方法 其他的dao接口只需要继承这个接口 就有了这些方法

    然后其他dao接口的实现类 在继承这个通用dao接口的实现类  就实现了如果只是基本的增删改查 不需要单独写方法

    接下来上代码

     1 /**
     2  * 通用基础dao接口 
     3  * 可以实现增删改和根据id查询 和分页查询
     4  * 
     5  * */
     6 public interface BaseDao<T> {
     7     
     8     //通用保存方法
     9     public Integer save(T t);
    10     
    11     //通用修改方法
    12     public void update(T t);
    13     
    14     //通用删除方法
    15     public void delete(T t);
    16     
    17     //通用根据主键查询方法
    18     public T queryByID(Serializable id);
    19     
    20     //通用 查询全部方法
    21     public List<T> queryAll();
    22 
    23     
    24     //通用 查询总记录数 配合分页查询使用
    25     public Integer queryRowCount(DetachedCriteria dc);
    26     
    27     //通用分页查询方法 参1:离线条件查询对象  参2:自定义的分页帮助类
    28     public void queryPage(DetachedCriteria dc,Pagination p);
    29     
    30     
    31     
    32     
    33 }

    因为hibernate增删改方法都是传入具体要操作的实体类的对象  所以只能使用泛型 

    接下来就是dao接口的实现类

    public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
    
        //定义这个属性 从无参构造方法中 获得实际要进行操作实体类的class对象
        private Class clazz;
        
        /**
         * 在这个构造方法中 获得继承这个类的子类,上写的泛型的实际类型
         * 例如  UserDaoImpl extends BaseDaoImpl<User>
         * 就是要获得这个泛型的实际类型  这个User
         * */
        public BaseDaoImpl() {  
        //子类实例化时,会调用父类构造方法,通过this指向的就是子类的对象,得到了子类的class对象
        Class child=this.getClass();
        
        //获得父类的泛型参数对象
     ParameterizedType type =(ParameterizedType) child.getGenericSuperclass();
        
         //获得泛型对象的实际类型 由于泛型可以有多个参数 例如 Map<String,Object>
        //所以返回得是数组 取出第一个 强转成Class对象 赋值给属性  就得到了实际操作的实体类的class
      this.clazz= (Class)type.getActualTypeArguments()[0];
        
            
        }
    
        public Integer save(T t) {
            return (Integer)this.getHibernateTemplate().save(t);
        }
    
        public void update(T t) {
            this.getHibernateTemplate().update(t);
        }
    
        public void delete(T t) {
            this.getHibernateTemplate().delete(t);
        }
    
        public T queryByID(Serializable id) {
            return (T)this.getHibernateTemplate().get(clazz, id);
        }
    
        public List<T> queryAll() {
            return (List<T>)this.getHibernateTemplate().find("from "+clazz.getSimpleName());
        }
    
        public Integer queryRowCount(DetachedCriteria dc) {
            
            dc.setProjection(Projections.rowCount());//设置离线条件查询对象执行count聚合函数
            
            List list = this.getHibernateTemplate().findByCriteria(dc);//执行查询
            
            return list.size()>0?((Long)list.get(0)).intValue():0;
        }
    
        public void queryPage(DetachedCriteria dc, Pagination p) {
            
           dc.setProjection(null);//离线条件查询对象,刚刚执行聚合函数操作,设置为null代表 不使用聚合函数
            
            //执行查询  参数1:离线条件查询对象,参数2:查询记录的起始索引,参3:查询几条记录
            List list = this.getHibernateTemplate().findByCriteria(dc, (p.getCurrentPage()-1)*p.getPageSize(), p.getPageSize());
           
            p.setList(list);
        }
    
    }

    这个实现类核心就在无参构造方法  子类实现这个类以后  实例化 调用父类的构造方法  就可以得到子类泛型上的具体类型 然后赋值给父类中的class对象

    得到了class对象 就可以实现查询了

    演示使用

    public interface UserDao extends BaseDao<User> {
         
    }

    UserDao接口继承了通用dao接口 并且设置了实际的类型

    这时候Userdao接口就有了通用的增删改查方法

    public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao {
    
        
    
    }

    UserDao的实现类  继承了通用dao接口的实现类  并且实现了UserDao接口

    这个时候如果只要使用基本的增删改查方法 在UserDaoImpl中不需要写额外的方法

    这一点还是很方便的  mybatis就做不到

    我把我自己用的分页帮助类也发上来吧

    public class Pagination {
        private List list;
        private int currentPage=1;//当前页码
        private int pageSize=3;//每页个数
        private int rowCount;//总记录数
        public List getList() {
            return list;
        }
        public void setList(List list) {
            this.list = list;
        }
        public int getCurrentPage() {
            return currentPage;
        }
        public void setCurrentPage(int currentPage) {
            this.currentPage = currentPage;
        }
        public int getPageSize() {
            return pageSize;
        }
        public void setPageSize(int pageSize) {
            this.pageSize = pageSize;
        }
        public int getRowCount() {
            return rowCount;
        }
        public void setRowCount(int rowCount) {
            this.rowCount = rowCount;
        }
        
        public int getStartPage(){ //第一页
            return 1;
        }
        public int getEndPage(){ //最后一页
            return this.getPageCount();
        }
        public int getPageCount(){ //总页数
            return this.rowCount%this.pageSize==0?this.rowCount/this.pageSize:this.rowCount/this.pageSize+1;
        }
        public int getprevPage(){//上一页
            return this.currentPage>1?this.currentPage-1:1;
        }
        public int getnextPage(){//下一页
            return this.currentPage==getEndPage()?getEndPage():this.currentPage+1;
        }
    
    }

    SSH整合 基本上就这么多东西 

  • 相关阅读:
    交换排序:冒泡排序vs快速排序
    SSO
    MVC源码分析
    python_正则表达式概述
    (爬虫向)python_json学习笔记
    Pycharm Debug调试心得
    HTML学习二_HTML常用的行级标签,常用实体字符及表单标签
    吴恩达机器学习笔记3-代价函数II(cost function)
    吴恩达机器学习笔记2-代价函数I(cost function)
    Python面向对象1:类与对象
  • 原文地址:https://www.cnblogs.com/java888/p/10848760.html
Copyright © 2020-2023  润新知