SSM框架解析-springmvc+spring+mybatis

1、前言

現在用java進行web開發,最主流的框架有SSH和SSM其分別爲struts+spring+hibernate和Spring+Springmvc+Mybatis,他們都是經典的MVC框架,對於項目的複用與代碼的分離有着不錯的效果。相比於SSH,SSM的交互是出於方法上的,比起action更加的靈活,今天我們主要說說SSM。

2、MVC

說起MVC很多人都聽過,那SSM,SSH與MVC的關係是怎麼樣的,mvc是一種軟件設計的典範,它主要由模型(model)-視圖(view)-控制器(controller)組成,主要實現了對邏輯、視圖、數據的分離。這樣做的好處就是代碼可以實現複用,而且項目也更易於管理與維護,耦合性大大降低,程序員們不用再花太多的精力去組織代碼。下面是對MVC的組成部分的介紹:
Model(模型)是應用程序中用於處理應用程序數據邏輯的部分。
  通常模型對象負責在數據庫中存取數據。
View(視圖)是應用程序中處理數據顯示的部分。
  通常視圖是依據模型數據創建的。
Controller(控制器)是應用程序中處理用戶交互的部分。
  通常控制器負責從視圖讀取數據,控制用戶輸入,並向模型發送數據。
在SSM中我們主要分爲表示層、業務邏輯層、數據持久層,在對應到MVC中,控制器由Springmvc的controller來承擔,視圖層主要由jsp來實現,而模型層主要由Mybatis操作數據庫表來實現,Spring通過依賴注入管理各層組件。

3、SSM

要理解SSM,我們需要理解組成他們的每一個技術的作用,只有這樣三者結合起來才能實現整體的項目構建。下面我們先說Springmvc,再說spring,最後講解mybatis。

3.1 springmvc

首先我們要明白一點springmvc是實現了一個連接器的作用,它接收來自頁面用戶的請求,解析參數並傳給服務層進行下一步業務邏輯處理,因此它承擔了一箇中轉站的作用,如果你用過servlet那麼一定知道用戶請求是給到servlet來處理的,在springmvc中用戶的請求會全部由DispatcherServlet來進行處理,根據url的不同會分發給不同的controller,與servlet不同,我們在一個controller中可以定義多個方法用於實現一個模塊中多個不同的的請求,比如登錄註冊模塊只需要寫一個controller,在其下寫多個方法,分別來執行登錄和註冊的請求,這樣我們就把對請求的處理細化到了方法上。下面我們用一個小例子來實現一下springmvc
(1)首先新建一個Dynamic web project,我們命名爲springmvcTest001,第一步先添加我們需要用到的jar包,如下圖所示:


接下來在src下建立包並建立HelloController.java,如下所示:
package com.example;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
* @author zhaoshaopeng
* @version 創建時間:2017年9月13日 下午2:45:13
* 類說明
*/
@Controller
public class HelloController {
	
	@RequestMapping(value="test1")
	public String test1(){
		System.out.println("test1");
		return "test1";
		
	}
	@RequestMapping(value="test2")
	public String test2(){
		System.out.println("test2");
		return "test2";

	}

}

在上面的代碼中出現了@controller和@RequestMapping這兩個註解,第一個的意思就是告訴容器目前所標註的類是一個controller,系統將會把當前類加入到DispatcherServlet的候選列表,第二個註解的意思是響應請求的,裏面的value內容就是在頁面寫請求的url。
(2)在WEB-INF文件夾下寫我們的springmvc配置文件,Spring-mvc.xml
<beans xmlns="http://www.springframework.org/schema/beans"  
	xmlns:context="http://www.springframework.org/schema/context"  
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
	xmlns:mvc="http://www.springframework.org/schema/mvc"  
	xsi:schemaLocation="    
	http://www.springframework.org/schema/mvc   
	http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd  
	http://www.springframework.org/schema/beans         
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    
	http://www.springframework.org/schema/context     
	http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
	
	<!-- 把標記了@Controller註解的類轉換爲bean -->  
	<context:component-scan base-package="com.example" />

	<!-- 啓動Spring MVC的註解功能,完成請求和註解POJO的映射 -->  
	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />  
	<!-- 對模型視圖名稱的解析,即在模型視圖名稱添加前後綴 -->  
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"  
		p:prefix="/" p:suffix=".jsp"/>  
	
