权限管理、旅游系统前篇

1.功能介绍

1.1 环境搭建

主要讲解maven工程搭建,以及基于Oracle数据库的商品表信息,并完成SSM整合。

1.2 商品查询

基于SSM整合基础上完成商品查询,要掌握主面页面main.jsp及商品显示页面product-list.jsp页面的创建。

1.3 商品添加

进一步巩固SSM整合,并完成商品添加功能,要注意事务操作以及product-add.jsp页面生成。

1.4 订单查询

订单的查询操作,它主要完成简单的多表查询操作,查询订单时,需要查询出与订单关联的其它表中信息,所以大

家一定要了解订单及其它表关联关系

1.5 订单分页查询

订单分页查询,我们使用的是mybatis分页插件PageHelper,要掌握PageHelper的基本使用。

1.6 订单详情查询

订单详情是用于查询某一个订单的信息,这个知识点主要考核学生对复杂的多表查询操作的掌握。

1.7 Spring Security 概述

Spring Security是 Spring 项目组中用来提供安全认证服务的框架,它的使用很复杂,我们在课程中只介绍了spring Security的基本操作,大家要掌握spring Security框架的配置及基本的认证与授权操作。

1.8 用户管理

用户管理中我们会介绍基于spring Security的用户登录、退出操作。以及用户查询、添加、详情有等操作,这些功能的练习是对前期SSM知识点的进一步巩固。

1.9 角色管理

角色管理主要完成角色查询、角色添加

1.10 资源权限管理

资源权限管理主要完成查询、添加操作,它的操作与角色管理类似,角色管理以及资源权限管理都是对权限管理的

补充。

1.11 权限关联与控制

主要会讲解用户角色关联、角色权限关联,这两个操作是为了后续我们完成授权操作的基础,关于授权操作我们会

在服务器端及页面端分别讲解

1.12 AOP日志处理

AOP日志处理,我们使用spring AOP切面来完成系统级别的日志收集。

2.数据库介绍

2.1 产品表

60006951393

2.2 订单表

60006953852

2.3 会员表

60006955217

2.4 旅客表

60006956592

2.5 用户表

60006958979

2.6角色表

60006965255

2.7资源权限表

60006967372

2.8 日志表

60006968966

SSM 环境搭建与产品操作

1.环境准备

1.1 数据库与表结构

1.1.1 创建用户与授权

数据库我们使用Oracle

Oracle 为每个项目创建单独user,oracle数据表存放在表空间下,每个用户有独立表空间创建用户及密码:

语法[创建用户]: create user 用户名 identified by 口令[即密码];
例子: create user test identified by test;

授权


语法: grant connect, resource to 用户名;
例子: grant connect, resource to test;

PL/SQL Developer是一个集成开发环境,专门面向Oracle数据库存储程序单元的开发PL/SQL Developer侧重于易用性、代码品质和生产力,充分发挥Oracle应用程序开发过程中的主要优势。

连接oracle数据库

a) 创建用户

60006993926

60006994656

60006995296

b) 授权

60006996195

对象权限是指针对于某一张表的操作权限,系统权限是指对表的CRUD操作权限, 角色权限是系统权限的集合,我们设置 时,一般是设置角色权限,设置resource与connect

1.1.2 创建表

产品表信息描述

序号 字段名称 字段类型 字段描述
1 id varchar2(32) 无意义,主键uuid
2 productNum varchar2(50) 产品编号,唯一,不为空
3 productName varchar2(50) 产品名称(路线名称)
4 cityName varchar2(50) 出发城市
5 DepartureTime timestamp 出发时间
6 productPrice number 产品价格
7 productDesc varchar2(500) 产品描述
8 productStatus int 状态(0 关闭 1 开启)

创建表sql

CREATE TABLE product(
id varchar2(32) default SYS_GUID() PRIMARY KEY,
productNum VARCHAR2(50) NOT NULL, productName VARCHAR2(50),
cityName VARCHAR2(50), DepartureTime timestamp, productPrice Number, productDesc VARCHAR2(500), productStatus INT,
CONSTRAINT product UNIQUE (id, productNum)
)

