SSM(Spring+SpringMVC+Mybatis)+Mysql 框架整合搭建流程以及其間注意事項

複習SSM框架,過久沒用本身手動撘一個,發現本身仍是有不少地方忘記了和沒注意的事項。。。css

 

首先,直接給出總流程html

零、引jar包前端

  一、引包(或者寫maven.pom)java

1、數據庫部分mysql

  設計數據庫各表結構,主鍵、外鍵等web

2、Model部分spring

  一、根據表結構寫相對應的bean(*.java)sql

  二、配置mybatis.xml數據庫

    主要寫typeAlias(別名)express

  三、根據別名編寫  *Mapper.xml  放在beanMapper包下

3、Controller部分

  一、根據  *Map.xml 編寫 *Dao.java 與 *DaoImp.java

  二、根據 *Dao.java 編寫 *Service.java 與 *ServiceImp.java(屬性:*Dao)

  三、根據  *Service.java 編寫 *Controller.java (屬性:*Service)

    註釋實現 *.action 映射

4、配置部分

  一、db.properties

    裏面設置MySql或者其餘數據庫的鏈接屬性,以及鏈接池的參數設置

  二、applicationContext.xml

    a. 引入db.properties數據庫配置文件

    b. 創建鏈接池

      將數據庫配置的配置設置成參數傳入

    c. 創建sqlSessionFactory

      將 mybatis.xml + 鏈接池 + *Mapper.xml所在文件夾位置   三個屬性傳入

    d. 創建事務管理器

      將鏈接池傳入

    e. 配置事務管理器(聲明事務切入的包和類)

      註解實現 or 配置實現

    f. controller層的bean的註冊

      註冊各個DaoImp

      註冊各個ServiceImp(將對應Dao 以property注入)

 

  三、spring-mvc.xml

    一、配置Action層

      註解實現 or 配置實現(記得將Service注入)

    二、映射器配置

    三、適配器配置

    四、視圖解析器配置

  四、 web.xml

    一、設置listener

    二、設置applicationContext.xml位置

    三、配置前段控制器

      servlet(此時聲明spring-mvc.xml位置)、servlet-mapping

    四、配置編碼過濾器

      filter、filter-mapping

    五、設置起始頁面

5、View部分

  一、編寫jsp

 

 

下面是整個流程的細節以及注意事項,(注意事項會用藍色底色標註)

整個框架的功能爲:兩個頁面分別爲學生和班級的增刪改查功能(在此以學生頁面爲例)

零、引jar包

  

   至於每一個lib下有哪些jar,網上搜一下就好了,不贅述。

   不過仍是有幾個須要注意的地方:

  • 若是使用Myeclipse的自動配置Spring的話(右鍵項目——「properties」——「project facets」——勾選Spring)
    • 這樣產生的Spring Library是最小系統的lib,裏面的jar不包含與Spring-MVC有關的jar
    •   因此不少仍是須要本身從新引入,還不如一開始就創建本身的Spring-SpringMVC的userlib(Config Build Path裏面能夠設置,再也不贅述)
  • Mybatis的包引入後還須要引入Mybatis-Spring-XX.jar,裏面包括連兩個框架集成所需的class
  • 最後一個最忽視的地方:Spring-mvc的相關包必須放在web-inf/lib包下,不然會說找不到,而咱們常常是用的USER-LIB,因此最後應該配置一下:

    右鍵項目——properties——Deployment——Depolyment Assembly  而後選擇右邊的add,而後選擇「Java Build Path Entries」,將全部的User-lib都添加進來。

 

