引子


  随着SSM的流行,可以看到现在大多数公司都在转向SSM模式的开发框架,所谓SSM指的是Spring mvc+Spring+MyBatis, 小编最近也在研究SSM框架,把最近的学习进度和成功在这里给大家做一个分享。便于大家学习交流。


框架


  小编这里搭建的SSM框架,主要包括服务层,业务层,数据层,每层又进行了单独拆分,数据库这里使用的是mysql, 服务层这里搭建的是rest服务. 先看下项目结构图和框架图。




ssm项目系统架构设计 ssm项目结构_spring mvc



ssm项目系统架构设计 ssm项目结构_java_02


数据层


创建表sql
  CREATE TABLE `product` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `code` char(10) NOT NULL DEFAULT '',
  `name` char(35) NOT NULL DEFAULT '',
  `color` char(30) DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8


在 supersoft.erp.domain项目中创建domain对象


public class Product {

      private String code;

      private String name;

      private String color;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}


在erp-dao-mybatis中添加ProductMapper.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="org.supersoft.erp.dao.api.ProductDao">

<!-- useGeneratedKeys="true" keyProperty="id" 添加方法-->
    <insert id="add" parameterType="Product" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO product (CODE,NAME,color) VALUES(
        #{code},#{name}, #{color})
    </insert>

    <!-- 更新 -->
        <update id="update"  parameterType="Product" >
    <![CDATA[
        UPDATE product SET
            name = #{name} ,
            color = #{color} 
        WHERE 
            code = #{code} 
    ]]>
    </update>

    <!-- 删除 -->
    <delete id="deleteByCode"  parameterType="String">
    <![CDATA[
        DELETE FROM product WHERE
        code =  #{value} 
    ]]>
    </delete>

     <select id="findOne" parameterType="String" resultType="Product">
        SELECT 
           code,name,color
            FROM product 
            WHERE 
                code = #{value} 

    </select>


       <!-- 分页查询 -->
         <select id="findAll" parameterType="hashmap"  resultType="Product">
               SELECT 
              code,name,color
            FROM product  where 1=1
            <if test="code!= null and code!= '' ">
                and code = #{code}
           </if>
             <if test="name!= null and name!= '' ">
                and name = #{name}
             </if>
              limit  ${page}, ${pageSize}
         </select>

        <!-- 查询总的数量 -->
       <select id="count" resultType="long"   parameterType="hashmap">
        SELECT count(*) FROM product  where 1=1
          <if test="code!= null and code!= '' ">
                and code = #{code}
           </if>
             <if test="name!= null and name!= '' ">
                and name = #{name}
             </if>
       </select>
</mapper>


erp-dao-api的实现就是erp-dao-mybatis


package org.supersoft.erp.dao.api;

import java.util.List;
import java.util.Map;

import org.supersoft.erp.domain.Product;

public interface ProductDao {

    /**
     * 添加
     * @param product
     */
    public void add(Product product);

    /**
     * 更新
     * @param entity
     */
    public void update(Product entity);


    /**
     * 根据条码删除
     * @param code
     */
    public void deleteByCode(String code);


    /**
     * 查找一个
     *
     * @param code
     * @return
     */
    public Product findOne(String code);


    /**
     * 查询所有
     * @param query
     * @return
     */
    public List<Product> findAll(Map<String, Object> query);

    /**
     * 统计个数
     *
     * @param 查找条件
     * @return
     */
    public long count(Map<String, Object> query);
}


业务层


erp-service-api和 erp-service-impl,


package org.supersoft.erp.service.api;

import java.util.List;
import java.util.Map;

import org.supersoft.erp.domain.Product;


public interface ProductService {

    /**
     * 添加商品
     * @param product
     */
    void addProduct(Product product);

    /**
     * 更新商品
     * @param product
     */
    void updateProduct(Product product);

    /**
     * 根据编码删除商品
     * @param code
     */
    void deleteProduct(String code);

    /**
     * 查找单个商品
     * @param code
     * @return
     */
    Product findOneProduct(String code);

    /**
     * 查询所有产品
     * @param query
     * @return
     */
     List<Product> findAllProduct(Map<String, Object> query);

     /**
      * 查询总的数量
      * @param query
      * @return
      */
     long count(Map<String, Object> query);
}


服务实现ProductServiceImpl.java


package org.supersoft.erp.service.impl;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.supersoft.erp.dao.api.ProductDao;
import org.supersoft.erp.domain.Product;
import org.supersoft.erp.service.api.ProductService;

@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductDao productDao;

    /**
     * 添加商品
     */
    public void addProduct(Product product) {
        if(product == null){
            throw new IllegalArgumentException();
        }

        productDao.add(product);
    }

    /**
     * 更新商品
     */
    public void updateProduct(Product product) {
        if(product == null){
            throw new IllegalArgumentException();
        }
        productDao.update(product);

    }

    /**
     * 删除商品
     */
    public void deleteProduct(String code) {

        productDao.deleteByCode(code);
    }

    /**
     * 查找单个商品
     */
    public Product findOneProduct(String code) {
        return productDao.findOne(code);
    }

    public List<Product> findAllProduct(Map<String, Object> query) {
         return productDao.findAll(query);
    }

    public long count(Map<String, Object> query) {
        return productDao.count(query);
    }
}


