通向架构师的道路(第二十一天)万能框架spring(三)之SSH

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 一、前言我们有了Spring+JdbcTemplate和Spring+iBatis并结合maven的基础,搭建一个SSX这样的框架现在就和玩一样的简单了,今天我们将搭建一个使用Struts1.3,Srping3, Hibernate3的SSH1的开发框架,大家跟着我一步步走,会发觉在程序跑通后自己再动手搭建一遍这个框架,只需要30分钟。

一、前言

我们有了Spring+JdbcTemplate和Spring+iBatis并结合maven的基础,搭建一个SSX这样的框架现在就和玩一样的简单了,今天我们将搭建一个使用Struts1.3,Srping3, Hibernate3的SSH1的开发框架,大家跟着我一步步走,会发觉在程序跑通后自己再动手搭建一遍这个框架,只需要30分钟。

二、SSH框架


仔细看这个框架,稍微有点不一样了。

1)      Spring3是通过一个hibernate template来和hibernate的dao层结合起来并且管理起hibernate的相关事务的。因此我们自己写了一个BaseHibernateDaoSupport来用spring统一管理hibernate的事务。

2)      Hibernate和Spring的结合非常方便,我们只需要写一个hibernate.xml就可以了,datasource.xml中把原先的iBatis的相关配置全部去掉它,什么都不需要加事务还是维持原有的配置不变即可,对于我们来说需要改动的是dao层,还有把service层稍微做些小调整(一两句话的调整,非常简单),可能是我看到过的最简单的一种SSX的结合方式,远比iBatis和spring的结合要easy多了。

3)      Hibernate3开始可以使用jpa或者还是传统的hbm.xml文件这样的描述方式,在此我们坚持使用JPA的Annotation方式来声明我们的model而不是使用*.hbm.xml这样的方式。

注意:所有的包(package name)都要从原来的org.sky.ssi变成org.sky.ssh喽?

三、搭建SSH框架

3.1建立工程

我们还是使用maven来建立我们的工程,我们工程的名字叫myssh。



建完后照着翻外篇《第十九天》中的“四、如何让Maven构建的工程在eclipse里跑起来”对工程进行设置。



3.2 maven库设置

嘿嘿嘿嘿,不需要任何设置,直接把beta工程中的pom.xml文件拷贝入myssh工程中就可以用了,里面相关的spring,struts, hibernate的包我都已经事先配合了。

如果你是个图完美的的,你可以把pom.xml文件中的iBatis相关的jar给去除。

3.3 开始配置Hibernate与spring结合

打开/src/main/resources/spring/datasource下的datasource.xml,把所有的关于iBatis的设置全部去除,把org.sky.ssi这样的包名全部改成org.sky.ssh。

我们在myssh工程中需要增加一个工具类,一个xml和几个用到的hibernate的model的映射,下面来看。

src/main/resources/spring/hibernate/hibernate.xml文件

我们在src/main/resources/spring目录下增加一个目录叫hibernate,在这个hibernate目录下我们创建一个hibernate.xml文件。



其内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

                        xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                        xsi:schemaLocation="

       http://www.springframework.org/schema/beans

       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

                           http://www.springframework.org/schema/beans

                           http://www.springframework.org/dtd/spring-beans.dtd

">

          <bean id="hibernateSessionFactory"

                 class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">

                  <property name="packagesToScan" value="org.sky.ssh.dao.impl.*.*" />

                   <property name="dataSource">

                       <ref bean="dataSource" />

                   </property>

                   <property name="annotatedClasses">

                        <list>

                                <value>org.sky.ssh.model.TLogin</value>

                                 <value>org.sky.ssh.model.TStudent</value>                                                                                           

                       </list>

                    </property>

                       <property name="hibernateProperties">

                       <props>

                               <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>

                               <prop key="hibernate.show_sql">true</prop>

                               <prop key="hibernate.generate_statistics">true</prop>

                               <prop key="hibernate.connection.release_mode">auto</prop>

                               <prop key="hibernate.autoReconnect">true</prop>

                               <prop key="hibernate.hbm2ddl.auto">update</prop>

                                <prop key="hibernate.connection.autocommit">true</prop>

                        </props>

                    </property>

             </bean>

</beans>

<property name="packagesToScan"value="org.sky.ssh.dao.impl.*.*" />

这句就是代表所有的hibernate的sessionFactory自动被注入到我们的myssh工程的dao层中去,即在dao层中我们只要通过BaseHibernateDaoSupport.getSession()就可以进行相关的hibernate的数据库操作了.

我们还注意到了在src/main/resources/spring/hibernate/hibernate.xml文件中有这样的hibernate的model的映射:

<property name="annotatedClasses">

           <list>

                    <value>org.sky.ssh.model.TLogin</value>

                    <value>org.sky.ssh.model.TStudent</value>                                                       

           </list>

</property>

这就是基于annotation的jpa的hibernate的model层的写法,这边的几个<value>括起来的东西就是一个个java的.class,这些java文件都是基于jpa的annotation写法。

当然,如果表结构简单,你可以直接手写这些java类,但是如果一个表结构很复杂,几十个字段主键还有组合主键这样的形式存在,那么手写这个jpa就会变得有点困难。

一般我们在开发项目时都是通过先建表,再建类的,对吧?

因此在这里我们其实是可以借助相关的工具通过数据库表来生成我们的hibernate的这些model类的。

利用eclipse从表逆向生成java的jpa(hibernate)类

准备工做

1.       必须要有eclipse3.7及升级后的database, jpa feature,如:eclipse wtp版

2.       建立数据源

根据下面操作,请切换到j2ee视图,然后先打开datasource explorer窗口




下一步


点右上面这个黑白色(黑白配,男生女生配,啊我呸!)的圆形pie一样的这个按钮

填入自定义的oracledriver名

点JARList这个tab(需要加载一个oracle的driver,即ojdbc6.jar)


可以去oracleclient端安装的路径的jdbc\lib中找到该JAR,注意上图中两个红圈处标出的路径与jar名

点OK返回下面这个对话框