1、數據庫部分

  先不着急建表,首先分析表間的關係,很明顯爲多對一,因此「多」這邊的表就應該設置外鍵指向「一」,外鍵的做用(1.一致性、2完整性)再也不贅述。

  例如本項目,就是應該在「多」的一方表 students 這邊設置外鍵 cid 指向 classes表的cid。(其實students表這邊的cid 應該起名爲s_cid以示區分

  classes表:

CREATE TABLE `classes` (
  `cid` int(5) NOT NULL AUTO_INCREMENT,
  `cname` varchar(10) NOT NULL,
  PRIMARY KEY (`cid`)
) 
classes.sql

 

  students表:

CREATE TABLE `students` (
  `sid` int(5) NOT NULL AUTO_INCREMENT,
  `sname` varchar(10) NOT NULL,
  `sage` int(5) DEFAULT NULL,
  `ssex` int(1) DEFAULT NULL,
  `cid` int(5) DEFAULT NULL,
  PRIMARY KEY (`sid`),
  KEY `cid` (`cid`),
  CONSTRAINT `students_ibfk_1` FOREIGN KEY (`cid`) REFERENCES `classes` (`cid`)
)
students.sql

  我是用 SQLyog 設置而後自動生成的。

 

2、Model部分

 

  一、根據表結構寫相對應的bean(*.java)

    建立bean包,以後把全部bean都放在這

    

    根據表結構編寫 *.java(項目最好不要像我起Cass這種java內已有的類名,以避免引入的時候混淆)

      做爲主表student的話它的屬性中cid那一個應該寫爲Class類,以此最後查詢返回的時候能直接進行映射

package bean;

public class Class {
    Integer cid;
    String cname;
    
    public Class() {
        super();
    }

    public Class(Integer cid, String cname) {
        super();
        this.cid = cid;
        this.cname = cname;
    }
    
    public Class(String cname) {
        super();
        this.cname = cname;
    }
    public Integer getCid() {
        return cid;
    }
    public void setCid(Integer cid) {
        this.cid = cid;
    }
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }

    @Override
    public String toString() {
        return "Class [cid=" + cid + ", cname=" + cname + "]";
    }
}
Class.java
package bean;

public class Student {
    Integer sid;
    String sname;
    Integer ssex;
    Integer sage;
    Class cls;
    
    public Student() {
        super();
    }
    
    public Student(Integer sid, String sname, Integer ssex, Integer sage, Class cls) {
        super();
        this.sid = sid;
        this.sname = sname;
        this.ssex = ssex;
        this.sage = sage;
        this.cls = cls;
    }
    
    public Student(String sname, Integer ssex, Integer sage, Class cls) {
        super();
        this.sname = sname;
        this.ssex = ssex;
        this.sage = sage;
        this.cls = cls;
    }

    public Integer getSid() {
        return sid;
    }
    public void setSid(Integer sid) {
        this.sid = sid;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }
    public Integer getSage() {
        return sage;
    }
    public void setSage(Integer sage) {
        this.sage = sage;
    }
    public Integer getSsex() {
        return ssex;
    }
    public void setSsex(Integer ssex) {
        this.ssex = ssex;
    }
    public Class getCls() {
        return cls;
    }
    public void setCls(Class cls) {
        this.cls = cls;
    }

    @Override
    public String toString() {
        return "Student [sid=" + sid + ", sname=" + sname + ", sage=" + sage + ", ssex=" + ssex + ", cls=" + cls + "]";
    }
}
Student.java

    其間的各類構造器必需要無參構造器——Mybatis返回結果的時候默認調用,其餘的構造器能夠根據本身須要來)以及setter和getter方法也必定要設置。

  二、配置mybatis.xml

    主要寫typeAlias(別名)

mybatis.xml
  •     此處須要注意頭文件說明中: "http://mybatis.org/dtd/mybatis-3-config.dtd" 設置 XMLcatalog
    •   點擊IDE裏的「windows」——「preference」——「Files 安定Editors」——「XML」——「XML Files」——「XML」——「XML catalog」
    •   點擊右邊的add
    •   location選擇項目中「mybatis-3-config.dtd」的位置(沒有則下載複製過來,通常直接放在src目錄下)
    •   key type選擇 url;key 直接複製頭文件中的 ***.dtd 便可

 

  三、編寫 *Mapper.xml 放在beanMapper包下