</beans>  

在配置文件中,首先要掃描我們標註的java文件所在的包,其次還要開啓註解功能,最後一個是對頁面的映射,當在標註了@RequestMapping的方法中返回了字符串後,首先會在這個地方進行匹配,後綴爲.jsp,如果匹配到了就跳轉到相應的頁面。
接下來,我們得在web.xml中註冊我們的springmvc配置文件,如下:
<?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" id="WebApp_ID" version="3.0">
	<display-name>springmvcTest001</display-name>
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
	<servlet>
		<servlet-name>applicationContextServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/Spring-mvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>applicationContextServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>default</servlet-name>
		<url-pattern>*.jpg</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>default</servlet-name>
		<url-pattern>*.png</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>default</servlet-name>
		<url-pattern>*.js</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>default</servlet-name>
		<url-pattern>*.css</url-pattern>
	</servlet-mapping>
</web-app>

接下來,再創建三個jsp頁面,index.jsp,test1.jsp,test2.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">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<a href="/test1">test1</a>
	<a href="/test2">test2</a>
</body>
</html>

<%@ 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">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	this is test1!
</body>
</html>

<%@ 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">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
this is test2!

</body>
</html>

最終實現的就是處理用戶請求,並跳轉到頁面的簡單功能。在這裏還要注意一點,如果創建的jsp頭部有錯,那是沒有導入包的原因,在buildpath中addlibary,點擊server Running 下點擊tomcat導入包就可以了。通過這個例子希望能對springmvc有一個認識。

3.2、Spring

說到Spring最熟悉的就是依賴注入和控制反轉了,很多不瞭解的人會覺得很高深,其實實現起來很簡單,沒有那麼神祕。首先我們應該理解這兩個詞是什麼意思。我們拆開來看:
依賴是什麼意思,誰依賴誰;
注入什麼意思,誰注入誰;
誰控制了誰;
爲什麼叫反轉;
下面解釋一下:
依賴就是一個物體依託於一個物體而去完成一件事,這裏是應用程序依賴於容器
注入是指把某個東西注入到另一個事務中,這裏是Ioc容器注入對象
   Ioc容器控制了對象
   依賴對象的獲取被反轉了,由主動創建變成了被動接受
這裏依賴注入(DI)和控制反轉(IOC)是同一事物在不同角度的描述,依賴注入是從對象(應用程序)角度出發的,對象依賴容器創建並注入所需的外部資源;控制反轉是從容器角度來說的,容器控制對象,由容器反向向對象中注入所需要的外部資源。下面我們通過一個例子來體會spring的作用。
(1)首先我們創建工程GSpringIOC,並引入相應的包,如下:
(2)接下來創建接口:
package com.ioc.zhujie;
/**
* @author zhaoshaopeng
* @version 創建時間:2017年8月29日 下午4:57:34
* 類說明
*/
public interface IBookDAO {
	
	public String addBook(String bookname);

}

(3)去實現這個接口:
package com.ioc.zhujie;

import org.springframework.stereotype.Component;

/**
* @author zhaoshaopeng
* @version 創建時間:2017年8月29日 下午4:58:23
* 類說明
*/
@Component("bookdaoObj")
public class BookDAO_zhujie implements IBookDAO{

	@Override
	public String addBook(String bookname) {
		// TODO Auto-generated method stub
		return "添加圖書"+bookname+"成功!";
	}
	

}

這裏@Component("bookdaoObj")註解的作用是將當前類注入到spring容器,名稱爲bookdaoObj。
(4)下面寫一個具體的業務邏輯類
package com.ioc.zhujie;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

/**
* @author zhaoshaopeng
* @version 創建時間:2017年8月29日 下午5:02:24
* 使用xml實現ioc
*/
@Component
public class BookService_zhujie {
	IBookDAO bookDAO;

	public void storeBook(String bookname){
		 //容器
        ApplicationContext ctx=new ClassPathXmlApplicationContext("IOCBeans02.xml");
        //從容器中獲得id爲bookdao的bean
        bookDAO=(IBookDAO)ctx.getBean("bookdaoObj");
        System.out.println("圖書上貨");
        String result=bookDAO.addBook(bookname);
        System.out.println(result);
    }
	

}

