记录自己的学习之旅(SSH框架篇)

@记录自己的学习之旅(SSH框架篇)

SSH框架

SSH是一个集成框架,主要有三个基础框架整合而成,也就是我们常说的Spring+Struts+Hibernate。
通过SSH框架,我们可以将系统分为表示层,业务层和数据持久层。其中Struts作为SSH的一个基础框架,起到MVC分层架构的作用,Hibernate则是我们与数据进行交互的一条通道,为持久层提供支持,Spring则是担任一个管理者的角色。

如何搭建一个SSH框架

SSH整合整合步骤
利用Spring整合Hibernate导包
配置applicationContext.xml
创建实体类和映射关系文件
创建DAO接口及实现类
声明DAO组件,注入SessionFactory
利用Spring整合Struts2导包
配置web.xml
配置applicationContext.xml
创建并声明Action
配置Action,创建JSP

一、Spring整合Hibernate

1、导包

创建一个WEB项目SSH_Day01,并导入数据库驱动包,Hibernate开发包以及Spring开发包。我这边直接从官网下的Hibernate和Spring的开发包,导入了里面的jar包,同时导入对应数据的驱动包和测试需要使用的jar包。

2、配置applicationContext.xml

在Java Resorces目录下我们建立一个resouce目录存放对应的配置文件。
在这里插入图片描述

2.1 配置数据源
<!-- 加载配置文件 -->
	<context:property-placeholder location="classpath:dbconfig.properties" />
    <!-- 配置数据源 -->
	<bean id="ds" class="com.mchange.v2.c3p0.ComboPooledDataSource"        
        destroy-method="close">
    <!-- 配置连接参数 -->           
    <property name="driverClass" value="${jdbc.driver}"/>       
    <property name="jdbcUrl" value="${jdbc.url}"/>       
    <property name="user" value="${jdbc.username}"/>       
    <property name="password" value="${jdbc.password}"/> 
    <!-- 配置连接池 -->
    <property name="initialPoolSize" value="3"/>
    <property name="maxPoolSize" value="10"/>
    <property name="minPoolSize" value="1"/>
    <!-- acquireIncrement:当连接池中的连接用完时,C3P0一次性创建新连接的数目 -->
    <property name="acquireIncrement" value="3"/>
    <!-- maxIdleTime:最大空闲时间,超过空闲时间的连接将被丢弃。为0或负数则永不丢弃。默认为0-->
    <property name="maxIdleTime" value="60"/>
    </bean>

我这里用的是Oracle的数据库,对应的连接配置文件如下:

   jdbc.driver=oracle.jdbc.driver.OracleDriver
   jdbc.url=jdbc:oracle:thin:@localhost:1521:orcl
   jdbc.username=zyq
   jdbc.password=1234
2.2 配置SessionFactory
<!-- 配置SessionFactory -->
    <bean id = "SessionFactory" class = "org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    	<!-- 依赖数据源 -->
    	<property name="dataSource" ref= "ds"/>
    	<!-- Hibernate框架相关配置 -->
    	<property name="hibernateProperties">
    		<props>
    			<prop key="hibernate.dialect">
    				org.hibernate.dialect.OracleDialect
    			</prop>
    			<!-- 在控制台输出sql -->
    			<prop key="hibernate.show_sql">true</prop>
    			<!-- 将sql格式化,然后再输出 -->
    			<prop key="hibernate.formate_sql">true</prop>
    		</props>
    	</property>
    </bean>

这边dialect就是“方言”,因为hibernate是要把Java对象转换成关系数据库来描述的,而关系数据库虽然有一些统一的标准,但是各个数据库之间还是有不同的地方,我们用这种方式将它里面将不同数据类型、SQL语法转换成hibernate能理解的统一的格式。