ClassMapper.xml
StudentMapper.xml

  此處有一些須要注意的地方:

  •   頭文件的 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"也須要引入XML catalog
  •   <resultMap>標籤中的屬性與列匹配是有必定順序的: 順序爲(constructor?, id*, result*, association*, collection*, discriminator?),不按順序來回報錯。
  •   主鍵必定要以 id 的子標籤進行匹配,不然在進行其餘表的鏈接的時候可能會報空指針錯誤
  •   動態sql進行foreach的時候,若是傳入的屬性只有一個List或者Array,則collection=「list」或則collection=「array」,此時再也不須要寫「parameterType」屬性,可是注意寫item,以及${item}
  •   <where>標籤中的<if>標籤內後面的 「,」 可寫可不寫。可是前面「and」必須寫
  •   若是xml內須要寫邏輯語句例如 「&」「>」"<"等 ,此時不能直接寫(包括sql語句內),由於會與標籤符「<>」混淆,因此應該採用xml內的轉義字符(實體引用):
    • 例如StudnetMapper.xml中的 <if test="sname!=null &amp; sname != ''"> 

 

3、Controller部分

  一、根據  *Map.xml 編寫 *Dao.java (接口)與 *DaoImp.java(實現類)

    (上面的名字是建議,下面的名字是我當時臨時寫的,可能不一致)

package daoIntf;

import java.util.List;
import bean.Class;

public interface ClassDaoIntf {
    public void addClass(Class cls) throws Exception;
    
    public void deleteClass(Class cls) throws Exception;
    
    public void updateClass(Class cls) throws Exception;
    
    public List<Class> findClass(Class cls) throws Exception;

    public void addClass(String string)  throws Exception;
    
    public List<Class> findClass(String string)  throws Exception;
}
ClassDaoInf.java(接口)
package daoIntf;

import java.util.List;
import bean.Student;

public interface StudentDaoIntf {
    public void addStudent(Student stu) throws Exception;
    
    public void deleteStudent(List<Integer> sids) throws Exception;
    
    public void updateStudent(Student stu) throws Exception;
    
    public List<Student> findStudent(Student stu) throws Exception;
}
StudentDaoInf.java(接口)
package dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import bean.Class;
import daoIntf.ClassDaoIntf;


public class ClassDao implements ClassDaoIntf {
    
    private SqlSessionFactory sqlSessionFactory;
    
    public ClassDao() {
    }
    
//    public ClassDao(SqlSessionFactory sqlSessionFactory) {
//        super();
//        this.sqlSessionFactory = sqlSessionFactory;
//    }
    
    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    
    @Override
    public void addClass(Class cls) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.insert("ClassNameSpace.add", cls);
        System.out.println("插入班級"+cls+"成功");
        sqlSession.commit();
        sqlSession.close();
    }
    
    public void addClass(String cname) throws Exception {
        addClass(new Class(cname));
    }

    @Override
    public void deleteClass(Class cls) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.delete("ClassNameSpace.delete", cls);
        System.out.println("刪除班級"+cls+"成功");
        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public void updateClass(Class cls) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.update("ClassNameSpace.update", cls);
        System.out.println("更新班級"+cls+"成功");
        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public List<Class> findClass(Class cls) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<Class> result =  sqlSession.selectList("ClassNameSpace.find", cls);
        System.out.println("查詢班級"+result+"成功");
        sqlSession.close();
        return result;
    }
    
    public List<Class> findClass(String cname) throws Exception {
        return findClass(new Class(cname));
    }
    
    public List<Class> findClass() throws Exception {
        return findClass(new Class());
    }
}
ClassDao.java(實現類)
package dao;

import java.util.List;

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

import bean.Student;
import daoIntf.StudentDaoIntf;



public class StudentDao implements StudentDaoIntf {
    
    private SqlSessionFactory sqlSessionFactory;
    