业务层


业务层是直接提供对外服务的接口,也就是采用spring mvc框架来实现的。这里业务层也包括接口和接口实现


package org.supersoft.erp.rest.api;

import java.util.List;

import org.supersoft.erp.common.CommonResponse;
import org.supersoft.erp.common.ServiceResponse;
import org.supersoft.erp.domain.Product;
import org.supersoft.erp.rest.dto.ProductDto;
import org.supersoft.erp.rest.dto.ProductQueryDto;

public interface ProductController {

    /**
     * 
     * @param 添加商品
     * @return
     */
    CommonResponse<?> addProduct(ProductDto product);

    /**
     * 
     * @param 修改商品
     * @return
     */
    CommonResponse<?> updateProduct(ProductDto product);


    /**
     * 根据编码删除
     * @param code
     * @return
     */
    CommonResponse<?> delProduct(String code);

    /**
     * 查询单个记录
     * @param entity
     * @return
     */

    CommonResponse<Product> findOneProduct(String code);


    /**
     * 查询多条记录
     * @param query
     * @return
     */
     CommonResponse<List<Product>> findAllProduct(ProductQueryDto query);
}



package org.supersoft.erp.rest.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.supersoft.erp.common.CommonResponse;
import org.supersoft.erp.common.Page;
import org.supersoft.erp.common.ServiceResponse;
import org.supersoft.erp.domain.Product;
import org.supersoft.erp.rest.api.ProductController;
import org.supersoft.erp.rest.dto.ProductDto;
import org.supersoft.erp.rest.dto.ProductQueryDto;
import org.supersoft.erp.service.api.ProductService;


@RestController
@RequestMapping("product")
public class ProductControllerImpl implements ProductController {

    @Autowired
    private ProductService productService;

    /**
     * 添加
     */
    @RequestMapping(value = "save", method = RequestMethod.POST)
    @ResponseBody
    public CommonResponse<?> addProduct(@RequestBody ProductDto product) {
        try
        {
            Product p=new Product();
            BeanUtils.copyProperties(product, p);
            productService.addProduct(p);
            return CommonResponse.result();
        }
        catch(Throwable t)
        {
            return CommonResponse.error();
        }
    }

    /**
     * 修改
     */
    @RequestMapping(value = "update", method = RequestMethod.POST)
    @ResponseBody
    public CommonResponse<?> updateProduct(@RequestBody ProductDto product) {
        try
        {
            Product p=new Product();
            BeanUtils.copyProperties(product, p);
            productService.updateProduct(p);
            return CommonResponse.result();
        }
        catch(Throwable t)
        {
            return CommonResponse.error();
        }
    }

    /**
     * 删除商品
     */
    @RequestMapping(value = "delete", method = RequestMethod.POST)
    @ResponseBody
    public CommonResponse<?> delProduct(@RequestParam String code) {
        try
        {
            productService.deleteProduct(code);
            return CommonResponse.result();
        }
        catch(Throwable t)
        {
            return CommonResponse.error();
        }
    }

    /**
     * 查找单个商品
     * @param code
     * @return
     */
    @RequestMapping(value = "get", method = RequestMethod.POST)
    @ResponseBody
    public CommonResponse<Product> findOneProduct(@RequestParam String code) {
        try
        {
            Product p=productService.findOneProduct(code);
            return CommonResponse.result(p);
        }
        catch(Throwable t)
        {
            return CommonResponse.error();
        }
    }

    /**
     * 按条件查询
     */
    @RequestMapping(value = "list", method = RequestMethod.POST)
    @ResponseBody
    public CommonResponse<List<Product>> findAllProduct(@RequestBody ProductQueryDto query) {
        try
        {
            Map<String,Object> map=new HashMap<String,Object>();
            map.put("code", query.getCode());
            map.put("pageIndex", query.getPageIndex());
            map.put("pageSize", query.getPageSize());
            map.put("name", query.getName());
            List<Product> list=productService.findAllProduct(map);
            return CommonResponse.result(list);
        }
        catch(Throwable t)
        {
            return CommonResponse.error();
        }
    }

