引子
随着SSM的流行,可以看到现在大多数公司都在转向SSM模式的开发框架,所谓SSM指的是Spring mvc+Spring+MyBatis, 小编最近也在研究SSM框架,把最近的学习进度和成功在这里给大家做一个分享。便于大家学习交流。
框架
小编这里搭建的SSM框架,主要包括服务层,业务层,数据层,每层又进行了单独拆分,数据库这里使用的是mysql, 服务层这里搭建的是rest服务. 先看下项目结构图和框架图。
数据层
创建表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>
数据层是直接操作数据库的层,这里创建数据库操作的API,在erp-dao-api中添加ProductDao.java文件,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: 用来处理请求地址映射的注解宿主
框架搭建完毕后,我们这里要有宿主来启动服务,这里使用webapp作为宿主,创建
supersoft-erp-webapp项目
添加mybatis连接的配置
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进行发送