    public StudentDao() {
    }
    
//    public StudentDao(SqlSessionFactory sqlSessionFactory) {
//        super();
//        this.sqlSessionFactory = sqlSessionFactory;
//    }
    
    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    
    @Override
    public void addStudent(Student stu) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.insert("StudentNameSpace.add", stu);
        System.out.println("插入學生"+stu+"成功");
        sqlSession.close();
    }

    @Override
    public void deleteStudent(List<Integer> sids) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        System.out.println(sids);
        sqlSession.delete("StudentNameSpace.delete", sids);
        System.out.println("刪除學生"+sids+"成功");
        sqlSession.close();
    }

    @Override
    public void updateStudent(Student stu) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.update("StudentNameSpace.update", stu);
        System.out.println("更新學生"+stu+"成功");
        sqlSession.close();
    }

    @Override
    public List<Student> findStudent(Student stu) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<Student> result =  sqlSession.selectList("StudentNameSpace.find", stu);
        System.out.println("查詢學生"+result+"成功");
        sqlSession.close();
        return result;
    }
}
StudentDao.java(實現類)

  建議使用set方法屬性注入,由於若是使用構造器的注入的話Junit進行測試會報錯「只能擁有一個構造器」。

  二、根據 *Dao.java 編寫 *Service.java 與 *ServiceImp.java(屬性:*Dao)

  全部涉及業務操做都應該在此完成(業務操做就是與傳過來的數據之間計算有關的操做,例如:分頁計算、股票預測),不過本案例主要是增刪改查,因此不涉及業務操做,直接調用Dao便可。

package serviceIntf;

import java.util.List;

import bean.Class;

public interface ClassServiceInf {
    public void addClass(Class cls) throws Exception;
    
    public void deleteClass(Class cls) throws Exception;
    
    public void updateClass(Class cls) throws Exception;
    
    public List<Class> findClass(Class cls) throws Exception;
}
ClassServiceInf.java(接口)
package serviceIntf;

import java.util.List;

import bean.Class;

public interface ClassServiceInf {
    public void addClass(Class cls) throws Exception;
    
    public void deleteClass(Class cls) throws Exception;
    
    public void updateClass(Class cls) throws Exception;
    
    public List<Class> findClass(Class cls) throws Exception;
}
StudentServiceInf.java(接口)
package service;

import java.util.List;

import bean.Class;
import dao.ClassDao;
import daoIntf.ClassDaoIntf;
import serviceIntf.ClassServiceInf;

public class ClassService implements ClassServiceInf {

    private ClassDaoIntf classDao;
    
    public void setClassDao(ClassDaoIntf classDao) {
        this.classDao = classDao;
    }
    
    @Override
    public void addClass(Class cls) throws Exception {
        classDao.addClass(cls);
    }

    @Override
    public void deleteClass(Class cls) throws Exception{
        classDao.deleteClass(cls);
    }

    @Override
    public void updateClass(Class cls) throws Exception {
        classDao.updateClass(cls);
    }

    @Override
    public List<Class> findClass(Class cls) throws Exception {
        return classDao.findClass(cls);
    }
    
}
ClassService.java(實現類)
package service;

import java.util.List;

import bean.Class;
import bean.Student;
import dao.ClassDao;
import daoIntf.ClassDaoIntf;
import daoIntf.StudentDaoIntf;
import serviceIntf.ClassServiceInf;
import serviceIntf.StudentServiceInf;

public class StudentService implements StudentServiceInf {

    private StudentDaoIntf studentDao;

    public void setStudentDao(StudentDaoIntf studentDao) {
        this.studentDao = studentDao;
    }
    
    @Override
    public void addStudent(Student stu) throws Exception {
        studentDao.addStudent(stu);
    }

    @Override
    public void deleteStudent(List<Integer> sids) throws Exception {
        studentDao.deleteStudent(sids);
    }

    @Override
    public void updateStudent(Student stu) throws Exception {
        studentDao.updateStudent(stu);
    }

    @Override
    public List<Student> findStudent(Student stu) throws Exception {
        return studentDao.findStudent(stu);
    }
}
StudentService.java(實現類)

  三、根據  *Service.java 編寫 *Controller.java (屬性:*Service)

    Action層主要就是在此處實現對錶單傳過來的數據進行校驗(也可由js完成)、加工、封裝、以及返回(重定向or轉發),並不涉及業務操做

    註釋實現 *.action 映射比較方便,也能夠選擇xml配置實現

 

    @requestMapping中還有個method屬性能夠指定接受的訪問類型eg.:GET:  method=RequestMethod.GET )

package action;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import bean.Class;
import service.ClassService;
import serviceIntf.ClassServiceInf;

@Controller
@RequestMapping(value="/class")
public class ClassAction {
    private ClassServiceInf classService;
    @Resource(name="classService")
    public void setClassService(ClassServiceInf classService) {
        this.classService = classService;
    }
    