    @RequestMapping(value = "count", method = RequestMethod.POST)
    @ResponseBody
    public CommonResponse<Long> countProduct(@RequestBody ProductQueryDto query)
    {
        try
        {
            Map<String,Object> map=new HashMap<String,Object>();
            map.put("code", query.getCode());
            map.put("pageIndex", query.getPageIndex());
            map.put("pageSize", query.getPageSize());
            map.put("name", query.getName());
            Long count=productService.count(map);
            return CommonResponse.result(count);
        }
        catch(Throwable t)
        {
            return CommonResponse.error();
        }
    }

    /**
     * 分页查询
     * @param query
     * @return
     */
    @RequestMapping(value = "page", method = RequestMethod.POST)
    @ResponseBody
    public CommonResponse<Page<Product>> findPageOrder(@RequestBody ProductQueryDto query)
    {
        try {
            Map<String,Object> map=new HashMap<String,Object>();
            map.put("code", query.getCode());
            map.put("pageSize", query.getPageSize());
            map.put("name", query.getName());
            map.put("page", (query.getPageIndex()-1)*query.getPageSize());


            List<Product> list =productService.findAllProduct(map);
            long total = productService.count(map);

            return CommonResponse.result(new Page<Product>(list, total));
        } catch (Throwable t) {
            return CommonResponse.error();
        }

    }

}



@RestController:标明是接口是rest服务


@RequestBody: 注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上


@ResponseBody: 用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区,

                              返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用

@RequestMapping: 用来处理请求地址映射的注解

宿主


supersoft-erp-webapp项目


spring-dao-connection.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"  
    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.1.xsd    
                        http://www.springframework.org/schema/context    
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd    
                        http://www.springframework.org/schema/mvc    
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> 

<!--     <context:property-placeholder location="classpath*:log4j.properties" /> -->

    <!-- 启用注解 -->
    <context:annotation-config />


    <bean id="hyjDataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/world?characterEncoding=utf8" />
        <property name="username" value="root" />
        <property name="password" value="123456" />
    </bean>
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="hyjDataSource" />
        <property name="configLocation" value="classpath:spring-dao-mybatis.xml" />
        <property name="mapperLocations" value="classpath*:*Mapper.xml" />
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="org.supersoft.erp.dao.api" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    </bean>
</beans>



实体对象别名配置spring-dao-mybatis.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>

    <typeAliases>
        <package name="org.supersoft.erp.domain" />
    </typeAliases>

</configuration>


spring.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:tx="http://www.springframework.org/schema/tx"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-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/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <!-- spring扫描包 -->
    <context:component-scan base-package="org.supersoft.erp.service.impl" />

    <!-- 加载mybatis数据库连接配置文件 -->
    <import resource="classpath:spring-dao-connection.xml" />

</beans>




spring mvc配置文件erp-servlet.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        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.xsd">

<!-- 扫描spring mvc controller -->
    <context:component-scan base-package="org.supersoft.erp.rest.impl" />

    <beans:bean
        class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
    <beans:bean
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

    <!-- Enables the Spring MVC @Controller programming model -->
    <annotation-driven />

    <!-- for processing requests with annotated controller methods and set Message 
        Convertors from the list of convertors -->
    <beans:bean
        class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <beans:property name="messageConverters">
            <beans:list>
                <beans:ref bean="jsonMessageConverter" />
            </beans:list>
        </beans:property>
    </beans:bean>

    <!-- To convert JSON to Object and vice versa -->
    <beans:bean id="jsonMessageConverter"
        class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    </beans:bean>

</beans:beans>


配置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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">
    <display-name>ERP app</display-name>

    <!-- 加载spring配置 -->
   <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring.xml</param-value>
    </context-param>

    <!-- 监听器 -->
   <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- 过滤器 -->
    <filter>
        <filter-name>CORS</filter-name>
        <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>

        <init-param>
            <param-name>cors.allowOrigin</param-name>
            <param-value>*</param-value>
        </init-param>
        <init-param>  
            <param-name>cors.supportedMethods</param-name> 
            <param-value>GET, POST, HEAD, PUT, DELETE</param-value> 
        </init-param>  
        <init-param>  
            <param-name>cors.supportedHeaders</param-name> 
            <param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified,currentUserId,currentUserName</param-value> 
        </init-param>  
    </filter>

    <filter-mapping>  
        <filter-name>CORS</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>

    <!-- spring mvc核心配置文件 erp-servlet.xml -->
    <servlet>
        <servlet-name>erp</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>erp</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>


部署服务到tomat就可以进行访问测试了。


 客户端调用 


客户端访问可以使用浏览器自动的http请求工具,这里使用谷歌浏览器的DHC进行发送



ssm项目系统架构设计 ssm项目结构_框架_03