填入servername, username, password等信息,你懂的(别忘了勾上save password


选TestConnection


点OK,NEXT, FINISH完成

看,这边一下子把所有的schema都列出来了,但是我们知道oracle的schema就是username,因此我们用bookstore(这个只是示例,这边因该用你连接数据库的username)的schema只需要显示bookstore的相关数据库object就够我们用了。



看,右键点击你的connection选Properties然后在下面的对话框中选DefaultSchema Filter


在上面的对话框中把Disablefilter放开,然后在Startswith the characters填入你的oracle用户名(schema名),必须大写

点OK

返回后右键点connection选Refresh,看,是不是只列出来就是你要的东西了(相当于pl/sql里从all objects切换成my objects


这个东西还可以在没有安装oracle客户端的情况下,拿ECLIPSE来当oracle的客户端用。

建立JPA(Hibernate)工程

在hibernate3里我们把hibernate的annoation方式称为全注解即JPA,因此我们不需要使用hibernate3以前的那种xml文件的配置的方式。

新建JPA工程



这边我们使用的工程名为myssh_model

工程名起名规范,比如说你的工程叫MyProject,那么你的HIBERNATE是ForMyProject工程的,因此你的hibernate即JPA工程就应该叫MyProject_model

根据上图勾选后NEXT,NEXT到下面这一步(千万不要手快然后直接去点那个FINISH按钮啊,我们还没完呢)


根据上图勾选

点FINISH


在弹出框时选Yes


生成的JPA工程


右键单击工程,在JPATools里选GenerateEntities from Tables,这个你懂的。。。

下面,灵的东西要来了。。。


点一下Connection下的这个有“黄色铰链”的按钮(connection),这时下方的下拉列表会显示你当前的jpa工程使用的dbconnection中的Table,看到米有?


注意,把这个Updateclass list in persistence.xml去掉,因为我们用的是纯annotation,不希望再用xml配置方式了,要不然生成出来的工程会出错的,点Next


如果表与表之间有foreignkey的关系,它都能帮你识别出来

Next


保持所有的CLASS的主键为none,我们在后面为每个表分别指定主键的形势,因为有些主键是用的是sequence,有的主键是要通过界面手输进来的,不是sequence,有的主键甚至是复合主键。

别忘了把package填上,注意package的命名规范(规则)养成良好习惯

点NEXT

下面为每个CLASS指定主键的生成方式。

对于T_LOGIN表来说我们的PK让它保持为默认。

对于T_STUDENT表来说,我们的主键是用一个oracle的 sequence来生成的,这个oracle的sequence命为:


因此当你为一个jpa指定了sequence的PK时,在做插入动作时,该表的PK会自动从在这一步指定的sequence中去读取nextval值,相当于执行了一步:select  SEQ_STUDENT_NO.nextval from dual;这样的操作.


把每个JPA的主键指定完毕后可以点Finish了


Look,快来看上帝哦,JPA类被自动生成了,但编译有问题,因为我们没有给工程指定lib包,jpa工程需要用到以下lib包


我已经同时上传到我的博客的资源上了。

于是,在工程下建一个文件夹叫lib,把这些jar全放lib目录里然后加入classpath


编译通过后,我们就可以把这些java拷入我们需要用到hibernate工程的project里了,拷进去后别忘了改一处地方:

以下是我原有工程中有一个jpa,因此我在spring/hibernate/hibernate.xml文件中需要把一个jpa纳入spring的管理,但现在我拷进去一堆jpa都要纳入spring管理,怎么办?就是把这个文件打开,找到

<property name=”annotatedClasses”>处

然后看到<List><value>了吗?自己把一个个JPA加进去吧,然后就可以去爽了。

 

<property name="annotatedClasses">

                <list>

                                <value>org.sky.ssh.model.TLogin</value>

                                <value>org.sky.ssh.model.TStudent</value>                                                 

                </list>

</property>

org.sky.ssh.dao.BaseHibernateDaoSupport.java文件

package org.sky.ssh.dao;

 

import javax.annotation.Resource;

import org.hibernate.SessionFactory;

 

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class BaseHibernateDaoSupport extends HibernateDaoSupport {

                @Resource(name = "hibernateSessionFactory")

                public void setSF(SessionFactory sessionFactory) {

                                super.setSessionFactory(sessionFactory);

                }

}

四、SSH框架的使用

我们现在可以开始使用我们的SSH框架了。

4.1修改DAO层代码

org.sky.ssh.dao.LoginDAO

package org.sky.ssh.dao;

 

 

public interface LoginDAO {

                public long validLogin(String loginId, String loginPwd) throws Exception;

}

 

org.sky.ssh.dao.impl.LoginDAOImpl

package org.sky.ssh.dao.impl;

 

import org.sky.ssh.dao.BaseHibernateDaoSupport;

import org.sky.ssh.dao.LoginDAO;

import org.springframework.stereotype.Repository;

import org.hibernate.Query;

 

@Repository

public class LoginDAOImpl extends BaseHibernateDaoSupport implements LoginDAO {

 

                public long validLogin(String loginId, String loginPwd) throws Exception {

                                Long count = new Long(0);

                                String sql = "select count(tl.loginId) from TLogin as tl where tl.loginId=:loginId and tl.loginPwd=:loginPwd ";

                                Query query = super.getSession().createQuery(sql);

                                query.setString("loginId", loginId);

                                query.setString("loginPwd", loginPwd);

                                count = (Long) query.list().get(0);

                                return count;

                }

 

}

org.sky.ssh.dao.StudentDAO

package org.sky.ssh.dao;

 

import org.sky.ssh.model.TStudent;

import org.sky.ssh.dbo.StudentDBO;

import org.sky.ssh.student.form.*;

import java.util.*;

 

public interface StudentDAO {

 

                public List<TStudent> getAllStudent() throws Exception;

 

                public void addStudent(String studentName) throws Exception;

 

                public void delStudent(TStudent std) throws Exception;

}

org.sky.ssh.dao.impl.StudentDAOImpl

package org.sky.ssh.dao.impl;

 

import java.util.ArrayList;

import java.util.List;

 

import org.hibernate.Query;

import org.sky.ssh.dao.BaseHibernateDaoSupport;

import org.sky.ssh.dao.StudentDAO;

import org.sky.ssh.model.TStudent;

import org.springframework.stereotype.Repository;

 

@Repository

public class StudentDAOImpl extends BaseHibernateDaoSupport implements StudentDAO {

 

                public List<TStudent> getAllStudent() throws Exception {

                                List<TStudent> stdList = new ArrayList<TStudent>();

                                String sql = "from TStudent as s";

                                Query query = super.getSession().createQuery(sql);

                                stdList = query.list();

                                return stdList;

                }

 

                public void addStudent(String studentName) throws Exception {

                                TStudent std = new TStudent();

                                std.setStudentName(studentName);

                                this.getHibernateTemplate().save(std);

                }

 

                public void delStudent(TStudent std) throws Exception {

                                this.getHibernateTemplate().delete(std);

                }

}

对Service层的接口作相应的调整,把原来在iBatis中使用Map传值的地方改一下即可,对吧?

Hibernate的DAO是我看到过的最简单的DAO写法,连脑子都不需要多动。

 

4.2 启动我们的框架

确保我们的StudentServiceImpl类中有如下语句:

public void delStudent(String[] stdNo) throws Exception {

                                for (String s : stdNo) {

                                                TStudent std = new TStudent();

                                                std.setStudentNo(Long.parseLong(s));

                                                studentDAO.delStudent(std);

                                                throw new Exception("force system to throw a exception");

                                }

}

在eclipse中启动tomcat


在IE中输入:http://localhost:8080/myssh/,页面自动跑到登录界面


输入alpha/aaaaaa登录成功后我们增加两个用户:test2与test3




在主界面上勾选test2与test3点删除按钮。

页面出错


看数据库层面


数据记录还在,说明我们的springservice层与hibernatedao层已经结合成功。

在StudentServiceImpl类中将:throw new Exception("force system to throw a exception");这句注释掉.


重新启动tomcat后登录并勾选test2与test3,然后点删除按钮.


删除成功。

查看数据库层记录


数据删除也成功了,结束今天的教程。

五、附录

Hibernate的dialect大全

DB2

org.hibernate.dialect.DB2Dialect

DB2 AS/400

org.hibernate.dialect.DB2400Dialect

DB2 OS390

org.hibernate.dialect.DB2390Dialect

PostgreSQL

org.hibernate.dialect.PostgreSQLDialect

MySQL

org.hibernate.dialect.MySQLDialect

MySQL with InnoDB

org.hibernate.dialect.MySQLInnoDBDialect

MySQL with MyISAM

org.hibernate.dialect.MySQLMyISAMDialect

Oracle (any version)

org.hibernate.dialect.OracleDialect

Oracle 9i/10g

org.hibernate.dialect.Oracle9Dialect

Sybase

org.hibernate.dialect.SybaseDialect

Sybase Anywhere

org.hibernate.dialect.SybaseAnywhereDialect

Microsoft SQL Server

org.hibernate.dialect.SQLServerDialect

SAP DB

org.hibernate.dialect.SAPDBDialect

Informix

org.hibernate.dialect.InformixDialect

HypersonicSQL

org.hibernate.dialect.HSQLDialect

Ingres

org.hibernate.dialect.IngresDialect

Progress

org.hibernate.dialect.ProgressDialect

Mckoi SQL

org.hibernate.dialect.MckoiDialect

Interbase

org.hibernate.dialect.InterbaseDialect

Pointbase

org.hibernate.dialect.PointbaseDialect

FrontBase

org.hibernate.dialect.FrontbaseDialect

Firebird

org.hibernate.dialect.FirebirdDialect

 





相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
27天前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
11天前
|
存储 分布式计算 关系型数据库
架构/技术框架调研
本文介绍了微服务间事务处理、调用、大数据处理、分库分表、大文本存储及数据缓存的最优解决方案。重点讨论了Seata、Dubbo、Hadoop生态系统、MyCat、ShardingSphere、对象存储服务和Redis等技术,提供了详细的原理、应用场景和优缺点分析。
|
1月前
|
人工智能 前端开发 JavaScript
前端架构思考 :专注于多框架的并存可能并不是唯一的方向 — 探讨大模型时代前端的分层式微前端架构
随着前端技术的发展,微前端架构成为应对复杂大型应用的流行方案,允许多个团队使用不同技术栈并将其模块化集成。然而,这种设计在高交互性需求的应用中存在局限,如音视频处理、AI集成等。本文探讨了传统微前端架构的不足,并提出了一种新的分层式微前端架构,通过展示层与业务层的分离及基于功能的横向拆分,以更好地适应现代前端需求。
|
1月前
|
存储 分布式计算 API
大数据-107 Flink 基本概述 适用场景 框架特点 核心组成 生态发展 处理模型 组件架构
大数据-107 Flink 基本概述 适用场景 框架特点 核心组成 生态发展 处理模型 组件架构
85 0
|
16天前
|
监控
SMoA: 基于稀疏混合架构的大语言模型协同优化框架
通过引入稀疏化和角色多样性,SMoA为大语言模型多代理系统的发展开辟了新的方向。
29 6
SMoA: 基于稀疏混合架构的大语言模型协同优化框架
|
1月前
|
Java Spring
Spring底层架构源码解析(三)
Spring底层架构源码解析(三)
113 5
|
1月前
|
XML Java 数据格式
Spring底层架构源码解析(二)
Spring底层架构源码解析(二)
|
1月前
|
Java 数据库连接 数据库
让星星⭐月亮告诉你,SSH框架01、Spring概述
Spring是一个轻量级的Java开发框架,旨在简化企业级应用开发。它通过IoC(控制反转)和DI(依赖注入)降低组件间的耦合度,支持AOP(面向切面编程),简化事务管理和数据库操作,并能与多种第三方框架无缝集成,提供灵活的Web层支持,是开发高性能应用的理想选择。
38 1
|
1月前
|
JSON 前端开发 Java
Spring Boot框架中的响应与分层解耦架构
在Spring Boot框架中,响应与分层解耦架构是两个核心概念,它们共同促进了应用程序的高效性、可维护性和可扩展性。
53 3
|
13天前
|
缓存 负载均衡 JavaScript
探索微服务架构下的API网关模式
【10月更文挑战第37天】在微服务架构的海洋中,API网关犹如一座灯塔,指引着服务的航向。它不仅是客户端请求的集散地,更是后端微服务的守门人。本文将深入探讨API网关的设计哲学、核心功能以及它在微服务生态中扮演的角色,同时通过实际代码示例,揭示如何实现一个高效、可靠的API网关。
下一篇
无影云桌面