    @RequestMapping(value="/add")
    public ModelAndView addClass(Class cls) throws Exception {
        ModelAndView mv = new ModelAndView();
        //調用業務層方法
        classService.addClass(cls);
        mv.addObject("action", "addClass");
        mv.setViewName("success");
        return mv;
    }
    
    @RequestMapping(value="/find")
    public ModelAndView findClass(Class cls) throws Exception {
        ModelAndView mv = new ModelAndView();
        //調用業務層方法
        List<Class> classList = classService.findClass(cls);
        
        if (classList.isEmpty()) {
            mv.addObject("isNull", true);
        }
        mv.addObject("cid", cls.getCid());
        mv.addObject("cname", cls.getCname());
        mv.addObject("classList", classList);
        mv.setViewName("class");
        return mv;
    }
}
ClassAction.java
package action;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import bean.Class;
import bean.Student;
import service.StudentService;
import serviceIntf.ClassServiceInf;
import serviceIntf.StudentServiceInf;

@Controller
@RequestMapping(value="/student")
public class StudentAction {
    
    @Resource(name="studentService")
    private StudentServiceInf studentService;
    
    @Resource(name="classService")
    private ClassServiceInf classService;
    
    public void setStudentService(StudentServiceInf studentService) {
        this.studentService = studentService;
    }
    
    @RequestMapping(value="/start")
    public ModelAndView startStudent() throws Exception {
        ModelAndView mv = new ModelAndView();
        //調用業務層方法
        Class cls = new Class();
        List<Class> classList = classService.findClass(cls);
        if (classList.isEmpty()) {
            mv.addObject("clsIsNull", true);
        }
        mv.addObject("classList", classList);
        mv.setViewName("student");
        return mv;
    }
    
    @RequestMapping(value="/add")
    public ModelAndView addStudent(Student stu, Integer cid) throws Exception {
        stu.setCls(new Class(cid, ""));
        ModelAndView mv = new ModelAndView();
        //調用業務層方法
        studentService.addStudent(stu);
        mv.addObject("action", "addStudent");
        mv.setViewName("success");
        return mv;
    }
    
    @RequestMapping(value="/delete")
    public ModelAndView deleteStudent(Integer[] sids) throws Exception {
        System.out.println(Arrays.asList(sids));
        ModelAndView mv = new ModelAndView();
        //調用業務層方法
        studentService.deleteStudent(new ArrayList<Integer>(Arrays.asList(sids)));
        mv.addObject("action", "deleteStudent");
        mv.setViewName("success");
        return mv;
    }
    
    @RequestMapping(value="/find")
    public ModelAndView findStudent(Student stu, Integer cid) throws Exception {
        ModelAndView mv = new ModelAndView();
        
        //調用業務層方法
        stu.setCls(new Class(cid, ""));
        List<Student> studentList = studentService.findStudent(stu);
        
        if (studentList.isEmpty()) {
            mv.addObject("stuIsNull", true);
        }
        
        mv.addObject("student", stu);
        mv.addObject("studentList", studentList);
        mv.setViewName("forward:/student/start.action");
        return mv;
    }
}
StudentAction.java

 

  •   在此處寫了一個「/studdent/start.action」的起始action 目的是爲了向 「所屬班級」 的下拉選項動態傳入數據庫的值
  •   注意,若是須要接受表單傳來的多個同類對象(例如:多個須要刪除的id)應該使用數組進行接收(Integer[] sids),形參數組名必須與jsp中的name屬性保持一致

 

4、配置部分

  一、db.properties

    裏面設置MySql或者其餘數據庫的鏈接屬性,以及鏈接池的參數設置

mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/ssm
mysql.user=root
mysql.password=tiger

initialSize=0
maxActive=20  
maxIdle=20  
minIdle=1  
maxWait=60000
jdbc.properties

  二、applicationContext.xml

    a. 引入db.properties數據庫配置文件

    b. 創建鏈接池

      將數據庫配置的配置設置成參數傳入

    c. 創建sqlSessionFactory

      將 mybatis.xml + 鏈接池 + *Map.xml所在文件夾位置   三個屬性傳入

    d. 創建事務管理器

      將鏈接池傳入

    e. 配置事務管理器(聲明事務切入的包和類)

      註解實現 or 配置實現

    f. controller層的bean的註冊

      註冊各個DaoImp

      註冊各個ServiceImp(將對應Dao 以property注入)

