案例实现ssm整合
整合之后关于查询多条数据所需要的pagehelper分页插件的使用见
https://blog.csdn.net/wilson27/article/details/89511816
以及springSecurity的使用、配置方法、心得见
https://blog.csdn.net/wilson27/article/details/89466268
第1章 产品介绍
1.1 数据库与表结构
产品表信息描述
序号 | 字段名称 | 字段类型 | 字段描述 |
---|---|---|---|
1 | id | int(11) | 主键自增 |
2 | productNum | varchar(50) | 产品编号,唯一不为空 |
3 | productName | varchar(50) | 产品名称 |
4 | cityName | varchar(50) | 出发城市 |
5 | departureTime | date | 出发时间 |
6 | productPrice | float | 产品价格 |
7 | productDesc | varchar(500) | 产品描述 |
8 | productStatus | int(1) | 产品状态,0关闭,1开启 |
创建表sql,为了方便实现主键自增
--建表
CREATE TABLE `product` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`productNum` varchar(50) DEFAULT NULL COMMENT '产品编号,唯一不为空',
`productName` varchar(50) DEFAULT NULL COMMENT '产品名称',
`cityName` varchar(50) DEFAULT NULL COMMENT '出发城市',
`departureTime` date DEFAULT NULL COMMENT '出发时间',
`productPrice` float DEFAULT NULL COMMENT '产品价格',
`productDesc` varchar(500) DEFAULT NULL COMMENT '产品描述',
`productStatus` int(1) DEFAULT NULL COMMENT '产品状态,0关闭,1开启',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
第2章 SSM集成
我们这里采用Maven项目分模块的方式实现,要创建的模块如下:
1. 创建ssm-parent父工程(打包方式选择pom,必须的)
2. 创建ssm-web子模块(打包方式是war包)
3. 创建ssm-service子模块(打包方式是jar包)
4. 创建ssm-dao子模块(打包方式是jar包)
5. 创建ssm-domain子模块(打包方式是jar包)
6. 创建ssm-util子模块(打包方式是jar包)
7. web依赖于service,service依赖于dao,dao依赖于domain,domain依赖util
2.1 ssm-parent
2.1.1pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lovejava</groupId>
<artifactId>ssm-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>../ssm-model</module>
<module>../ssm-dao</module>
<module>../ssm-service</module>
<module>../ssm-web</module>
<module>../ssm-util</module>
</modules>
<!--打包方式为pom-->
<packaging>pom</packaging>
<!--统一管理版本-->
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
<mysql.version>5.1.6</mysql.version>
<mybatis.version>3.4.5</mybatis.version>
<aspectjweaver.version>1.6.8</aspectjweaver.version>
<junit.version>4.12</junit.version>
<jsp-api.version>2.0</jsp-api.version>
<servlet-api.version>2.5</servlet-api.version>
<jstl.version>1.2</jstl.version>
<mybatis-spring.version>1.3.0</mybatis-spring.version>
<druid.version>1.0.9</druid.version>
<jackson-version>2.9.6</jackson-version>
<!--文件的编码格式-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<!--jar包管理,并不会将jar包导入到工程中-->
<dependencyManagement>
<!--引入依赖-->
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectjweaver.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!--用于SpringMVC-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!--用于数据库源相关操作-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<!--ServletAPI-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp-api.version}</version>
<scope>provided</scope>
</dependency>
<!--jstl标签-->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<!--MySQL数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--测试框架-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>compile</scope>
</dependency>
<!--
用于JSON数据转换
实现Json 互转 JavaBean
-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson-version}</version>
</dependency>
<!-- log start -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- log end -->
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!--MyBatis集成Spring-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring.version}</version>
</dependency>
<!--数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
2.1.2 创建工具包工程
紧接着我们把ssm-util也创建了,该工程用于提供工具类的。
创建jar包工程,名字叫ssm-util,集成ssm-parent
在其中创建一个类,提供时间转字符串类型。
public class DateUtils {
//时间格式
public static SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/***
* 时间格式转换
* @param date
* @return
*/
public static String dateToStr1(Date date){
return simpleDateFormat1.format(date);
}
}
2.2 ssm-model
创建Product即可
public class Product {
private Integer id;
private String productNum;
private String productName;
private String cityName;
private Date departureTime;
private Float productPrice;
private String productDesc;
private int productStatus;
//get..set..
}
在ssm-model的pom.xml中引入spring以及工具包的依赖
<!--依赖工具包-->
<dependencies>
<!--工具包-->
<dependency>
<groupId>com.lovejava</groupId>
<artifactId>ssm-util</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--Spring管理-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
2.3 ssm-dao
2.2.1 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ssm-parent</artifactId>
<groupId>com.lovejava</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../ssm-parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ssm-dao</artifactId>
<!--引入依赖-->
<dependencies>
<!--model的依赖-->
<dependency>
<groupId>com.lovejava</groupId>
<artifactId>ssm-model</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<!--MyBatis集成Spring-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</dependency>
<!--数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!--MySQL数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--SpringJdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<!-- log start -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<!-- log end -->
</dependencies>
</project>
2.2.2 spring-mybatis.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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="jdbc:mysql://127.0.0.1:3306/ssm" />
<property name="username" value="ssm" />
<property name="password" value="ssm" />
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
</bean>
<!--SqlSessionFactoryBean,spring继承Mybatis重点,集成spring后,这个类执行了mybatis中的工厂、动态代理等等操作。-->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入数据源-->
<property name="dataSource" ref="dataSource" />
</bean>
<!--接口扫描 MapperScannerConfigurer-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--指定Dao接口的包-->
<property name="basePackage" value="com.lovejava.dao" />
<!--
指定SqlSessionFactoryBeanName
在多数据源情况下,需要指定
-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean" />
</bean>
</beans>
2.2.3 ProductDao.java
public interface ProductDao {}
2.3 ssm-service
2.3.1 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ssm-parent</artifactId>
<groupId>com.lovejava</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../ssm-parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ssm-service</artifactId>
<!--打包jar-->
<packaging>jar</packaging>
<!--引入依赖-->
<dependencies>
<!--依赖dao-->
<dependency>
<groupId>com.lovejava</groupId>
<artifactId>ssm-dao</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- spring -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<!--springAOP-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
</dependencies>
</project>
2.3.2 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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:cache="http://www.springframework.org/schema/cache"
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.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- 事务传播特性配置 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- the transactional semantics... -->
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" isolation="DEFAULT"
rollback-for="java.lang.Exception" />
<tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT"
rollback-for="java.lang.Exception" />
<tx:method name="insert*" propagation="REQUIRED" isolation="DEFAULT"
rollback-for="java.lang.Exception" />
<tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT"
rollback-for="java.lang.Exception" />
<tx:method name="modify*" propagation="REQUIRED" isolation="DEFAULT"
rollback-for="java.lang.Exception" />
<tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT"
rollback-for="java.lang.Exception" />
<!-- 查询方法 -->
<tx:method name="query*" read-only="true" />
<tx:method name="select*" read-only="true" />
<tx:method name="find*" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 配置事务管理器 -->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 声明式事务AOP配置 -->
<aop:config>
<aop:pointcut expression="execution(* com.itheima.service.impl.*.*(..))"
id="tranpointcut" />
<!-- 事务控制 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="tranpointcut" />
</aop:config>
<!--引入mybatis集成配置-->
<import resource="spring-mybatis.xml" />
</beans>
2.3.3 ProductService接口
public interface ProductService {}
2.3.4 ProductServiceImpl
@Service
public class ProductServiceImpl implements ProductService {}
2.4 ssm-web
2.4.1 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ssm-parent</artifactId>
<groupId>com.lovejava</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../ssm-parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ssm-web</artifactId>
<packaging>war</packaging>
<dependencies>
<!--依赖service-->
<dependency>
<groupId>com.lovejava</groupId>
<artifactId>ssm-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--springmvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<!--JSON转换-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<!--servletAPI -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
</dependency>
</dependencies>
</project>
2.4.2 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"
id="WebApp_ID" version="3.0">
<!--POST编码过滤器-->
<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>
<!--前端核心控制器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--指定springmvc核心配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--启动加载优先级-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--映射拦截-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--欢迎页面-->
<welcome-file-list>
<welcome-file>index.shtml</welcome-file>
</welcome-file-list>
</web-app>
2.4.3 springmvc.xml
(包扫描,此处引入了spring的配置,所以配置springMVC一个扫描即可。如果没有引入,则需要分开扫描,原因是springMVC容器是spring容器的子容器,子容器可以访问父容器,父容器不可以访问子容器,spring加载了所有bean,springMVC只加载了controller类,所以springMVC作为子类可以访问到bean可以响应,如果只是spring扫描,将会发生404)
※※※※※※※※推荐将所有类放在spring MVC容器中。
疑问一: 单例的bean在父子容器中存在一个实例还是两个实例?
答:初始化两次,Spring 容器先初始化bean,MVC容器再初始化bean,所以应该是两个bean。
疑问二:为啥不把所有bean 都在子容器中扫描?
答: 网上很多文章说子容器不支持AOP,其实这是不对的。因为正常会有AOP的相关配置都在Spring容器中配置,如果都迁移到MVC配置文件,则所有bean都在子容器中,相当于只有一个容器了,所以也就实现了AOP。缺点是不利于扩展。
<?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/context
http://www.springframework.org/schema/context/spring-context.xsd
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">
<!--包扫描,此处引入了spring的配置,所以一个扫描即可,springMVC容器是spring容器的子类,子类可以访问父类,spring加载了所有bean,springMVC只加载了controller类,所以springMVC作为子类可以访问到bean可以响应-->
<context:component-scan base-package="com" />
<!--注解驱动-->
<mvc:annotation-driven />
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/pages/" />
<!--后缀-->
<property name="suffix" value=".jsp" />
</bean>
<!--静态资源过滤-->
<mvc:default-servlet-handler />
<!--引入spring.xml-->
<import resource="spring.xml" />
</beans>
2.4.4 ProductController
@Controller
@RequestMapping(value = "/product")
public class ProductController {}
第3章 产品功能模块
3.1 所有产品查询
3.1.1 Controller实现
@Controller
@RequestMapping(value = "/product")
public class ProductController {
@Autowired
private ProductService productService;
/***
* 商品列表查询
* @param model
* @return
*/
@RequestMapping(value = "/list")
public String list(Model model){
//集合查询
List<Product> products = productService.list();
model.addAttribute("products",products);
return "product-list";
}
}
3.1.2 Service实现
//接口
public interface ProductService {
List<Product> list();
}
//接口实现
@Service
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductDao productDao;
@Override
public List<Product> list() {
return productDao.list();
}
}
3.1.3 Dao实现
public interface ProductDao {
/**
* 查询所有
* @return
*/
@Select("select * from product")
List<Product> list();
}
3.1.4 页面显示 product-list.jsp
<!--数据列表-->
<table id="dataList"
class="table table-bordered table-striped table-hover dataTable">
<thead>
<tr>
<th class="" style="padding-right: 0px;"><input
id="selall" type="checkbox" class="icheckbox_square-blue">
</th>
<th class="sorting">产品编号</th>
<th class="sorting">产品名称</th>
<th class="sorting">出发城市</th>
<th class="sorting">出发日期</th>
<th class="sorting">价格</th>
<th class="sorting">描述</th>
<th class="sorting">状态</th>
<th class="text-center">操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${products}" var="product">
<tr>
<td><input name="ids" value="${product.id}" type="checkbox"></td>
<td>${product.productNum}</td>
<td>${product.productName}</td>
<td>${product.cityName}</td>
<td>
${product.departureTime}
</td>
<td>${product.productPrice}</td>
<td>${product.productDesc}</td>
<td>
${product.productStatus}
</td>
<td class="text-center">
<button type="button" class="btn bg-olive btn-xs"
onclick='del(${product.id})'>删除</button>
<button type="button" class="btn bg-olive btn-xs"
onclick='location.href="/product/one?id=${product.id}"'>查看</button>
</td>
</tr>
</c:forEach>
</tbody>
</table>
<!--数据列表/-->
3.1.5 日期格式解决
JSP页面显示的日期为默认的英文日期,转换成字符串格式有2种方式。
3.1.5.1 方案一
使用fmt标签进行转换
<!--引入头文件-->
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<fmt:formatDate value="${product.departureTime }" pattern="yyyy-MM-dd hh:mm:ss"/>
3.1.5.2 方案二
在JavaBean中添加属性,重写该属性的get方法进行转换
//添加该属性
private String departureTimeStr;
/**
* 重新get方法,返回字符串类型的时间
* @return
*/
public String getDepartureTimeStr() {
if(departureTime == null) {
return "";
}else {
return DateUtils.dateToStr(departureTime, "yyyy-MM-dd HH:mm:ss");
}
}
public class DateUtils {
/**
* 把日期转换成字符串
* @param date
* @return
*/
public static String dateToStr(Date date,String pattern) {
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
return sdf.format(date);
}
}
3.1.6 处理状态的问题
有2种方法实现
1)在JSP页面进行判断
<c:if test="${product.productStatus == 0 }">关闭</c:if>
<c:if test="${product.productStatus == 1 }">开启</c:if>
2)在JavaBean中添加属性,重写get方法
private String productStatusStr;
public String getProductStatusStr() {
return productStatus == 0?"关闭":"开启";
}
3.2 保存产品
3.2.1 Controller
在ProductController中增加2个方法,一个是跳转到增加页面,一个是实现增加,他们的访问路径一致,提交方式不一样。
/***
* 新增页面跳转
*/
@RequestMapping(value = "/add",method = RequestMethod.GET)
public String add(){
return "product-add";
}
/***
* 增加操作
* @return
*/
@RequestMapping(value = "/add",method = RequestMethod.POST)
public String add(Product product){
//增加数据
int acount = productService.add(product);
return "redirect:/product/list";
}
3.2.2 Service
新增一个add方法
//接口
int add(Product product);
//实现类
@Override
public int add(Product product) {
return productDao.add(product);
}
3.2.3 Dao
新增一个add方法,这里使用@Insert注解实现增加操作,代码如下:
/***
* 增加操作
* @param product
* @return
*/
@Insert("insert into product(productNum,productName,cityName,departureTime,productPrice,productDesc,productStatus)values(#{productNum},#{productName},#{cityName},#{departureTime},#{productPrice},#{productDesc},#{productStatus})")
int add(Product product);
3.2.4 页面 product-add.jsp
<form action="${pageContext.request.contextPath}/product/add" method="post">
<!-- 正文区域 -->
<section class="content"> <!--产品信息-->
<div class="panel panel-default">
<div class="panel-heading">产品信息</div>
<div class="row data-type">
<div class="col-md-2 title">产品编号</div>
<div class="col-md-4 data">
<input type="text" class="form-control" name="productNum"
placeholder="产品编号" value="">
</div>
<div class="col-md-2 title">产品名称</div>
<div class="col-md-4 data">
<input type="text" class="form-control" name="productName"
placeholder="产品名称" value="">
</div>
<div class="col-md-2 title">出发时间</div>
<div class="col-md-4 data">
<div class="input-group date">
<div class="input-group-addon">
<i class="fa fa-calendar"></i>
</div>
<input type="text" class="form-control pull-right"
id="datepicker-a3" name="departureTime">
</div>
</div>
<div class="col-md-2 title">出发城市</div>
<div class="col-md-4 data">
<input type="text" class="form-control" name="cityName"
placeholder="出发城市" value="">
</div>
<div class="col-md-2 title">产品价格</div>
<div class="col-md-4 data">
<input type="text" class="form-control" placeholder="产品价格"
name="productPrice" value="">
</div>
<div class="col-md-2 title">产品状态</div>
<div class="col-md-4 data">
<select class="form-control select2" style="width: 100%"
name="productStatus">
<option value="0" selected="selected">关闭</option>
<option value="1">开启</option>
</select>
</div>
<div class="col-md-2 title rowHeight2x">其他信息</div>
<div class="col-md-10 data rowHeight2x">
<textarea class="form-control" rows="3" placeholder="其他信息"
name="productDesc"></textarea>
</div>
</div>
</div>
<!--订单信息/--> <!--工具栏-->
<div class="box-tools text-center">
<button type="submit" class="btn bg-maroon">保存</button>
<button type="button" class="btn bg-default"
onclick="history.back(-1);">返回</button>
</div>
<!--工具栏/--> </section>
<!-- 正文区域 /-->
</form>
3.2.5 解决日期问题
在进行数据绑定的时候,日期出现了异常,该格式的日期不支持默认数据类型转换
3.2.5.1 自定义类型转换器
自定义类型转换器
3.2.5.2 在departureTime属性上添加注解解决
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm")
private Date departureTime;
3.2.5.3 @InitBinder
在Controller类中添加方法,进行类型转换
/**
* 类型转换
* @param dataBinder
*/
@InitBinder
public void initBinderDate(WebDataBinder dataBinder) {
dataBinder.registerCustomEditor(Date.class, new PropertiesEditor() {
// JSP页面传过来的数据
public void setAsText(String text) throws IllegalArgumentException {
// 把字符串转换成日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
try {
Date date = sdf.parse(text);
// 设置值
super.setValue(date);
} catch (ParseException e) {
e.printStackTrace();
}
}
});
}
3.3 修改产品
3.3.1 Controller
增加2个方法,一个是根据id查询产品,一个是保存方法
/***
* 修改产品
* @return
*/
@RequestMapping(value = "/update")
public String update(Product product){
int mcount = productService.update(product);
//redirect:重定向
return "redirect:/product/list";
}
/***
* 查询单个
* @param id
* @param model
* @return
*/
@RequestMapping(value = "/one")
public String getById(Long id,Model model){
Product product = productService.getById(id);
model.addAttribute("product",product);
return "product-update";
}
3.3.2 Service
分别在接口和实现类中新增2个方法
//接口 ProductService
Product getById(Long id);
int update(Product product);
//实现类 ProductServiceImpl
@Override
public Product getById(Long id) {
return productDao.getById(id);
}
@Override
public int update(Product product) {
return productDao.update(product);
}
3.3.3 Dao
新增2个方法,一个根据ID查询,一个修改方法。
/**
* 根据ID查询
* @param id
* @return
*/
@Select("select * from product where id=#{id}")
Product getById(Long id);
/***
* 修改操作
* @param product
* @return
*/
@Update("update product set productNum = #{productNum},productName=#{productName},cityName=#{cityName},departureTime=#{departureTime},productPrice=#{productPrice},productDesc=#{productDesc},productStatus=#{productStatus} where id = #{id}")
int update(Product product);
3.3.4 页面 product-update.jsp
<form action="${pageContext.request.contextPath}/product/update" method="post">
<input type="hidden" name="id" value="${product.id}">
<!-- 正文区域 -->
<section class="content"> <!--产品信息-->
<div class="panel panel-default">
<div class="panel-heading">产品信息</div>
<div class="row data-type">
<div class="col-md-2 title">产品编号</div>
<div class="col-md-4 data">
<input type="text" class="form-control" name="productNum"
placeholder="产品编号" value="${product.productNum}"
readonly="readonly">
</div>
<div class="col-md-2 title">产品名称</div>
<div class="col-md-4 data">
<input type="text" class="form-control" name="productName"
placeholder="产品名称" value="${product.productName}">
</div>
<div class="col-md-2 title">出发时间</div>
<div class="col-md-4 data">
<div class="input-group date">
<div class="input-group-addon">
<i class="fa fa-calendar"></i>
</div>
<input type="text" class="form-control pull-right"
id="datepicker-a3" name="departureTime"
value="${product.departureTimeStr}">
</div>
</div>
<div class="col-md-2 title">出发城市</div>
<div class="col-md-4 data">
<input type="text" class="form-control" name="cityName"
placeholder="出发城市" value="${product.cityName}">
</div>
<div class="col-md-2 title">产品价格</div>
<div class="col-md-4 data">
<input type="text" class="form-control" placeholder="产品价格"
name="productPrice" value="${product.productPrice}">
</div>
<div class="col-md-2 title">产品状态</div>
<div class="col-md-4 data">
<select class="form-control select2" style="width: 100%"
name="productStatus">
<option value="0" selected="selected">关闭</option>
<option value="1">开启</option>
</select>
</div>
<div class="col-md-2 title rowHeight2x">其他信息</div>
<div class="col-md-10 data rowHeight2x">
<textarea class="form-control" rows="3" placeholder="其他信息"
name="productDesc">${product.productDesc}</textarea>
</div>
</div>
</div>
<!--订单信息/--> <!--工具栏-->
<div class="box-tools text-center">
<button type="submit" class="btn bg-maroon">修改</button>
<button type="button" class="btn bg-default"
onclick="history.back(-1);">返回</button>
</div>
<!--工具栏/--> </section>
<!-- 正文区域 /-->
</form>
3.4 删除产品
3.4.1 Controller层
/***
* 根据ID删除
* @param id
* @return
*/
@RequestMapping(value = "/delete")
public String delete(Integer id){
int dcount = productService.deleteById(id);
return "redirect:/product/list";
}
3.4.2 Service层
//接口
int deleteById(Integer id);
//实现类
@Override
public int deleteById(Integer id) {
return productDao.deleteById(id);
}
3.4.3 Dao层
/***
* 删除操作
* @param id
* @return
*/
@Delete("delete from product where id=#{id}")
int deleteById(Integer id);
第4章 订单模块功能
4.1 订单表与产品表的关系
- 一个用户只会产生一个订单,一个订单只能选择一个产品,因为是旅游产品。
- 一个产品可以被多个订单所选择。
- 订单表与产品表的关系是多对一
- 订单表的SQL语句
- 订单表信息描述 orders
序号 | 字段名称 | 字段类型 | 字段描述 |
---|---|---|---|
1 | id | bigint(20) | 主键自增 |
2 | orderNum | varchar(20) | 订单编号,唯一值 |
3 | orderTime | date | 下单时间 |
4 | peopleCount | int(5) | 出行人数 |
5 | orderDesc | varchar(500) | 订单描述 |
6 | payType | int(1) | 支付方式(0支付宝,1微信,2其他) |
7 | orderStatus | int(1) | 订单状态(0未支付,1已支付) |
8 | productId | bigint(20) | 产品ID外键 |
productId描述了订单与产品之间的关系。
4.2 创建表sql
CREATE TABLE `orders` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键自增',
`orderNum` varchar(20) NOT NULL COMMENT '订单编号,唯一值',
`orderTime` date DEFAULT NULL COMMENT '下单时间',
`peopleCount` int(5) DEFAULT NULL COMMENT '出行人数',
`orderDesc` varchar(500) DEFAULT NULL COMMENT '订单描述',
`payType` int(1) DEFAULT NULL COMMENT '支付方式(0支付宝,1微信,2其他)',
`orderStatus` int(1) DEFAULT NULL COMMENT '订单状态(0未支付,1已支付)',
`productId` bigint(20) DEFAULT NULL COMMENT '产品ID外键',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
4.3 搭建订单模块的环境
4.3.1 创建Orders
public class Orders {
private Long id;
private String orderNum;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
private Date orderTime;
private Integer peopleCount;
private String orderDesc;
private Integer payType;
private Integer orderStatus;
//private Long productId;
//一对一映射关系
private Product product;
//get..set..toString
}
4.3.2 订单查询
4.3.2.1 创建Controller
@Controller
@RequestMapping(value = "/orders")
public class OrdersController {
@Autowired
private OrdersService ordersService;
/***
* 订单列表
* @param model
* @return
*/
@RequestMapping(value = "/list")
public String list(Model model){
List<Orders> orders = ordersService.list();
model.addAttribute("orders",orders);
return "order-list";
}
}
4.3.2.2 Service
//接口
public interface OrdersService {
List<Orders> list();
}
//实现类
@Service
public class OrdersServiceImpl implements OrdersService {
@Autowired
private OrdersDao ordersDao;
@Override
public List<Orders> list() {
return ordersDao.list();
}
}
4.3.2.3 Dao
public interface OrdersDao {
/**
* 查询所有
*
* @return
*/
@Select("select o.id as oid,o.orderNum,o.orderTime,o.peopleCount,o.orderDesc,o.payType,o.orderStatus,p.* from orders o,product p where o.productId = p.id")
@Results(value = {
@Result(id = true, property = "id", column = "oid"),
@Result(property = "orderNum", column = "orderNum"),
@Result(property = "orderTime", column = "orderTime"),
@Result(property = "peopleCount", column = "peopleCount"),
@Result(property = "orderDesc", column = "orderDesc"),
@Result(property = "payType", column = "payType"),
@Result(property = "orderStatus", column = "orderStatus"),
@Result(property = "product.id", column = "id"),
@Result(property = "product.productNum", column = "productNum"),
@Result(property = "product.productName", column = "productName"),
@Result(property = "product.cityName", column = "cityName"),
@Result(property = "product.departureTime", column = "departureTime"),
@Result(property = "product.productPrice", column = "productPrice"),
@Result(property = "product.productDesc", column = "productDesc"),
@Result(property = "product.productStatus", column = "productStatus")
})
List<Orders> list();
}
4.3.2.4 页面 product-list.jsp
<!--数据列表-->
<table id="dataList"
class="table table-bordered table-striped table-hover dataTable">
<thead>
<tr>
<th class="" style="padding-right: 0px;"><input
id="selall" type="checkbox" class="icheckbox_square-blue">
</th>
<th class="sorting">产品编号</th>
<th class="sorting">产品名称</th>
<th class="sorting">出发城市</th>
<th class="sorting">出发日期</th>
<th class="sorting">价格</th>
<th class="sorting">描述</th>
<th class="sorting">状态</th>
<th class="text-center">操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${products}" var="product">
<tr>
<td><input name="ids" value="${product.id}" type="checkbox"></td>
<td>${product.productNum}</td>
<td>${product.productName}</td>
<td>${product.cityName}</td>
<td>
${product.departureTimeStr}
<fm:formatDate value="${product.departureTime}" pattern="yyyy-MM-dd hh:mm:ss" />
</td>
<td>${product.productPrice}</td>
<td>${product.productDesc}</td>
<td>
<c:if test="${product.productStatus == 0 }">关闭</c:if>
<c:if test="${product.productStatus == 1 }">开启</c:if>
</td>
<td class="text-center">
<button type="button" class="btn bg-olive btn-xs"
onclick='del(${product.id})'>删除</button>
<button type="button" class="btn bg-olive btn-xs"
onclick='location.href="/product/one?id=${product.id}"'>查看</button>
</td>
</tr>
</c:forEach>
</tbody>
</table>
<!--数据列表/-->
4.3.3 新增订单
4.3.3.1 Controller
新增2个方法,分别实现页面跳转和保存订单操作。在这里,页面需要加载产品信息供用户选择,所以需要注入ProductService来实现查询.
@Autowired
private ProductService productService;
/**
* 保存操作
* @param orders
* @return
*/
@RequestMapping(value = "/add",method = RequestMethod.POST)
public String add(Orders orders){
int acount = ordersService.add(orders);
return "redirect:/orders/list";
}
/***
* 增加订单页面跳转
* @return
*/
@RequestMapping(value = "/add",method = RequestMethod.GET)
public String add(Model model){
//查询所有产品信息,页面需要加载,所以需要注入ProductService来实现查询
List<Product> products = productService.list();
model.addAttribute("products",products);
return "order-add";
}
4.3.3.2 Service
//接口
int add(Orders orders);
//实现类
@Override
public int add(Orders orders) {
return ordersDao.add(orders);
}
4.3.3.3 Dao
/**
* 插入数据操作
* @param orders
* @return
*/
@Insert("insert into orders (orderNum,orderTime,peopleCount,orderDesc,payType,orderStatus,productId) values (#{orderNum},#{orderTime},#{peopleCount},#{orderDesc},#{payType},#{orderStatus},#{product.id})")
int add(Orders orders);
重点:
增加订单
订单查询
时间格式处理
熟练@Insert、@Select、@Update、@Delete注解的使用