一、SSM简介
SSM(Spring+SpringMVC+MyBatis)框架集由Spring、MyBatis两个开源框架整合而成(SpringMVC是Spring中的部分内容)。常作为数据源较简单的web项目的框架。
1. Spring
- Spring就像是整个项目中装配bean的大工厂,在配置文件中可以指定使用特定的参数去调用实体类的构造方法来实例化对象。也可以称之为项目中的粘合剂。
- Spring的核心思想是IoC(控制反转),即不再需要程序员去显式地
new
一个对象,而是让Spring框架帮你来完成这一切。
2. SpringMVC
- SpringMVC在项目中拦截用户请求,它用于web层,相当于controller(等价于传统的servlet和struts的action)。它的核心Servlet即DispatcherServlet承担中介或是前台这样的职责,将用户请求通过HandlerMapping去匹配Controller,Controller就是具体对应请求所执行的操作。
- 例如,用户在地址栏输入http://网站域名/login,那么springmvc就会拦截到这个请求,并且调用controller层中相应的方法,(中间可能包含验证用户名和密码的业务逻辑,以及查询数据库操作,但这些都不是springmvc的职责),最终把结果返回给用户,并且返回相应的页面(当然也可以只返回json/xml等格式数据)。
3. mybatis
- mybatis是对jdbc的封装,它让数据库底层操作变的透明。mybatis的操作都是围绕一个sqlSessionFactory实例展开的。mybatis通过配置文件关联到各实体类的Mapper文件,Mapper文件中配置了每个类对数据库所需进行的sql语句映射。在每次与数据库交互时,通过sqlSessionFactory拿到一个sqlSession,再执行sql命令。
二、SSM各个层解释说明
转载自博客:点击查看原文章
1. 持久层:DAO层(mapper)
DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,
- DAO层的设计首先是设计DAO的接口,
- 然后在Spring的配置文件 (applicationContext.xml) 中定义此接口的实现类,
- 然后就可在模块中调用此接口来进行数据业务的处理,而不用关心此接口的具体实现类是哪个类,显得结构非常清晰,
- DAO层的数据源配置,以及有关数据库连接的参数都在Spring的配置文件中进行配置。
2. 业务层:Service层
Service层主要负责业务模块的逻辑应用设计。
- 首先设计接口,再设计其实现的类
- 接着再在Spring的配置文件中配置其实现的关联。这样我们就可以在应用中调用Service接口来进行业务处理。
- Service层的业务实现,具体要调用到已定义的DAO层的接口,
- 封装Service层的业务逻辑有利于通用的业务逻辑的独立性和重复利用性,程序显得非常简洁。
3. 表现层/控制层:Controller层(Handler层)
Controller层负责具体的业务模块流程的控制,在此层里面要调用Service层的接口来控制业务流程。
- 控制的配置也同样是在Spring的配置文件里面进行,针对具体的业务流程,会有不同的控制器,我们具体的设计过程中可以将流程进行抽象归纳,设计出可以重复利用的子单元流程模块,这样不仅使程序结构变得清晰,也大大减少了代码量。
4. View层
此层与控制层结合比较紧密,需要二者结合起来协同工发。View层主要负责前台jsp页面的表示.
三、整体流程
- 页面发送请求给控制器(Controller),控制器调用业务层(Service)处理逻辑,逻辑层向持久层(Dao)发送请求,持久层与数据库交互,后将结果返回给业务层,业务层将处理逻辑发送给控制器,控制器再调用视图展现数据。
- 调用顺序:web页面发出请求 → web.xml(配置前端控制器)→ applicationContext.xml (开启注解扫描)→ Controller(@Resource注入service,调用Service) → Service(注入dao,调用dao) →DAO(Mapper接口映射器) → 完成具体的数据库操作
- 其中Service层应该既调用DAO层的接口,又要提供接口给Controller层的类来进行调用,它刚好处于一个中间层的位置。每个模型都有一个Service接口,每个接口分别封装各自的业务处理方法。
四、简单测试流程案例
1.web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>SSMdemo</display-name>
<!-- 配置前端控制器 -->
<servlet>
<servlet-name>ssm</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ssm</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
2.applicatonContext.xml
- 主要配置内容:
- 数据库信息
- dao接口
- SqlSessionFactory
- 这里使用sqlSessionFactoryBeanName属性是因为如果配置的是sqlSessionFactory属性,将不会先加载数据库配置文件及数据源配置
- mapper扫描器(注解方式)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!--mybatis关键: UserDao dao=session.getMapper(UserDao.class); -->
<!-- mybatis-spring(5,-1)第5个包最后一个类 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 需要制定dao接口 setBasePackage() -->
<property name="basePackage" value="com.hqyj.dao"></property>
<!-- 需要SqlSession对象,由于框架比较智能,不用写ref注入,它也会自动给我们注入 -->
</bean>
<!-- 获取SqlSessionFactory. class值=jar包mybatis-spring(1,3)-->
<bean id="ssf" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 指定数据库连接参数 -->
<property name="dataSource" ref="dbcp"></property>
<!-- 指定映射文件-->
<property name="mapperLocations" value="classpath:com/hqyj/sql/*.xml"></property>
</bean>
<!-- 数据库连接池 class值=jar包commons-dbcp(1,4) -->
<bean id="dbcp" class="org.apache.commons.dbcp.BasicDataSource">
<property name="username" value="root"></property>
<property name="password" value="root"></property>
<property name="url" value="jdbc:mysql://localhost:3306/cloud_note?useUnicode=true&characterEncoding=utf8"></property>
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
</bean>
<!-- 配置handlerMapping 可以用注解的方式代替 @RequestMapping -->
<!-- 想使用注解,需要先开启注解扫描 -->
<context:component-scan base-package="com.hqyj"></context:component-scan>
<!-- 开启驱动 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 配置ViewResolver -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".html"></property>
</bean>
</beans>
3.UserMapper.xml (数据库操作)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace命名空间,作用就是对sql进行分类化管理(sql隔离) -->
<!-- 辅配置文件 -->
<mapper namespace="com.hqyj.dao.UserDao">
//查询所有信息
<select id="findAll" resultType="com.hqyj.entity.User">
select * from cn_user; <!-- 注意:加不加分号都可以 -->
</select>
//按名字查找
<select id="findByName" resultType="com.hqyj.entity.User" parameterType="string">
select * from cn_user where cn_user_name like concat('%',#{name},'%') <!-- 注意:只有一个参数时,#{}内的内容可以随便写 -->
</select>
//增加数据
<!-- 由于是插入了所有信息,参数类型可以直接用对象即可,但是values值必须与对象的属性相同,不能随便写 -->
<insert id="save" parameterType="com.hqyj.entity.User">
insert into cn_user(cn_user_id,cn_user_name,cn_user_password,cn_user_token,cn_user_nick)
values(#{cn_user_id},#{cn_user_name},#{cn_user_password},#{cn_user_token},#{cn_user_nick})
</insert>
//删除数据
<delete id="delete" parameterType="string">
delete from cn_user where cn_user_name = #{user_name}
</delete>
//修改数据
<update id="update" parameterType="com.hqyj.entity.User">
update cn_user set cn_user_nick = #{cn_user_nick} where cn_user_name = #{cn_user_name}
</update>
</mapper>
4.UserDao.java(与UserMapper.xml的操作相对应)
package com.hqyj.dao;
import java.util.List;
import com.hqyj.entity.User;
public interface UserDao {
/*
* Mapper接口映射规则
1.id就是方法名
2.resultType就是返回值类型
3.ParameterType就是参数
4.namespace就是我们的接口路径:包名.接口名
*/
public List<User> findAll();
public List<User> findByName(String name);
public void save(User user);
public void delete(String name);
public void update(User user);
}
5.User.java
package com.hqyj.entity;
public class User {
private String cn_user_id;
private String cn_user_name;
private String cn_user_password;
private String cn_user_token;
private String cn_user_nick;
public String getCn_user_id() {
return cn_user_id;
}
public void setCn_user_id(String cn_user_id) {
this.cn_user_id = cn_user_id;
}
public String getCn_user_name() {
return cn_user_name;
}
public void setCn_user_name(String cn_user_name) {
this.cn_user_name = cn_user_name;
}
public String getCn_user_password() {
return cn_user_password;
}
public void setCn_user_password(String cn_user_password) {
this.cn_user_password = cn_user_password;
}
public String getCn_user_token() {
return cn_user_token;
}
public void setCn_user_token(String cn_user_token) {
this.cn_user_token = cn_user_token;
}
public String getCn_user_nick() {
return cn_user_nick;
}
public void setCn_user_nick(String cn_user_nick) {
this.cn_user_nick = cn_user_nick;
}
@Override
public String toString() {
return "User [cn_user_id=" + cn_user_id + ", cn_user_name=" + cn_user_name + ", cn_user_password="
+ cn_user_password + ", cn_user_token=" + cn_user_token + ", cn_user_nick=" + cn_user_nick + "]";
}
}
6.login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<form action="ssm.do">
<input type="submit" value="SSM"></input>
</form>
</body>
</html>
7.UserController.java
package com.hqyj.controller;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.hqyj.entity.User;
import com.hqyj.service.UserService;
//controller调用service
@Controller //这里用控制层组件注解,不用通用注解!相当于<bean id="userController" class="com.hqyj.controller.UserController">
public class UserController {
@Resource //相当于<bean id="userService" class="com.hqyj.service.UserService">
private UserService service;
@RequestMapping("/ssm.do")
public String function(){
System.out.println(111);
List<User> users=service.testService();
for(User u:users){
System.out.println(u.getCn_user_name());
}
return "success";
}
}
8.UserService.java
package com.hqyj.service;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.hqyj.dao.UserDao;
//service调用dao
import com.hqyj.entity.User;
@Service
public class UserService {
@Resource
private UserDao userDao;
public List<User> testService(){
List<User> users=userDao.findByName("*d*");
return users;
}
}
9.success.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
you have succeed!
</body>
</html>
10.测试
(1) 运行login.html
(2) 点击SSM
(3)从上图可知测试成功