這裏我們沒有去實例化bookDAO,而是在容器中取出。
(5)接下來在WEB-INF下創建spring的配置文件IOCBeans02.xml:
<?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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.3.xsd">
        <context:component-scan base-package="com.ioc.zhujie"></context:component-scan>
</beans>

這裏寫了自動掃描添加了註解的包
(6)最後我們寫一個測試類來測試一下
package com.ioc.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ioc.zhujie.BookService_zhujie;

/**
* @author zhaoshaopeng
* @version 創建時間:2017年8月29日 下午5:32:01
* 類說明
*/
public class test_zhujie {
	@org.junit.Test
    public void testStoreBook()
    {
        //容器
        ApplicationContext ctx=new ClassPathXmlApplicationContext("IOCBeans02.xml");
        BookService_zhujie bookservice=ctx.getBean(BookService_zhujie.class);
        bookservice.storeBook("《Spring MVC權威指南 第二版》");
    }

}

通過上面的例子,我們可以看出,通過spring我們的對象不再由類去主動創建,而是通過spring容器來完成,這就減少了類間的耦合度,同時在開發中也通過spring實現對對象外部資源的注入,比如sql操作等。

3.2Mybatis

MyBatis是一個支持普通SQL查詢,存儲過程和高級映射的優秀持久層框架。MyBatis消除了幾乎所有的JDBC代碼和參數的手工設置以及對結果集的檢索封裝。MyBatis
可以使用簡單的XML或註解用於配置和原始映射,將接口和Java的POJO(Plain Old Java Objects,普通的Java對象)映射成數據庫中的記錄。
下面用一個例子說明Mybatis的使用。
(1)建立工程,加入包

並創建實體類GAdmin
package com.example.model;

import java.io.Serializable;

/**
* @author zhaoshaopeng
* @version 創建時間:2017年8月21日 下午5:25:58
* 類說明
*/

public class GAdmin implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 2534721862170815266L;
	private int id;
	private String name="";
	private String password="";
	private String sex="";
	private String tel="";
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getTel() {
		return tel;
	}
	public void setTel(String tel) {
		this.tel = tel;
	}
	@Override
    public String toString() {
        return "Admin [id=" + id + ", name=" + name + ", password=" + password + "]";
    }

}

(2)創建映射文件admapper.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">
<mapper namespace="com.example.mapper.admapper">
    <select id="getAdmin" parameterType="int" 
        resultType="com.example.model.GAdmin">
        select * from admin where id=#{id}
    </select>
</mapper>

在這個文件中我們寫了一個查詢語句,參數爲int,輸出爲一個對象。
(3)創建mybatis配置文件conf.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <!-- 配置數據庫連接信息 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/gstudb" />
                <property name="username" value="root" />
                <property name="password" value="1234" />
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/example/mapper/admapper.xml"/>
    </mappers>
    
</configuration>

在文件中我們配置了連接數據庫的信息,並把剛纔寫的mapper文件加載進來
(4)寫一個測試類去測試一下
package com.example.test;

import java.io.InputStream;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import com.example.model.GAdmin;

/**
* @author zhaoshaopeng
* @version 創建時間:2017年9月13日 下午5:25:41
* 類說明
*/

public class test {
	@org.junit.Test
	public void testmybatis(){
		//mybatis的配置文件
        String resource = "conf.xml";
        //使用類加載器加載mybatis的配置文件(它也加載關聯的映射文件)
        InputStream is = test.class.getClassLoader().getResourceAsStream(resource);
        //構建sqlSession的工廠
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);     
        SqlSession session = sessionFactory.openSession();
        String statement = "com.example.mapper.admapper.getAdmin";//映射sql的標識字符串
        //執行查詢返回一個唯一user對象的sql
        GAdmin user = session.selectOne(statement, 1);
        System.out.println(user.toString());
		
	}

}
最後附上例子的結構圖:

由於數據庫每個人的情況不同,因此需要自己手動修改才能跑通。

4、結束語

本文通過對MVC的簡單梳理,緊接着講解了springmvc、spring、mybatis的基本用法,在這裏並沒有進行三者的整合,因此在使用時可能感受並不是那麼深刻,但這裏講的都是基本用法,掌握了這些後續的環節才能靈活運用,在後續我也會附上整合的理解,希望大家共同進步!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章