<?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"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.1.xsd
        
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
        
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
        
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">

        <!-- 引入jdbc文件 -->
        <context:property-placeholder location="classpath:config/jdbc.properties"/>
        
        <!-- 經過上面的文件,配置鏈接池 -->
        <bean id="dataSourceID" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="${mysql.driver}"></property>
            <property name="jdbcUrl" value="${mysql.url}"></property>
            <property name="user" value="${mysql.user}"></property>
            <property name="password" value="${mysql.password}"></property>
        </bean>
        
        <!-- 加載mybatis文件 -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSourceID"></property>
            
            <property name="configLocation" value="classpath:config/mybatis.xml"></property>
            
            <property name="mapperLocations" value="classpath:beanMapper/*Mapper.xml"></property>
        </bean>
        
        <!-- 配置事務管理器 -->
        <bean id="transactionManager"
            class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSourceID"></property>
        </bean>
        
        <!-- 註釋實現事務 -->
        <!-- <tx:annotation-driven transaction-manager="transactionManager" /> -->
        
        <!-- 配置實現事務——指定方法 -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="add*" propagation="REQUIRED"/>
                <tx:method name="delete*" propagation="REQUIRED"/>
                <tx:method name="update*" propagation="REQUIRED"/>
                <tx:method name="find*" propagation="SUPPORTS"/>
            </tx:attributes>
        </tx:advice>
        
        <!-- 配置實現事務————指定事務切入的包和類 -->
        <aop:config>
            <aop:pointcut expression="execution(* dao.*.*(..))" id="pointcut"/>    
            <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
        </aop:config>
        
        <!-- 實例化Dao -->
        <bean id="classDao" class="dao.ClassDao">
            <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
        </bean>
        <bean id="studentDao" class="dao.StudentDao">
            <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
        </bean>
        
        
        <!-- 實例化Service -->
        <bean id="classService" class="service.ClassService">
            <property name="classDao" ref="classDao"></property>
        </bean>
        <bean id="studentService" class="service.StudentService">
            <property name="studentDao" ref="studentDao"></property>
        </bean>
</beans>
applicationContext.xml

 

  三、spring-mvc.xml

    一、配置Action層

      註解實現(掃描action包) or 配置實現(記得將Service注入)

      必須把Action層的聲明和掃描放在spring-mvc.xml裏面(由於是前端控制器完成action 的 mapping),不然報錯

    二、映射器配置

    三、適配器配置

    四、視圖解析器配置

<?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:mvc="http://www.springframework.org/schema/mvc" 
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.1.xsd
        
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">

        
        <!-- 實例化Action:由於是用註解實現的actionMapper因此用掃描的方式 -->
        <context:component-scan base-package="action"></context:component-scan>    
        
        <!-- 配置映射器(註解實現因此略) -->
        
        <!-- 配置適配器(略) -->
        
        <!-- 配置視圖解析器 -->
        <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/jsp/"></property>
            <property name="suffix" value=".jsp"></property>
        </bean>

</beans>
spring-mvc.xml

 

  四、 web.xml

    一、設置listener

    二、設置applicationContext.xml位置

      不要和spring-mvc.xml弄混了

    三、配置前段控制器

      servlet(此時用<init-para>聲明spring-mvc.xml位置)、servlet-mapping

    四、配置編碼過濾器

      filter、filter-mapping

    五、設置起始頁面

<?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_3_1.xsd" 
        version="3.1">
        
  <display-name>SSM-test</display-name>
  
  <listener>
    <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>
  
  
  <!-- 前段控制器(Spring核心控制器) -->
  <servlet>
      <servlet-name>springmvc</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
       <param-name>contextConfigLocation</param-name>
       <param-value>classpath:config/springmvc.xml</param-value>
      </init-param>
  </servlet>
  <servlet-mapping>
      <servlet-name>springmvc</servlet-name>
      <url-pattern>*.action</url-pattern>
  </servlet-mapping>
  
  
    <!-- 編碼過濾器 -->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <!-- 起始界面 -->
    <welcome-file-list>
        <welcome-file>jsp/MyJsp.jsp</welcome-file>
    </welcome-file-list>