2.3 配置注解扫描和事务管理
<!-- 开启注解扫描 -->
    <context:component-scan base-package="com.*"/>
    
    <!-- 声明式事务管理,采用AOP形式切入 -->
    <bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    	<property name="sessionFactory" ref="SessionFactory"/>
    </bean>
    <!-- 通知 -->
	<tx:advice id="txAdvice" transaction-manager="txManager">
		<tx:attributes>
			<!-- 传播行为 -->
			<tx:method name="save*" propagation="REQUIRED" />
			<tx:method name="insert*" propagation="REQUIRED" />
			<tx:method name="add*" propagation="REQUIRED" />
			<tx:method name="create*" propagation="REQUIRED" />
			<tx:method name="delete*" propagation="REQUIRED" />
			<tx:method name="update*" propagation="REQUIRED" />
			<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="select*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
		</tx:attributes>
	</tx:advice>
	<!-- 切面 -->
	<aop:config>
		<aop:advisor advice-ref="txAdvice"
			pointcut="within(com.*.*)" />
	</aop:config>

3 创建实体类和映射关系文件

3.1 创建实体类

在src目录下,新建一个entity包用于存放我们的实体类,这里我创建了一个User类,这个大家可以随便建立。
在这里插入图片描述
对应的User类代码如下

package com.entity;

public class User {
    private Integer id;
    
    private String card;

	private String username;

    private String password;

    private String company;

    private Integer age;

    private Integer sex;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
		this.id = id;
	}
    
    public String getCard() {
		return card;
	}

	public void setCard(String card) {
		this.card = card;
	}
    
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username == null ? null : username.trim();
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password == null ? null : password.trim();
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company == null ? null : company.trim();
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getSex() {
        return sex;
    }

    public void setSex(Integer sex) {
        this.sex = sex;
    }
}
3.2 创建映射关系文件

一般每个实体类都有自己的映射文件,并使用XXX.hbm.xml的形式来命名,“XXX”既是持久化类名,并且持久化类与其映射文件放在同一目录下。这里我建立了User.hbm.xml文件。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

    <class name="com.entity.User" table="user_test">
        <id name="id" type="integer" column="id">
			<!-- 用来指明主键的生成方式 -->
			<generator class="sequence">
				<param name="sequence">seq_user_test</param>
            </generator>
        </id>
        <property name="card" type="string" column ="usr_id"/>
        <property name="username" type="string" column ="usr_nam"/>
        <property name="password" type="string" column ="pwd"/>
        <property name="company" type="string" column ="company"/>
        <property name="age" type="integer" column ="age"/>
        <property name="sex" type="integer" column ="sex"/>
    </class>

</hibernate-mapping>  

这里hibernate-mapping是XXX.hbm.xml配置文件的根节点;
class中属性含义
name :实体类名,默认要写类全名,若配置了hibernate-mapping节点的package属性则可以只写类名。
table :此实体类对应的数据库表名。

id中属性含义
name :实体类属性名,用做数据库表主键的成员变量。
type :数据库字段类型。
column :数据库主键字段。

generator中属性含义
class :用于指定主键的生成方式
sequence:适用于代理主键,Hibernate根据底层数据库的序列来生成标识符。这里用的序列是在对应数据库里建立的。

property中属性含义
name :实体类属性名。
type :数据库字段类型。
column :数据库对应字段。

3.3 在配置文件中注册映射关系文件
<!-- 配置SessionFactory -->
    <bean id = "SessionFactory" class = "org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    	<!-- 依赖数据源 -->
    	<property name="dataSource" ref= "ds"/>
    	<!-- Hibernate框架相关配置 -->
    	<property name="hibernateProperties">
    		<props>
    			<prop key="hibernate.dialect">
    				org.hibernate.dialect.OracleDialect
    			</prop>
    			<prop key="hibernate.show_sql">true</prop>
    			<prop key="hibernate.formate_sql">true</prop>
    		</props>
    	</property>
    	
    	<!-- 注册映射文件 -->
    	<property name="mappingResources">
    		<list>
    			<value>com/entity/User.hbm.xml</value>
    		</list>
    	</property>
    </bean>

4、创建DAO接口及实现类