insert into PRODUCT (id, productnum, productname, cityname, departuretime, productprice,
productdesc, productstatus)
values ('676C5BD1D35E429A8C2E114939C5685A', 'itcast-002', '北京三日游', '北京', to_timestamp('10- 10-2018 10:10:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 1200, '不错的旅行', 1);
insert into PRODUCT (id, productnum, productname, cityname, departuretime, productprice,
productdesc, productstatus)
values ('12B7ABF2A4C544568B0A7C69F36BF8B7', 'itcast-003', '上海五日游', '上海', to_timestamp('25- 04-2018 14:30:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 1800, '魔都我来了', 0);
insert into PRODUCT (id, productnum, productname, cityname, departuretime, productprice,
productdesc, productstatus)
values ('9F71F01CB448476DAFB309AA6DF9497F', 'itcast-001', '北京三日游', '北京', to_timestamp('10- 10-2018 10:10:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 1200, '不错的旅行', 1);

1.2 maven工程搭建

1.2.1 创建maven工程

60007007741

60007008501

60007009003

创建子模块

itcast-ssm-web itcast-ssm-domain itcast-ssm-service itcast-ssm-dao itcast-ssm-utils 其中创建itcast-ssm-web时注意我们选择一个web工程

60007011447

1.2.2 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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.jk.jk_ssm</groupId>
    <artifactId>jk_ssm</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <!-- 统一管理jar包版本 -->
    <properties>
        <spring.version>5.0.2.RELEASE</spring.version>
        <slf4j.version>1.6.6</slf4j.version>
        <log4j.version>1.2.12</log4j.version>
        <shiro.version>1.2.3</shiro.version>
        <mysql.version>5.1.6</mysql.version>
        <mybatis.version>3.4.5</mybatis.version>
        <spring.security.version>5.0.1.RELEASE</spring.security.version>
    </properties>

    <!-- 锁定jar包版本 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</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-webmvc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- 项目依赖jar包 -->
    <dependencies>
        <!-- spring -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.8</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</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-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</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 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>${mybatis.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.0</version>
        </dependency>
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>${spring.security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>${spring.security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>${spring.security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
            <version>${spring.security.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.9</version>
        </dependency>
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>jsr250-api</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>
    <!-- 添加tomcat7插件 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
            </plugin>
        </plugins>
    </build>


    <modules>
        <module>jk_ssm_dao</module>
        <module>jk_ssm_service</module>
        <module>jk_ssm_domain</module>
        <module>jk_ssm_utils</module>
        <module>jk_ssm_web</module>
    </modules>


</project>

1.3编写实体类

/**
 * @outhor Mr.JK
 * @create 2020-05-01  10:52
 * 产品
 */
public class Product {
    private Integer id; // 主键
    private String productNum; // 编号 唯一
    private String productName; // 名称
    private String cityName; // 出发城市
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
    private Date departureTime; // 出发时间
    private String departureTimeStr;
    private double productPrice; // 产品价格
    private String productDesc; // 产品描述
    private Integer productStatus; // 状态 0 关闭 1 开启
    private String productStatusStr;
}

1.4 编写业务接口

public interface IProductService {

	List<Product> findAll() throws Exception;
}

1.5 编写持久层接口

public interface IProductDao {
	@Select("select * from product") 
    List<Product> findAll() throws Exception;
}

2.SSM整合与产品查询

2.1 Spring环境搭建

2.1.1.编写Spring配置文件applicationContext.xml

<!-- 配置 spring 创建容器时要扫描的包 --> 
<!-- 开启注解扫描,管理service和dao -->
<context:component-scan base-package="com.itheima.ssm.service"> 
</context:component-scan>
<context:component-scan base-package="com.itheima.ssm.dao"> 
</context:component-scan>

2.1.2.使用注解配置业务层

@Service
public class ProductServiceImpl implements IProductService{

    @Override
    public List<Product> findAll() throws Exception {
    	return null;
    }
}

2.2 Spring MVC 环境搭建

2.2.1.web.xml配置Spring MVC核心控制器

<!-- 前端控制器(加载classpath:spring-mvc.xml 服务器启动创建servlet) -->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 配置初始化参数,创建完DispatcherServlet对象,加载springmvc.xml配置文件 -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <!-- 服务器启动的时候,让DispatcherServlet对象创建 -->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>*.do</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>

2.2.2.Spring MVC配置文件springmvc.xml

<!-- 扫描controller的注解,别的不扫描 -->
    <context:component-scan base-package="com.jk.ssm.controller">
    </context:component-scan>

    <!-- 配置视图解析器 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- JSP文件所在的目录 -->
        <property name="prefix" value="/pages/" />
        <!-- 文件的后缀名 -->
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- 设置静态资源不过滤 -->
    <mvc:resources location="/css/" mapping="/css/**" />
    <mvc:resources location="/img/" mapping="/img/**" />
<!--    <mvc:resources location="/js/" mapping="/js/**" />-->
    <mvc:resources location="/plugins/" mapping="/plugins/**" />

    <!-- 开启对SpringMVC注解的支持 -->
    <mvc:annotation-driven />

    <!--
        支持AOP的注解支持,AOP底层使用代理技术
        JDK动态代理,要求必须有接口
        cglib代理,生成子类对象,proxy-target-class="true" 默认使用cglib的方式
    -->
    <aop:aspectj-autoproxy proxy-target-class="true"/>

2.2.3.编写Controller

ProductController

@Controller @RequestMapping("/product") public class ProductController {

    @Autowired
    private IProductService productService;

    @RequestMapping("/findAll.do") 
    public ModelAndView findAll() {
    	return null;
    }
}

2.3 Spring与Spring MVC整合

<!-- 配置加载类路径的配置文件 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:applicationContext.xml,classpath*:spring-security.xml</param-value>
  </context-param>

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

2.4 Spring与MyBatis整合

2.4.1.整合思路

把 mybatis 配置文件(mybatis.xml)中内容配置到 spring 配置文件中 。

2.4.2.Spring接管mybatis的Session工厂

db.properties

jdbc.driver=com.mysql.jdbc.Driver 
jdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=root
<context:property-placeholder location="classpath:db.properties"/>
    <!-- 配置连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}" />
        <property name="jdbcUrl" value="${jdbc.url}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <!-- 把交给IOC管理 SqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
    </bean>

2.4.3.自动扫描所有Mapper接口和文件

<!-- 扫描dao接口 -->

<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 
    <property name="basePackage" value="com.itheima.ssm.dao"/>
</bean>

2.4.4.配置Spring事务

<!-- 配置Spring的声明式事务管理 --> 
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>

2.5 测试运行

2.5.1.编写jsp页面

2.5.1.1 请求发起页面 index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>主页</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/product/findAll.do">查询产品信息</a>

</body> </html>
2.5.1.2 显示产品页面 product-list.jsp

60007118079

2.5.2.Controller

@Controller
@RequestMapping("/product")
public class ProductController {

    @Autowired
    private IProductService productService;

    /*
    查询全部产品
     */
    @RequestMapping("/findAll.do")
    public ModelAndView findAll() throws Exception {
        ModelAndView mv = new ModelAndView();
        List<Product> ps = productService.findAll();
        mv.addObject("productList",ps);
        mv.setViewName("product-list1");
        return mv;
    }

}

3.商品添加

3.1 商品添加页面 product-add.jsp

60007123691

页面详细代码请查看今天课程资料

3.2 Controller

@Controller
@RequestMapping("/product")
public class ProductController {

    @Autowired
    private IProductService productService;

    //产品添加
    @RequestMapping("/save.do")
    public String save(Product product) throws Exception {
        productService.save(product);
        return "redirect:findAll.do";
    }

    /*
    查询全部产品
     */
    @RequestMapping("/findAll.do")
    public ModelAndView findAll() throws Exception {
        ModelAndView mv = new ModelAndView();
        List<Product> ps = productService.findAll();
        mv.addObject("productList",ps);
        mv.setViewName("product-list1");
        return mv;
    }

}

3.3 Dao

public interface IProductDao {

	@Select("select * from product") 
    List<Product> findAll() throws Exception;

@Insert("insert into product(productNum,productName,cityName,departureTime,productPrice,productDesc,productStatus) values(#{productNum},#{productName},#{cityName},#{departureTime},#{productPrice},# {productDesc},#{productStatus})")
	void save(Product product);
}

SSM订单操作

1.表结构分析

1.1.订单表信息描述orders

序号 字段名称 字段类型 字段描述
1 id varchar2(32) 无意义、主键uuid
2 orderNum varchar2(50) 订单编号 不为空 唯一
3 orderTime timestamp 下单时间
4 peopleCount int 出行人数
5 orderDesc varchar2(500) 订单描述(其它信息)
6 payType int 支付方式(0 支付宝 1 微信 2其它)
7 orderStatus int 订单状态(0 未支付 1 已支付)
8 productId int 产品id 外键
9 memberid int 会员(联系人)id 外键

productId描述了订单与产品之间的关系。

memberid描述了订单与会员之间的关系。

创建表sql

CREATE TABLE orders(
id varchar2(32) default SYS_GUID() PRIMARY KEY, orderNum VARCHAR2(20) NOT NULL UNIQUE,
orderTime timestamp, peopleCount INT, orderDesc VARCHAR2(500), payType INT,
orderStatus INT, productId varchar2(32), memberId varchar2(32),
FOREIGN KEY (productId) REFERENCES product(id), FOREIGN KEY (memberId) REFERENCES member(id)
)
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)

values ('0E7231DC797C486290E8713CA3C6ECCC', '12345', to_timestamp('02-03-2018 12:00:00.000000',
'dd-mm-yyyy hh24:mi:ss.ff'), 2, '没什么', 0, 1, '676C5BD1D35E429A8C2E114939C5685A',

'E61D65F673D54F68B0861025C69773DB');
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)
values ('5DC6A48DD4E94592AE904930EA866AFA', '54321', to_timestamp('02-03-2018 12:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 2, '没什么', 0, 1, '676C5BD1D35E429A8C2E114939C5685A', 'E61D65F673D54F68B0861025C69773DB');
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)
values ('2FF351C4AC744E2092DCF08CFD314420', '67890', to_timestamp('02-03-2018 12:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 2, '没什么', 0, 1, '12B7ABF2A4C544568B0A7C69F36BF8B7', 'E61D65F673D54F68B0861025C69773DB');
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)
values ('A0657832D93E4B10AE88A2D4B70B1A28', '98765', to_timestamp('02-03-2018 12:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 2, '没什么', 0, 1, '12B7ABF2A4C544568B0A7C69F36BF8B7', 'E61D65F673D54F68B0861025C69773DB');
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)
values ('E4DD4C45EED84870ABA83574A801083E', '11111', to_timestamp('02-03-2018 12:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 2, '没什么', 0, 1, '12B7ABF2A4C544568B0A7C69F36BF8B7', 'E61D65F673D54F68B0861025C69773DB');
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)
values ('96CC8BD43C734CC2ACBFF09501B4DD5D', '22222', to_timestamp('02-03-2018 12:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 2, '没什么', 0, 1, '12B7ABF2A4C544568B0A7C69F36BF8B7', 'E61D65F673D54F68B0861025C69773DB');
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)
values ('55F9AF582D5A4DB28FB4EC3199385762', '33333', to_timestamp('02-03-2018 12:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 2, '没什么', 0, 1, '9F71F01CB448476DAFB309AA6DF9497F', 'E61D65F673D54F68B0861025C69773DB');
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)
values ('CA005CF1BE3C4EF68F88ABC7DF30E976', '44444', to_timestamp('02-03-2018 12:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 2, '没什么', 0, 1, '9F71F01CB448476DAFB309AA6DF9497F', 'E61D65F673D54F68B0861025C69773DB');
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)
values ('3081770BC3984EF092D9E99760FDABDE', '55555', to_timestamp('02-03-2018 12:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 2, '没什么', 0, 1, '9F71F01CB448476DAFB309AA6DF9497F', 'E61D65F673D54F68B0861025C69773DB');

实体类

/**
 * @outhor Mr.JK
 * @create 2020-05-01  16:12
 * 订单
 */
public class Orders {
    private Integer id;
    private String orderNum;
    private Date orderTime;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
    private String orderTimeStr;
    private int orderStatus;
    private String orderStatusStr;
    private int peopleCount;
    private Product product;
    private List<Traveller> travellers;
    private Member member;
    private Integer payType;
    private String payTypeStr;
    private String orderDesc;
}

1.2 会员表信息描述member

订单与会员之间是多对一关系,我们在订单表中创建一个外键来进行关联。

序号 字段名称 字段类型 字段描述
1 id varchar2(32) 无意义、主键uuid
2 name varchar2(20) 姓名
3 nickName varchar2(20) 昵称
4 phoneNum varchar2(20) 电话号码
5 email varchar2(50) 邮箱

创建表sql

CREATE TABLE member(
id varchar2(32) default SYS_GUID() PRIMARY KEY, NAME VARCHAR2(20),
nickname VARCHAR2(20), phoneNum VARCHAR2(20), email VARCHAR2(20)
)
insert into MEMBER (id, name, nickname, phonenum, email)
values ('E61D65F673D54F68B0861025C69773DB', '张三', '小三', '18888888888', 'zs@163.com');

实体类

public class Member {

	private String id; 
    private String name; 
    private String nickname; 
    private String phoneNum; 
    private String email; 
    //省略getter/setter
}

1.3.旅客表信息描述traveller

序号 字段名称 字段类型 字段描述
1 id varchar2(32) 无意义、主键uuid
2 name varchar2(20) 姓名
3 sex varchar2(20) 性别
4 phoneNum varchar2(20) 电话号码
5 credentialsType int 证件类型 0身份证 1护照 2军官证
6 credentialsNum varchar2(50) 证件号码
7 travellerType int 旅客类型(人群) 0 成人 1 儿童

创建表sql

CREATE TABLE traveller(
id varchar2(32) default SYS_GUID() PRIMARY KEY, NAME VARCHAR2(20),
sex VARCHAR2(20), phoneNum VARCHAR2(20), credentialsType INT,
credentialsNum VARCHAR2(50), travellerType INT
)
insert into TRAVELLER (id, name, sex, phonenum, credentialstype, credentialsnum, travellertype) values ('3FE27DF2A4E44A6DBC5D0FE4651D3D3E', '张龙', '男', '13333333333', 0, '123456789009876543', 0);
insert into TRAVELLER (id, name, sex, phonenum, credentialstype, credentialsnum, travellertype) values ('EE7A71FB6945483FBF91543DBE851960', '张小龙', '男', '15555555555', 0, '987654321123456789', 1);

实体类

/**
 * @outhor Mr.JK
 * @create 2020-05-01  16:23
 * 旅客
 */
public class Traveller {
    private Integer id;
    private String name;
    private String sex;
    private String phoneNum;
    private Integer credentialsType;
    private String credentialsTypeStr;
    private String credentialsNum;
    private Integer travellerType;
    private String travellerTypeStr;
}

旅客与订单之间是多对多关系,所以我们需要一张中间表(order_traveller)来描述

序号 字段名称 字段类型 字段描述
1 orderId varchar2(32) 订单id
2 travellerId varchar2(32) 旅客id

创建表sql

CREATE TABLE order_traveller( orderId varchar2(32), travellerId varchar2(32),
PRIMARY KEY (orderId,travellerId),
FOREIGN KEY (orderId) REFERENCES orders(id), FOREIGN KEY (travellerId) REFERENCES traveller(id)
)

insert into ORDER_TRAVELLER (orderid, travellerid)
values ('0E7231DC797C486290E8713CA3C6ECCC', '3FE27DF2A4E44A6DBC5D0FE4651D3D3E'); insert into ORDER_TRAVELLER (orderid, travellerid)
values ('2FF351C4AC744E2092DCF08CFD314420', '3FE27DF2A4E44A6DBC5D0FE4651D3D3E'); insert into ORDER_TRAVELLER (orderid, travellerid)
values ('3081770BC3984EF092D9E99760FDABDE', 'EE7A71FB6945483FBF91543DBE851960'); insert into ORDER_TRAVELLER (orderid, travellerid)
values ('55F9AF582D5A4DB28FB4EC3199385762', 'EE7A71FB6945483FBF91543DBE851960'); insert into ORDER_TRAVELLER (orderid, travellerid)
values ('5DC6A48DD4E94592AE904930EA866AFA', '3FE27DF2A4E44A6DBC5D0FE4651D3D3E'); insert into ORDER_TRAVELLER (orderid, travellerid)
values ('96CC8BD43C734CC2ACBFF09501B4DD5D', 'EE7A71FB6945483FBF91543DBE851960'); insert into ORDER_TRAVELLER (orderid, travellerid)
values ('A0657832D93E4B10AE88A2D4B70B1A28', '3FE27DF2A4E44A6DBC5D0FE4651D3D3E'); insert into ORDER_TRAVELLER (orderid, travellerid)
values ('CA005CF1BE3C4EF68F88ABC7DF30E976', 'EE7A71FB6945483FBF91543DBE851960'); insert into ORDER_TRAVELLER (orderid, travellerid)
values ('E4DD4C45EED84870ABA83574A801083E', 'EE7A71FB6945483FBF91543DBE851960');

2.订单查询

2.1 订单查询页面 order-list.jsp

60007173538

详细代码请查看今天课程资料

2.2 Controller

@Controller
@RequestMapping("/orders")
public class OrdersController {

    @Autowired
    private IOrdersService ordersService;


    @RequestMapping("/findAll.do")
    public ModelAndView findAll(@RequestParam(name="page",required = true,defaultValue = "1") Integer page,@RequestParam(name = "size",required = true,defaultValue = "4") Integer size) throws Exception {
        ModelAndView mv = new ModelAndView();
        List<Orders> ordersList = ordersService.findAll(page, size);
        //PageInfo就是一个分页Bean
        PageInfo pageInfo = new PageInfo(ordersList);
        mv.addObject("pageInfo",pageInfo);
        mv.setViewName("orders-page-list");
        return mv;
    }

2.3 Dao

IOrdersDao

/**
 * @outhor Mr.JK
 * @create 2020-05-01  16:33
 */

public interface IOrdersDao {


    @Select("select * from orders")
    @Results({
            @Result(id = true,property = "id",column = "id"),
            @Result(property = "orderNum",column = "orderNum"),
            @Result(property = "orderTime",column = "orderTime"),
            @Result(property = "orderStatus",column = "orderStatus"),
            @Result(property = "peopleCount",column = "peopleCount"),
            @Result(property = "payType",column = "payType"),
            @Result(property = "payTypeStr",column = "payTypeStr"),
            @Result(property = "orderDesc",column = "orderDesc"),
            @Result(property = "product",column = "productId",javaType = Product.class,
                    one = @One(select = "com.jk.ssm.dao.IProductDao.findById"))
    })
    public List<Orders> findAll() throws Exception;

}

IProductDao的findById

@Select("select * from product where id=#{id}") 
Product findById(String id) throws Exception;

3.订单分页查询

3.1 PageHelper介绍

PageHelper是国内非常优秀的一款开源的mybatis分页插件,它支持基本主流与常用的数据库,例如mysql、oracle、mariaDB、DB2、SQLite、Hsqldb等。

本项目在 github 的项目地址:https://github.com/pagehelper/Mybatis-PageHelper本项目在 gitosc 的项目地址:http://git.oschina.net/free/Mybatis_PageHelper

3.2 PageHelper使用

3.2.1.集成

引入分页插件有下面2种方式,推荐使用 Maven 方式。

3.2.1.1. 引入 Jar 包

你可以从下面的地址中下载最新版本的 jar 包

https://oss.sonatype.org/content/repositories/releases/com/github/pagehelper/pagehelper/

http://repo1.maven.org/maven2/com/github/pagehelper/pagehelper/

由于使用了sql 解析工具,你还需要下载 jsqlparser.jar:

http://repo1.maven.org/maven2/com/github/jsqlparser/jsqlparser/0.9.5/

3.2.1.2. 使用 Maven

在 pom.xml 中添加如下依赖:

<dependency> 
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId> <version>最新版本</version>
</dependency>

3.2.2.配置

特别注意,新版拦截器是 com.github.pagehelper.PageInterceptor 。 com.github.pagehelper.PageHelper 现在是一个特殊的 dialect 实现类,是分页插件的默认实现类,提供了和以前相同的用法。

3.2.2.1. 在 MyBatis 配置 xml 中配置拦截器插件
<!--
plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下:
	properties?, settings?, 
	typeAliases?, typeHandlers?,
	objectFactory?,objectWrapperFactory?,
	plugins?,
	environments?, databaseIdProvider?, mappers?
-->
<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
		<plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->

        <property name="param1" value="value1"/>
    </plugin>
</plugins>
3.2.2.2. 在 Spring 配置文件中配置拦截器插件

使用 spring 的属性配置方式,可以使用 plugins 属性像下面这样配置:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- 注意其他配置 -->
    <property name="plugins"> 
        <array>
            <bean class="com.github.pagehelper.PageInterceptor">
                <property name="properties">
                <!--使用下面的方式配置参数,一行配置一个 -->

                    <value>
                    	params=value1
                    </value> 
                </property>
            </bean> 
        </array>
    </property> 
</bean>

3.2.3 分页插件参数介绍

  1. helperDialect :分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。 你可以配置

helperDialect 属性来指定分页插件使用哪种方言。配置时,可以使用下面的缩写值:

oracle , mysql , mariadb , sqlite , hsqldb , postgresql , db2 , sqlserver , informix , h2 sqlserver201

2 , derby

特别注意:使用 SqlServer2012 数据库时,需要手动指定为 sqlserver2012 ,否则会使用 SqlServer2005 的方式进行分页。

你也可以实现 AbstractHelperDialect ,然后配置该属性为实现类的全限定名称即可使用自定义的实现方

法。

  1. offsetAsPageNum :默认值为 false ,该参数对使用 RowBounds 作为分页参数时有效。 当该参数设置为

true 时,会将 RowBounds 中的 offset 参数当成 pageNum使用,可以用页码和页面大小两个参数进行分

页。

  1. rowBoundsWithCount :默认值为 false ,该参数对使用 RowBounds 作为分页参数时有效。 当该参数设置

为 true 时,使用 RowBounds 分页会进行 count 查询。

  1. pageSizeZero :默认值为 false ,当该参数设置为 true 时,如果 pageSize=0 或者 RowBounds.limit =

0 就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是 Page 类型)。

  1. reasonable :分页合理化参数,默认值为 false 。当该参数设置为 true时, pageNum<=0 时会查询第一

页, pageNum>pages (超过总数时),会查询最后一页。默认 false 时,直接根据参数进行查询。

  1. params :为了支持 startPage(Object params) 方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值, 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable ,不配置映射的用默认值, 默认值为

pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero。

  1. supportMethodsArguments :支持通过 Mapper 接口参数来传递分页参数,默认值 false ,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。 使用方法可以参考测试代码中的 com.github.pagehelper.test.basic 包下的 ArgumentsMapTest 和

ArgumentsObjTest 。

  1. autoRuntimeDialect :默认值为 false 。设置为 true 时,允许在运行时根据多数据源自动识别对应方言

的分页 (不支持自动选择 sqlserver2012 ,只能使用 sqlserver ),用法和注意事项参考下面的场景五。

  1. closeConn :默认值为 true 。当使用运行时动态数据源或没有设置 helperDialect 属性自动获取数据库类

型时,会自动获取一个数据库连接, 通过该属性来设置是否关闭获取的这个连接,默认 true 关闭,设置为

false 后,不会关闭获取的连接,这个参数的设置要根据自己选择的数据源来决定。

3.2.4.基本使用

PageHelper的基本使用有6种,大家可以查看文档,最常用的有两种

3.2.4.1. RowBounds方式的调用(了解)
List<Country> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(1, 10));

使用这种调用方式时,你可以使用RowBounds参数进行分页,这种方式侵入性最小,我们可以看到,通过RowBounds方式调用只是使用了这个参数,并没有增加其他任何内容。

分页插件检测到使用了RowBounds参数时,就会对该查询进行物理分页。

关于这种方式的调用,有两个特殊的参数是针对 RowBounds的,你可以参看上面的分页插件参数介绍注:不只有命名空间方式可以用RowBounds,使用接口的时候也可以增加RowBounds参数,例如:

//这种情况下也会进行物理分页查询

List<Country> selectAll(RowBounds rowBounds);

注意: 由于默认情况下的 RowBounds 无法获取查询总数,分页插件提供了一个继承自 RowBounds 的

PageRowBounds ,这个对象中增加了 total属性,执行分页查询后,可以从该属性得到查询总数。

3.2.4.2. PageHelper.startPage静态方法调用(重点)

这种方式是我们要掌握的 在你需要进行分页的 MyBatis 查询方法前调用PageHelper.startPage 静态方法即可,紧跟在这个方法后的第一个MyBatis 查询方法会被进行分页。

//获取第1页,10条内容,默认查询总数count

PageHelper.startPage(1, 10); //紧跟着的第一个select方法会被分页
List<Country> list = countryMapper.selectIf(1);

3.3 订单分页查询

3.3.1 Service

@Override
public List<Orders> findAllByPage(int page, int pageSize) throws Exception {
	PageHelper.startPage(page, pageSize); 
    return ordersDao.findAllByPage();
}

3.3.2 Controller

@RequestMapping("/findAll.do")
public ModelAndView findAll(@RequestParam(name = "page", required = true, defaultValue = "1") Integer page, @RequestParam(name = "pageSize", required = true, defaultValue = "10") Integer pageSize) throws Exception {
    List<Orders> ordersList = ordersService.findAllByPage(page, pageSize); 
    PageInfo pageInfo = new PageInfo(ordersList);
    ModelAndView mv = new ModelAndView(); 
    mv.setViewName("order-list"); 
    mv.addObject("pageInfo", pageInfo); 
    return mv;
}

3.3.3 订单分页查询页面Order-list.jsp

60007268690

详细代码请查看今天课程资料

4.订单详情

在order-list.jsp页面上对”详情”添加链接

<button type="button" class="btn bg-olive btn-xs" onclick="location.href='${pageContext.request.contextPath}/orders/findById.do?id=${orders.id}'">详情</button>

4.1 订单详情 order-show.jsp

60007273993

详细代码请查看今天课程资料

4.2 Controller

@RequestMapping("/findById.do")
public ModelAndView findById(String id) throws Exception { 
    Orders orders = ordersService.findById(id);
    ModelAndView mv = new ModelAndView(); 
    mv.setViewName("order-show");
	mv.addObject("orders", orders); 
    return mv;
}

4.3 Dao

IOrdersDao的findById方法

//多表操作
    @Select("select * from orders where id = #{orderId}")
    @Results({
            @Result(id = true,property = "id",column = "id"),
            @Result(property = "orderNum",column = "orderNum"),
            @Result(property = "orderTime",column = "orderTime"),
            @Result(property = "orderStatus",column = "orderStatus"),
            @Result(property = "peopleCount",column = "peopleCount"),
            @Result(property = "payType",column = "payType"),
            @Result(property = "payTypeStr",column = "payTypeStr"),
            @Result(property = "orderDesc",column = "orderDesc"),
            @Result(property = "product",column = "productId",javaType = Product.class,
                    one = @One(select = "com.jk.ssm.dao.IProductDao.findById")),
            @Result(property = "member",column = "memberId",javaType = Member.class,
                    one = @One(select = "com.jk.ssm.dao.IMemberDao.findById")),
            @Result(property = "travellers",column = "id",javaType = java.util.List.class,
                    many = @Many(select = "com.jk.ssm.dao.ITravellerDao.findByOrdersId"))
    })
    Orders findById(String ordersId) throws Exception;

IMemberDao的findById方法

public interface IMemberDao {

    @Select("select * from member where id=#{id}")
    public Member findById(String id) throws Exception;

}

ITravellerDao.findByOrdersId方法

@Select("select * from traveller where id in (select travellerId from order_traveller where orderId=#{ordersId})")
public List<Traveller> findByOrdersId(String ordersId) throws Exception;

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

权限管理、旅游系统后篇 Previous
SpringSecurity源码分析 Next