</web-app>
web.xml

 

5、View部分

  一、編寫jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'MyJsp.jsp' starting page</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>
  
  <body>
          <a href="${pageContext.request.contextPath}/jsp/class.jsp">班級頁面</a>
          <a href="${pageContext.request.contextPath}/student/start.action">學生頁面</a>
  </body>
</html>
MyJsp.jsp(起始頁)
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'MyJsp.jsp' starting page</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>
  
  <body>
        <form action="${pageContext.request.contextPath}/class/add.action" method="post">
            <table align="center" border="2">
                <caption>添加班級</caption>
                <tr>
                    <th>班級名</th>
                    <td><input type="text" name="cname"></td>
                </tr>
                <tr align="center">
                    <td colspan="2">
                        <input type="submit" value="添加">
                    </td>
                </tr>
            </table>
        </form>  
  
          <form action="${pageContext.request.contextPath}/class/find.action" method="get">
              <table border="2" align="center">
              <caption> 搜索班級  </caption>
                  <tr>
                    <th>班級id</th>
                    <td><input type="text" name="cid" value="${cid}"></td>
                </tr>
                <tr>
                    <th>班級名</th>
                    <td><input type="text" name="cname" value="${cname}"></td>
                </tr>
              <tr align="center">
                  <td colspan="2"><input type="submit"></td>
              </tr>
              <tr>
                  <th>班級號</th>
                  <th>班級名</th>
              </tr>
              <tr>
                  <td colspan="2" align="center">
                      <c:if test="${isNull}"> 無相關記錄 </c:if>
                  </td>
              </tr>
              <c:forEach items="${classList}" var="cls">
                  <tr>
                      <td>${cls.cid}</td>
                      <td>${cls.cname}</td>
                  </tr>
              </c:forEach>
          </table>
          </form>
  </body>