创建包com.dao,在包里新建一个UserDao接口,声明增删改查的方法。

package com.dao;

import java.util.List;
import com.entity.User;

/**
 * 
 * @author Mr.ZOU
  *  实现对User表的增删改查的接口
 */

public interface UserDao {
	//查找所有数据
	List<User> findAll();
	//根据id查询单条记录
	User findById(Integer id);
	//保存
	void save(User user);
	//更新
	void update(User user);
	//删除
	void delete(Integer id);
}


接着新建一个实现类UserDaoImpl来继承HibernateDaoSupport,实现接口UserDao。

package com.dao;

import java.util.List;

import javax.annotation.Resource;

import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import com.entity.User;

@Repository
public class UserDaoImpl extends HibernateDaoSupport implements UserDao{
	
	@Resource
	public void setSf(SessionFactory sf) {
		super.setSessionFactory(sf);
	}
	
	
	
	@Override
	public List<User> findAll() {
		String hql = "from User";
		return (List<User>) getHibernateTemplate().find(hql);
	}

	@Override
	public User findById(Integer id) {
		
		return getHibernateTemplate().get(User.class, id);
	}

	@Override
	public void save(User user) {
		getHibernateTemplate().save(user);	
	}

	@Override
	public void update(User user) {
		getHibernateTemplate().update(user);		
	}

	@Override
	public void delete(Integer id) {
		
		User user = new User();
		user.setId(id);
		getHibernateTemplate().delete(user);
	}
	
}

5、测试

在com.dao目录下新建TestDao测试类。具体代码如下:

package com.dao;

import java.util.List;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.transaction.annotation.Transactional;

import com.entity.User;

public class TestDao {
	private String conf="applicationContext.xml";
	
	@Test
	/**
	 * 测试查询功能
	 */
	public void test1() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(conf);
		UserDao dao = (UserDao) ctx.getBean("userDaoImpl");
		List<User> list= dao.findAll();
		for(User user : list) {
			System.out.println(user.getCard()+" "+user.getUsername());
		}
	}
	
	@Test
	/**
	 * 测试查询功能
	 */
	public void test2() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(conf);
		UserDao dao = (UserDao) ctx.getBean("userDaoImpl");
		User user= dao.findById(3);
		System.out.println(user.getCard()+" "+user.getUsername());		
	}
	
	@Test
	/**
	 * 测试保存功能
	 */
	@Transactional
	public void test3() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(conf);
		UserDao dao = (UserDao) ctx.getBean("userDaoImpl");
		
		User user= new User();
		user.setCard("174258");
		user.setUsername("王五");
		user.setPassword("174258");
		user.setCompany("JIALIDUN UNIVERSITY");
		user.setAge(23);
		user.setSex(2);
		dao.save(user);
		test1();
	}
	
	@Test
	/**
	 * 测试更新功能
	 */
	@Transactional
	public void test4() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(conf);
		UserDao dao = (UserDao) ctx.getBean("userDaoImpl");
		
		User user= dao.findById(3);
		user.setSex(2);
		dao.update(user);
		
	}
	
	@Test
	/**
	 * 测试删除功能
	 */
	@Transactional
	public void test5() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(conf);
		UserDao dao = (UserDao) ctx.getBean("userDaoImpl");
		dao.delete(10);
		
	}
}

二、Spring整合Struts

1、导包

导入Struts2开发包,Spring开发包以及Spring整合Struts2开发包。不同版本之间可能会有冲突,我在开始也遇到了jar包问题,后来用的Spring版本是4.3.20,Struts2用的是2.5.20。

2、配置web.xml

主要是进行容器启动时加载Spring和Struts2前端控制器,具体代码如下:

<?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_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>SSH_Day01</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <!-- 配置listener,在容器启动时自动加载Spring -->
  <listener>
  	<!-- ContextLoaderListener的作用就是启动Web容器时,自动装配ApplicationContext.xml的配置信息。
  	因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,
  	启动容器时,就会默认执行它实现的方法。 
  	ContextLoaderListener通过一个ContextLoader对象来初始化Spring容器-->
  	<listener-class>
  		org.springframework.web.context.ContextLoaderListener
  	</listener-class>
  </listener>
  <context-param>
  	<param-name>contextConfigLocation</param-name>
  	<param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  
  <!--配置Struts2前端控制器 -->
  <filter>
  	<filter-name>struts</filter-name>
  	<filter-class>
  		org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
  	</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>struts</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
  
</web-app>

3、创建Action

建立包com.action,在包下建立FindUserAction类,在这个Action的业务方法中,调用UserDao查询方法查出结果显示在页面上。需要使用Spring注解声明这个Action组件,另外也需要通过注解将DAO注入。
代码如下所示:

package com.action;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.dao.UserDao;
import com.entity.User;

@Controller
@Scope("prototype")
public class FindUserAction {
	
	@Resource
	private UserDao userDao;
	
	private List<User> users;
	
	public String load() {
		setUsers(userDao.findAll());
		return "success";
	}

	public List<User> getUsers() {
		return users;
	}

	public void setUsers(List<User> users) {
		this.users = users;
	}
	
}

4、配置struts.xml

在src根目录下建立struts.xml,代码如下所示。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC 
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" 
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<!-- package提供了将多个Action组织为一个模块的方式
        package的名字必须是唯一的
        name:package名称
        extends:继承的父package名称
        namespace:定义package命名空间 该命名空间影响到url的地址,例如此命名空间为/user
        地址为http://localhost:8080/SSH_Day01/user/findUser
        result里配置了跳转到的页面
     -->
	<package name="user" namespace="/user" extends="struts-default">
		<action name="findUser" class="findUserAction" method = "load">
			<result name="success">
				/WEB-INF/jsp/user.jsp
			</result>
		</action>
	</package>
	
</struts>

4、配置对应的jsp文件

在WebContent目录下建一个index.jsp,这就是项目启动时显示的页面。通过这个页面请求跳转到我们查询结果的页面。

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%
	String path = request.getContextPath();
	String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>查询用户</title>
</head>
<body>
	 <a href="<%=path%>/user/findUser"> 查询所有用户 </a>
</body>
</html>

在WEB-INF目录下新建一个包jsp存放我们的jsp文,建立user.jsp,具体代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@page import="com.entity.*"%>
<%@page import="java.util.List"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://"
            + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>

<base href="<%=basePath%>"></base>
<style type="text/css">
	.td td{
		width: 100px;
	}
	.table{
		text-align: center;
		margin: 0 auto;
	}
</style>
</head>
<body>
<%
	List list = ((List<User>)request.getAttribute("users"));
%>
 
	<table class="table">
		<tr class="td">
			<td>ID</td>
			<td>用户名</td>
			<td>密码</td>
			<td style="width: 200px">公司</td>
			<td>年龄</td>
			<td>性别</td>
		</tr>
<%for ( int i=0 ; i<list.size(); i++ ){%>
<%  User user = (User)list.get(i);%>
<% 	if( user !=null){%>
		<tr class="td">
			<td><%=user.getId()%></td>
			<td><%=user.getUsername()%></td>
			<td><%=user.getPassword()%></td>
			<td><%=user.getCompany()%></td>
			<td><%=user.getAge()%></td>
			<td><%=user.getSex()==1?"男":"女"%></td>
		</tr>
	<%}else{ %>
		<tr class="td">
			<td style="color: red;">暂无相关数据</td>
		</tr>
<%} }%>
	</table>
 	
</body>

</head>

</html>

三、启动项目测试

配置完毕后,我们可以利用Tomcat进行测试。
在这里插入图片描述
在这里插入图片描述

四、感想

在做的途中也遇到很多问题,但感觉主要的还是jar包之间的问题,通过百度也都解决了,祝愿各位小伙伴在学习途中也都能解决各自的问题。
项目地址:https://gitee.com/ggpig/SSH_Day01

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值