</html>
class.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'MyJsp.jsp' starting page</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>
  
  <body>
        <form action="${pageContext.request.contextPath}/student/add.action" method="post">
            <table align="center" border="2">
                <caption>添加學生</caption>
                <tr>
                    <th>學生號</th>
                    <td><input type="text" name="sid"></td>
                </tr>
                <tr>
                    <th>學生名</th>
                    <td><input type="text" name="sname"></td>
                </tr>
                <tr>
                    <th>性別</th>
                    <td>
                        <select name="ssex">
                            <option value="1" selected="selected"></option>    
                            <option value="0"></option>    
                        </select>
                    </td>
                </tr>
                <tr>
                    <th>學生年齡</th>
                    <td><input type="text" name="sage"></td>
                </tr>
                <tr>
                    <th>所屬班級</th>
                    <td>
                        <select name="cid">
                            <c:forEach items="${classList}" var="cls">
                                <option value="${cls.cid}">${cls.cname}</option>
                            </c:forEach>
                        </select>
                    </td>
                </tr>
                <tr align="center">
                    <td colspan="2">
                        <input type="submit" value="添加">
                    </td>
                </tr>
            </table>
        </form>  
  
          <form action="${pageContext.request.contextPath}/student/find.action" method="get">
              <table border="2" align="center">
              <caption> 搜索學生  </caption>
                  <tr>
                    <th>學生號</th>
                    <td><input type="text" name="sid" value="${student.sid}"></td>
                </tr>
                <tr>
                    <th>學生名</th>
                    <td><input type="text" name="sname" value="${student.sname}"></td>
                </tr>
                <tr>
                    <th>性別</th>
                    <td>
                        <select name="ssex">
                            
                            <option value="1" ${(student.ssex == 1)?'selected="selected"':''}></option>    
                            <option value="0" ${(student.ssex == 0)?'selected="selected"':''}></option>
                            <option value="-1" ${(student.ssex == -1 || student == null )?'selected="selected"':''}>
                                請選擇
                            </option>    
                        </select>
                    </td>
                </tr>
                <tr>
                    <th>學生年齡</th>
                    <td><input type="text" name="sage">${student.sage}</td>
                </tr>
                <tr>
                    <th>所屬班級</th>
                    <td>
                        <select name="cid">
                            <c:forEach items="${classList}" var="cls">
                                <option value="${cls.cid}"  ${(student.cls.cid == cls.cid )?'selected="selected"':''}>${cls.cname}</option>
                            </c:forEach>
                            <option value="-1" ${(student.cls.cid == -1 || student == null )?'selected="selected"':''}>
                                請選擇
                            </option>
                            <c:if test="${clsIsNull}">
                                <option value="-1">
                                    無班級可選
                                </option>
                            </c:if>
                        </select>
                    </td>
                </tr>
              <tr align="center">
                  <td colspan="2"><input type="submit"></td>
              </tr>
          </table>
        </form>

        <form action="${pageContext.request.contextPath}/student/delete.action" method="get">
          <table border="2" align="center">
              <caption>學生信息表</caption>
              <tr>
                  <th>學號</th>
                  <th>姓名</th>
                  <th>性別</th>
                  <th>年齡</th>
                  <th>班級</th>
              </tr>
              <c:if test="${stuIsNull}">
                  <tr>
                      <td colspan="5" align="center">
                          無相關記錄
                      </td>
                  </tr>
              </c:if>
              <c:forEach items="${studentList}" var="stu">
                  <tr>
                      <td><input type="checkbox" value="${stu.sid}" name="sids">${stu.sid}</td>
                      <td>${stu.sname}</td>
                      <td>
                          <c:if test="${stu.ssex==0}"></c:if>
                          <c:if test="${stu.ssex==1}"></c:if>
                      </td>
                      <td>${stu.sage}</td>
                      <td>${stu.cls.cname}</td>
                  </tr>
              </c:forEach>
              <c:if test="${!stuIsNull}">
                  <tr>
                      <td colspan="5" align="center">
                          <input type="submit" value="刪除">
                      </td>
                  </tr>
              </c:if>
          </table>
          </form>
  </body>
</html>
student.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'success.jsp' starting page</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>
  
  <body>
          ${action}成功
  </body>
</html>
success.jsp

  幾個注意事項:(做爲一個作後端的強迫症患者,每次寫jsp都是莫大煎熬————但願好看,可是不會寫。。。)

  •   表單驗證通常用js來作,注意在jsp中將js引入

  •   下拉框的賦值同步(提交表單返回值後,傳過去的值仍然是選中的)可使用取值符的三目運算符來實現,例如:
<c:forEach items="${classList}" var="cls">
    <option value="${cls.cid}"  ${(student.cls.cid == cls.cid )?'selected="selected"':''}>${cls.cname}</option>
</c:forEach>

    這段代碼解決了「動態下拉框」,以及下拉框的賦值同步(單引號‘’在 <>中能夠忽略)

  • ${pageContext.request.contextPath} 與 <%=basePath%> 與 <%=path%>的區別
    •   首先看jsp內的java代碼
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

顯然 path

    只是顯示項目的名稱例如(SSM-test)

  basePath

     會顯示 訪問協議://服務器名:端口號/項目名                例如(http://127.0.0.1:8080/SSM-test/

    而且,在jsp眼裏,這只是一個字符串,不能跟表單數據,就算日後加上表單的數據(http://127.0.0.1:8080/SSM-test/add.action?sname='qqq'&sid=111)

    進行訪問最後也只是訪問(http://127.0.0.1:8080/SSM-test/add.action)

  ${pageContext.request.contextPath} 

  也是完整的域名路徑,不過有兩點不一樣:一、最後沒有「/」,而basePath有  二、在form的action中能夠跟表單數據

 

最後附上項目的文件放置:

 

以及SSM框架的流程圖:

  

導圖鏈接:https://www.processon.com/view/57eefd3ee4b0300f4fd1c3b9

其中Controller就是本文中的Action層啦。

 

SSM的流程其實主要就是Spring-mvc的流程: 

圖出處:https://blog.csdn.net/zuoluoboy/article/details/19766131

相關文章
相關標籤/搜索