javaweb-青橙项目-1-76

javaweb-青橙项目-1-76

1.项目预计

序列1-地址:https://github.com/Jonekaka/javaweb-qingcheng-1-76/tree/master/qingchengcode/qingchengcode

1.1小项目特点

对于一些小项目ssm就够了,但是对于高并发的大项目
需要更多新技术的融合与赋能

1.2大项目特点

技术新,技术范围广-技术
分布式、集群、高并发、负载均衡、高可用-设备压力分担
海量数据-数据
业务复杂-业务
系统安全-安全
将多个小设备虚拟为一个超算

1.3 主要电商模式

B2B ( Business to Business)是指进行电子商务交易的供需双方都是商家(或企
业、公司),她(他)们使用了互联网的技术或各种商务网络平台,完成商务交易的
过程。电子商务是现代 B2B marketing的一种具体主要的表现形式。
案例:阿里巴巴、慧聪网

C2C即 Customer(Consumer) to Customer(Consumer),意思就是消费者个
人间的电子商务行为。比如一个消费者有一台电脑,通过网络进行交易,把它出售给
另外一个消费者,此种交易类型就称为C2C电子商务。
案例:淘宝、易趣、瓜子二手车

B2C是Business-to-Customer的缩写,而其中文简称为“商对客”。“商对客”是电子商
务的一种模式,也就是通常说的直接面向消费者销售产品和服务商业零售模式。这种
形式的电子商务一般以网络零售业为主,主要借助于互联网开展在线销售活动。B2C
即企业通过互联网为消费者提供一个新型的购物环境——网上商店,消费者通过网络
在网上购物、网上支付等消费行为。
注:本项目采用B2C模式

案例:唯品会、乐蜂网B2B2C是一种电子商务类型的网络购物商业模式,B是BUSINESS的简称,C是
CUSTOMER的简称,第一个B指的是商品或服务的供应商,第二个B指的是从事电子
商务的企业,C则是表示消费者。
案例:京东商城、天猫商城

C2B(Consumer to Business,即消费者到企业),是互联网经济时代新的商业模
式。这一模式改变了原有生产者(企业和机构)和消费者的关系,是一种消费者贡献
价值(Create Value), 企业和机构消费价值(Consume Value)。
C2B模式和我们熟知的供需模式(DSM, Demand SupplyModel)恰恰相反,真正的
C2B 应该先有消费者需求产生而后有企业生产,即先有消费者提出需求,后有生产
企业按需求组织生产。通常情况为消费者根据自身需求定制产品和价格,或主动参与
产品设计、生产和定价,产品、价格等彰显消费者的个性化需求,生产企业进行定制
化生产。
案例:海尔商城、 尚品宅配

O2O即Online To Offline(在线离线/线上到线下),是指将线下的商务机会与互联
网结合,让互联网成为线下交易的平台,这个概念最早来源于美国。O2O的概念非
常广泛,既可涉及到线上,又可涉及到线下,可以通称为O2O。主流商业管理课程均
对O2O这种新型的商业模式有所介绍及关注。
案例:美团、饿了吗

F2C指的是Factory to customer,即从厂商到消费者的电子商务模式。

2. 青橙-需求分析与系统设计

2.1 需求分析

《青橙》是一个全品类B2C电商平台(单品类就是只卖一类,比如衣服,化妆品),包含网站前台和管理后台两大部分。网站前台
包含主站频道(首页、搜索、购物车及支付)、用户中心、秒杀、优惠券等频道。管理
后台包含商品、订单、库存、用户、运营、统计、财务、设置等功能
后台
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

前台
在这里插入图片描述
在这里插入图片描述
等等,商品详情页,登录页,评论页

2.2 系统设计

2.2.1 数据库分库设计

(1)商品库 qingcheng_goods
(2)订单库 qingcheng_order
(3)基础设置库 qingcheng_config
(4)运营库 qingcheng_business
(5)用户库 qingcheng_user
(6)系统库qingcheng_system
(7)支付库 qingcheng_pay
(8)短信库 qingcheng_sms
2.2.2 技术选型
主框架技术:SSM(通用mapper,比mybatis使用更加简单)+Dubbo(分布式框架)
前端技术: 网站后台 Vue.js+ElementUI(ui库) 网站前台采用Vue.js 和模板技术 thymeleaf
消息中间件技术: RabbitMQ
搜索中间件技术: elasticsearch
缓存中间件技术: redis
报表插件: echars
安全框架:SpringSecurity
单点登录中间件 :CAS

2.2.3 系统架构图

在这里插入图片描述

3. 通用mapper

3.1 通用mapper简介

对mybatis进行了进一步封装,解决mybatis存在的问题
通用 Mapper 是一个可以实现任意 MyBatis 通用方法的框架,项目提供了常规的增
删改查操作以及Example相关的单表操作。为什么要用通用mapper?我们这里列举一下
原生Mybatis的痛点:
1、mapper.xml文件里有大量的sql,当数据库表字段变动,配置文件就要修改
2、需要自己实现sql分页,select * from table where . . . limit 1,3
自己手写分页,除了传参page、pageSize,还需要返回条目总数count。
3、数据库可移植性差:如果项目更换数据库,比如oracle–>mysql,mapper.xml中的
sql要重新写,因为Oracle的PLSQL 和mysql 支持的函数是不同的。
4、生成的代码量过大。
5、批量操作,批量插入,批量更新,需要自写。
而这些,通过通用mapper就可以很轻松的解决了。

3.2 通用mapper快速入门

在线官方文档:https://gitee.com/free/Mapper/wikis/Home

3.2.1 通用mapper与Spring集成

官方的文档中介绍了通用mapper的三种使用方式 ,纯java使用方式、与Spring集成方
式、与SpringBoot集成方式。这里给大家介绍的是与Spring集成方式。

如果对语句抽象化,自动生成,自然能够避免表不同,数据库语法不同而带来的修改问题
同时也可以实现扩展功能,比如自动分页
也可以批量完成
实现数据库接口crud调用mapper提供的功能接口即可

(1)引入依赖
正常情况下,Spring 和 MyBatis 的集成环境中,应该已经存在下面的依赖:

<dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>版本号</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis‐spring</artifactId>
        <version>版本号</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring‐context</artifactId>
        <version>版本号</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring‐tx</artifactId>
        <version>版本号</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring‐jdbc</artifactId>
        <version>版本号</version>
    </dependency>

集成通用 Mapper 在上面的基础上添加下面的依赖:

  <dependency>
        <groupId>tk.mybatis</groupId>
        <artifactId>mapper</artifactId>
        <version>最新版本</version>
    </dependency>

(2)与spring集成
和通用 Mapper 以前版本一样,可以直接使用 tk.mybatis 提供
的 tk.mybatis.spring.mapper.MapperScannerConfigurer 进行配置,这个配置和
MyBatis 官方提供的 org.mybatis.spring.mapper.MapperScannerConfigurer 区别只是
第一层的包名, tk 和 org 。所以使用这种方式时,如果你项目已经使用 org. 进行了
配置,只需要改成 tk. 即可。

<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="扫描包名"/>
    </bean>

项目中采用的是这种xml的配置方式,通用mapper还提供了注解方式的配置,

3.2.2 实体类映射

实体类映射类似下列形式

@Table(name="tb_brand")
    public class Brand implements Serializable{
   
    @Id
    private Integer id;
    private String name;
    //getter and setter ....
    }

@Table是指定实体类对应的数据库表 @Id指的是主键映射。经过上面简单的配置后,相
当于就有了 MyBatis 中的关系映射了

3.2.3 创建Mapper接口

 public interface BrandMapper extends Mapper<Brand> {
   
    }

这里继承了 tk.mybatis.mapper.common.Mapper 接口,在接口上指定了泛型类
型 Brand 。当你继承了 Mapper 接口后,此时就已经有了针对 Brand 的大量方法,方
法如下:
在这里插入图片描述
等等》》》
这些方法中和 MBG 生成的大部分方法都一致,还有一部分 MBG 之外的常用方法。

基础接口select
List select(T record)
根据T对象中的属性名称查询,类似于select * from table where t.name=#{name} and
t.password = #{password}

T selectOne(T record)
根据实体中的属性进行查询,只能有一个返回值,有多个结果是抛出异常,查询条件使用等号
T selectByPrimaryKey(Object key)
根据主键查询 说明:根据主键字段进行查询,方法参数必须包含完整的主键属性,查询条
件使用等号
int selectCount(T record);
说明:根据实体中的属性查询总数,查询条件使用等号基础接口insert
int insert(T record);
说明:保存一个实体,null的属性也会保存,不会使用数据库默认值
int insertSelective(T record);
说明:保存一个实体,null的属性不会保存,会使用数据库默认值

基础接口Update
int updateByPrimaryKey(T record);
说明:根据主键更新实体全部字段,null值会被更新
int updateByPrimaryKeySelective(T record);
说明:根据主键更新属性不为null的值

基础接口delete
int delete(T record);
说明:根据实体属性作为条件进行删除,查询条件使用等号
int deleteByPrimaryKey(Object key);
说明:根据主键字段进行删除,方法参数必须包含完整的主键属性

4. 青橙-工程搭建

4.1 准备工作

先进行环境准备
(1)配置maven本地仓库
(2)创建数据库表
(3)注册中心zookeeper
4.2 模块依赖关系图
我们的工程有三种模块:(1)公共模块(解决模块的重复问题,这里主要是服务层与web层的重复问题,以及模块重复带来的复杂性-面向对象的思想) (2)服务层模块 (3)web层模块。
公共模块主要由公共配置和公共类构成。模块依赖关系入下图:
在这里插入图片描述

4.3 工程搭建

4.3.1 父工程与公共模块

(1)创建父工程qingcheng_parent pom.xml
父工程没有代码,删掉src文件夹

<?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.qingcheng</groupId>
<artifactId>qingcheng_parent</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>qingcheng_common</module>
<module>qingcheng_common_service</module>
<module>qingcheng_common_web</module>
<module>qingcheng_pojo</module>
<module>qingcheng_interface</module>
<module>qingcheng_service_goods</module>
<module>qingcheng_web_manager</module>
</modules>
<packaging>pom</packaging>
<!-- 集中定义依赖版本号 -->
<properties>
<junit.version>4.12</junit.version>
<spring.version>5.0.5.RELEASE</spring.version>
<pagehelper.version>4.1.4</pagehelper.version>
<servlet-api.version>2.5</servlet-api.version>
<dubbo.version>2.6.0</dubbo.version>
<zookeeper.version>3.4.7</zookeeper.version>
<zkclient.version>0.1</zkclient.version>
<mybatis.version>3.4.5</mybatis.version>
<mybatis.spring.version>1.3.1</mybatis.spring.version>
<mybatis.paginator.version>1.2.15</mybatis.paginator.version>
<mysql.version>5.1.32</mysql.version>
<druid.version>1.0.9</druid.version>
<commons-fileupload.version>1.3.1</commons-fileupload.version>
<spring.security.version>5.0.5.RELEASE</spring.security.version>
<jackson.version>2.9.4</jackson.version>
</properties>
<!-- 依赖管理标签  必须加 -->
<dependencyManagement>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</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-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-jdbc</artifactId>
<version>${
spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${
spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</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-test</artifactId>
<version>${
spring.version}</version>
</dependency>
<!-- dubbo相关 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>${
dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${
zookeeper.version}</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>${
zkclient.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>${
pagehelper.version}</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${
mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${
mybatis.spring.version}</version>
</dependency>
<dependency>
<groupId>com.github.miemiedev</groupId>
<artifactId>mybatis-paginator</artifactId>
<version>${
mybatis.paginator.version}</version>
</dependency>
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${
mysql.version}</version>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${
druid.version}</version>
</dependency>
<!-- 文件上传组件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${
commons-fileupload.version}</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-taglibs</artifactId>
<version>${
spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas</artifactId>
<version>${
spring.version}</version>
</dependency>
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.4.01</version>
</dependency>
<!-- 缓存 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.0.5.RELEASE</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-databind</artifactId>
<version>${
jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${
jackson.version}</version>
</dependency>
<!--通用Mapper-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>4.1.4</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.7</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${
servlet-api.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<!--为了使用jdk1.8新特性,引入。-->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

上面为父
(2)创建公共模块qingcheng_common,pom.xm
搭建公共模块,从最顶层开始搭建
提供基础参数

resources下创建applicationContext-common.xml

<!--用来加载所有文件名末尾属性为properties的文件-->
<context:property-placeholder location="classpath*:*.properties" />

resources下创建zk.properties
zk.properties

#配置zk连接地址地址
zk.address=127.0.0.1:2181

resources下创建log4j.properties
配置日志参数

(3)创建qingcheng_common_service ,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>qingcheng_parent</artifactId>
<groupId>com.qingcheng</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>qingcheng_common_service</artifactId>
<!--引入common依赖,传递依赖,-->
<dependencies>
<dependency>
<groupId>com.qingcheng</groupId>
<artifactId>qingcheng_common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</dependency>
<dependency>
<groupId>com.github.miemiedev</groupId>
<artifactId>mybatis-paginator</artifactId>
</dependency>
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
<!--通用Mapper-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
</dependency>
<!-- 缓存 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.6</version>
</dependency>
</dependencies>
</project>

resources下创建applicationContext-dao.xml,mybatis的

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
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-4.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--数据源的一些配置-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="driverClassName" value="${jdbc.driver}" />
<property name="maxActive" value="10" />
<property name="minIdle" value="5" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="plugins">
<!--mybatis的插件,分页-->
<array>
<bean class="com.github.pagehelper.PageHelper">
<property name="properties">
<value>
dialect=mysql
</value>
</property>
</bean>
</array>
</property>
</bean>
<!--包扫描-->
<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.qingcheng.dao" />
</bean>
<!-- 事务管理器  -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!--
开启事务控制的注解支持
注意:此处必须加入proxy-target-class="true",
需要进行事务控制,会由Spring框架产生代理对象,Dubbo需要将Service发布为服务,要求必须使用cglib创建代理对象。
-->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
</beans>

resources下创建applicationContext-dubbo.xml,dubbo的

<?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:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--指定暴露服务的端口,如果不指定默认为20880-->
<dubbo:protocol name="dubbo" port="${dubbo.port}"/>
<dubbo:application name="${dubbo.application}" />
<!--zk地址为common而来-->
<dubbo:registry protocol="zookeeper" address="${zk.address}" />
<dubbo:annotation package="com.qingcheng.service" />
<!--<context:annotation-config/>-->
<dubbo:provider timeout="10000" threadpool="fixed" threads="100" accepts="1000"/>
</beans>

redis的

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/beans/spring-cache.xsd">
<!-- redis 相关配置 --> 
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">  
<property name="maxIdle" value="${redis.maxIdle}" />   
<property name="maxWaitMillis" value="${redis.maxWait}" />  
<property name="testOnBorrow" value="${redis.testOnBorrow}" />  
</bean>  
<!--spring data redis的配置,使用中会用到配置文件,已经添加-->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:pool-config-ref="poolConfig"/>  
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">  
<property name="connectionFactory" ref="jedisConnectionFactory" />
</bean>
</beans>  

(4)创建qingcheng_common_web模块,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>qingcheng_parent</artifactId>
<groupId>com.qingcheng</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<!--传递依赖-->
<artifactId>qingcheng_common_web</artifactId>
<dependencies>
<dependency>
<groupId>com.qingcheng</groupId>
<artifactId>qingcheng_common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.qingcheng</groupId>
<artifactId>qingcheng_pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--文件上传相关依赖-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
<!--spring安全依赖-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<!--阿里提供的存储对象依赖-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
</dependency>
</dependencies>
</project>

resources下创建applicationContext-json.xml

<mvc:annotation‐driven>
<mvc:message‐converters register‐defaults="true">
<bean
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json"/>
<property name="features">
<list>
<value>WriteMapNullValue</value>
<value>WriteDateUseDateFormat</value>
</list>
</property>
</bean>
</mvc:message‐converters>
</mvc:annotation‐driven>

resources下创建applicationContext-dubbo.xml

<!-- 引用dubbo 服务,为工程起名字 -->
<dubbo:application name="${dubbo.application}" />
<!--对zk地址配置-->
<dubbo:registry protocol="zookeeper" address="${zk.address}"/>
<!--扫描所有控制器的类-->
<dubbo:annotation package="com.qingcheng.controller" />

下面两个模块也会被其他模块所引用,也可以归类为公共模块
(5)创建实体层模块qingcheng_pojo,pom.xml

<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence‐api</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>

(6)创建服务接口层模块 qingcheng_interface ,pom.xml

<!--jpa注解-->
<dependency>
<groupId>com.qingcheng</groupId>
<artifactId>qingcheng_pojo</artifactId>
<version>1.0‐SNAPSHOT</version>
</dependency>

4.3.2 服务层模块(商品)

在这里插入图片描述
其中一个为例子,其他一样
商品服务
(1)创建qingcheng_service_goods模块,pom.xml

<dependencies>
<dependency>
<groupId>com.qingcheng</groupId>
<artifactId>qingcheng_interface</artifactId>
<version>1.0‐SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.qingcheng</groupId>
<artifactId>qingcheng_common_service</artifactId>
<version>1.0‐SNAPSHOT</version>
</dependency>
</dependencies>
<!--指定各个服务的端口,创建各自的服务器。从9001开始-->
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7‐maven‐plugin</artifactId>
<configuration>
<!‐‐ 指定端口 ‐‐>
<port>9001</port>
<!‐‐ 请求路径 ‐‐>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>

(2)创建webapp/WEB-INF/web.xml

<!DOCTYPE web‐app PUBLIC
"‐//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web‐app_2_3.dtd" >
<web‐app>
<display‐name>Archetype Created Web Application</display‐name>
<!‐‐ 加载spring容器 ‐‐>
<context‐param>
<param‐name>contextConfigLocation</param‐name>
<param‐value>classpath*:applicationContext*.xml</param‐value>
</context‐param>
<listener>
<listener‐
class>org.springframework.web.context.ContextLoaderListener</listener‐
class>
</listener>
</web‐app>

(3)resources下创建dubbo.properties
配置功能区的端口与名字

dubbo.port=20881
dubbo.application=goods

(4)resources下创建db.properties
配置数据库连接信息

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/qingcheng_goods?
characterEncoding=utf‐8
jdbc.username=root
jdbc.password=123456

4.3.3 web层(管理后台)

(1)创建qingcheng_web_manager模块,pom.xml

<dependencies>
<dependency>
<groupId>com.qingcheng</groupId>
<artifactId>qingcheng_interface</artifactId>
<version>1.0‐SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.qingcheng</groupId>
<artifactId>qingcheng_common_web</artifactId>
<version>1.0‐SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7‐maven‐plugin</artifactId>
<configuration>
<!‐‐ 指定端口 ‐‐>
<port>9101</port>
<!‐‐ 请求路径 ‐‐>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>

(2)创建webapp/WEB-INF/web.xml

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 解决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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--安全框架的过滤器,暂时不用-->
<!--
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载,除了本身的,它所依赖的也能找到 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>

(3)resources下创建dubbo.properties

dubbo.application=manager

5. 青橙管理后台-品牌管理后端

5.1 需求分析

实现对品牌的基本操作(增删改查),只完成后端代码部分,并通过浏览器等工具完成
测试。

5.2 表结构分析

tb_brand 品牌表
就是品牌类别,图片地址时品牌的logo
在这里插入图片描述

5.3 代码实现

5.3.1 品牌列表

url
/brand/findAll.do
http请求方式
GET
返回格式

[{

"id": 品牌id,
"name": 品牌名称,
"image": 品牌图片地址,
"letter": 品牌的首字母,
"seq": 排序,
},
.......
]

代码实现:
(1)在qingcheng_pojo工程创建com.qingcheng.pojo包,包下创建实体类

@Table(name="tb_brand")
public class Brand implements Serializable{

@Id
private Integer id;//品牌id
private String name;//品牌名称
private String image;//品牌图片地址
private String letter;//品牌的首字母
private Integer seq;//排序
// getter and setter ......
}

(2)qingcheng_service_goods工程创建com.qingcheng.dao,包下创建数据访问层接

/*数据访问层,dao*/
public interface BrandMapper extends Mapper<Brand> {

}

(3)qingcheng_interface工程创建com.qingcheng.service.goods包,包下创建业务接

/**
* 品牌业务逻辑层
*/
public interface BrandService {

public List<Brand> findAll();
}

(4)qingcheng_service_goods工程创建com.qingcheng.service.impl包,包下创建类

@Service
public class BrandServiceImpl implements BrandService {

@Autowired
private BrandMapper brandMapper;
public List<Brand> findAll() {

return brandMapper.selectAll();
}
}

(5)qingcheng_web_manager工程创建com.qingcheng.controller.goods 包,包下创
建类

@RestController
@RequestMapping("/brand")
public class BrandController {

@Reference
/*注入远程的业务接口*/
private BrandService brandService;
@GetMapping("/findAll")
public List<Brand> findAll(){

return brandService.findAll();
}
}

测试

开启,可以在虚拟机中,也可以本机,zk
在这里插入图片描述
安装inferface,pojo
如果变化也要重新安装

开启service的tomcat7 run,开启,开启manager的tomcat7
在这里插入图片描述

浏览器输入:http://localhost:9101/brand/findAll.do
数据库返回数据,调用成功
在这里插入图片描述

5.3.2 品牌分页列表

接口定义:
url
/brand/findPage.do
http请求方式
GET
请求参数
在这里插入图片描述
例子:
GET /brand/findPage.do?page=1&size=10
返回格式

{
rows:[{

"id": 品牌id,
"name": 品牌名称,
"image": 品牌图片地址,
"letter": 品牌的首字母,
"seq": 排序,
},
.......
],
total:100}

pojo是和数据库对应的类,entity是自己封装的类,实现自定义数据模块
创建类pojo,创建功能接口interface,创建实现manager,分步实现
代码实现:
(1)qingcheng_pojo创建com.qingcheng.entity包,包下创建类
用来承载分页查询的对象

/**
* 分页结果
* @param <T>
*/
public class PageResult<T> implements Serializable {

private Long total;//记录数
private List<T> rows;//结果集
public PageResult(Long total, List<T> rows) {

this.total = total;
this.rows = rows;
}
public PageResult() {

}
public Long getTotal() {

return total;
}
public List<T> getRows() {

return rows;
}
public void setRows(List<T> rows) {

this.rows = rows;
}
public void setTotal(Long total) {

this.total = total;
}
}

(2)qingcheng_interface工程BrandService接口新增方法

public PageResult<Brand> findPage(int page, int size);

(3)qingcheng_service_goods工程BrandServiceImpl新增方法

/**
* 分页查询
* @param page 页码
* @param size 每页记录数
* @return 分页结果
*/
public PageResult<Brand> findPage(int page, int size) {

PageHelper.startPage(page,size);
Page<Brand> brands = (Page<Brand>) brandMapper.selectAll();
return new PageResult<Brand>
(brands.getTotal(),brands.getResult());
}

(4)qingcheng_web_manager工程BrandController新增方法

@GetMapping("/findPage")
public PageResult<Brand> findPage(int page, int size){

return brandService.findPage(page, size);
}

因为更新了interface与pojo,所以需要重新安装
启动工程,浏览器测试:http://localhost:9101/brand/findPage.do?page=1&size=10
在这里插入图片描述

5.3.3 品牌条件查询

url
/brand/findList.do
http请求方式
POST
请求参数
在这里插入图片描述
例子:

POST /brand/findList.do
{

"name": 品牌名称,
"letter": 品牌的首字母
}

返回格式

[{

"id": 品牌id,
"name": 品牌名称,
"image": 品牌图片地址,
"letter": 品牌的首字母,
"seq": 排序,
},
.......
]

代码实现:
(1)qingcheng_interface工程BrandService接口新增方法

public List<Brand> findList(Map<String, Object> searchMap);

(2)qingcheng_service_goods工程BrandServiceImpl新增方法

/**
* 条件查询
* @param searchMap 查询条件
* @return
*/
public List<Brand> findList(Map<String, Object> searchMap) {

Example example = createExample(searchMap);
return brandMapper.selectByExample(example);
}
/**
* 构建查询条件
* @param searchMap
* @return
*/
private Example createExample(Map<String, Object> searchMap){

Example example=new Example(Brand.class);
Example.Criteria criteria = example.createCriteria();
if(searchMap!=null){

//名称条件
if(searchMap.get("name")!=null &&
!"".equals(searchMap.get("name"))){

criteria.andLike("name","%"+
(String)searchMap.get("name")+"%");
}
//首字母
if(searchMap.get("letter")!=null &&
!"".equals(searchMap.get("letter"))){

criteria.andEqualTo("letter",
(String)searchMap.get("letter"));
}
}
return example;
}

(3)qingcheng_web_manager工程BrandController新增方法

 @PostMapping("/findList")
/*加入注解,分解请求得到的json数据*/
/*之前都是get请求的,输入条件参数,现在post请求*/
public List<Brand> findList( @RequestBody Map searchMap){

return brandService.findList(searchMap);
}

/之前都是get请求的,输入条件参数,现在post请求/
使用postman
在这里插入图片描述
以json方式请求,
在这里插入图片描述
多个条件加逗号即可

5.3.4 品牌条件+分页查询

写一个功能函数囊括以上两个功能即可
url
/brand/findPage.do
http请求方式
POST
请求参数

在这里插入图片描述
例子:

POST /brand/findPage.do?page=1&size=10
{

"name": 品牌名称,
"letter": 品牌的首字母
}

返回格式:

{
rows:[{

"id": 品牌id,
"name": 品牌名称,
"image": 品牌图片地址,
"letter": 品牌的首字母,
"seq": 排序
},
.......
],
total:100}

代码实现:
(1)qingcheng_interface工程BrandService接口新增方法

public PageResult<Brand> findPage(Map<String,Object> searchMap,int page,
int size);

(2)qingcheng_service_goods工程BrandServiceImpl新增方法

/**
* 分页+条件查询
* @param searchMap
* @param page
* @param size
* @return
*/
public PageResult<Brand> findPage(Map<String, Object> searchMap, int
page, int size) {

PageHelper.startPage(page,size);
Example example = createExample(searchMap);
Page<Brand> brands = (Page<Brand>)
brandMapper.selectByExample(example);
return new PageResult<Brand>
(brands.getTotal(),brands.getResult());
}

(3)qingcheng_web_manager工程BrandController新增方法

@PostMapping("/findPage")
public PageResult<Brand> findPage(@RequestBody Map<String,Object>
searchMap,int page, int size){

return brandService.findPage(searchMap,page,size);
}

使用了多态,将findPage执行了分页与条件的多次编写
在这里插入图片描述

5.3.5 根据ID查询品牌

url
/brand/findById.do
http请求方式
GET
请求参数
在这里插入图片描述

代码实现:
(1)qingcheng_interface工程BrandService接口新增方法

public Brand findById(Integer id);

(2)qingcheng_service_goods工程BrandServiceImpl新增方法
接口,实现,网址映射

/**
* 根据Id查询
* @param id
* @return
*/
public Brand findById(Integer id) {

return brandMapper.selectByPrimaryKey(id);
}

(3)qingcheng_web_manager工程BrandController新增方法

@GetMapping("/findById")
public Brand findById(Integer id){

return brandService.findById(id);
}

在这里插入图片描述

5.3.6 品牌新增

(1)qingcheng_pojo 新增类

/**
* 返回前端的消息封装,正确错误都有信息了
*/
public class Result implements Serializable {

private Integer code;//返回的业务码 0:成功执行 1:发生错误
private String message;//信息
public Result(Integer code, String message) {

this.code = code;
this.message = message;
}
public Result() {

this.code=0;
this.message = "执行成功";
}
public Integer getCode() {

return code;
}
public void setCode(Integer code) {

this.code = code;
}
public String getMessage() {

return message;
}
public void setMessage(String message) {

this.message = message;
}
}

(2)qingcheng_interface工程BrandService接口新增方法

public void add(Brand brand);

(3)qingcheng_service_goods工程BrandServiceImpl新增方法

/**
* 新增
* @param brand
*/
public void add(Brand brand) {

brandMapper.insert(brand);
}

(4)qingcheng_web_manager工程BrandController新增方法

@PostMapping("/add")
public Result add(@RequestBody Brand brand){

brandService.add(brand);
return new Result();
}

在这里插入图片描述

5.3.7 品牌修改

对于修改的方法,
第一个根据条件更新,第二个是如果有null值会被忽略,如果包含null值会被覆盖还是忽略,第四个为忽略,更加实用,不覆盖该数据库原来的数据
在这里插入图片描述

(1)qingcheng_interface工程BrandService接口新增方法

public void update(Brand brand);

(2)qingcheng_service_goods工程BrandServiceImpl新增方法

/**
* 修改
* @param brand
*/
public void update(Brand brand) {

brandMapper.updateByPrimaryKeySelective(brand);
}

(3)qingcheng_web_manager工程BrandController新增方法

@PostMapping("/update")
public Result update(@RequestBody Brand brand){

brandService.update(brand);
return new Result();
}

5.3.8 品牌删除

url
/brand/delete.do
http请求方式
GET
请求参数
在这里插入图片描述

例子:

GET /brand/delete.do?id=1

返回格式:

{

code:0,
message:""
}

code为0表示成功,为1表示失败
代码实现:
(1)qingcheng_interface工程BrandService接口新增方法

public void delete(Integer id);

(2)qingcheng_service_goods工程BrandServiceImpl新增方法

/**
* 删除
* @param id
*/
public void delete(Integer id) {

brandMapper.deleteByPrimaryKey(id);
}

(3)qingcheng_web_manager工程BrandController新增方法

@GetMapping("/delete")
public Result delete(Integer id){

brandService.delete(id);
return new Result();
}

以上主要是为了尝试,通用mapper的方法

6. 公共异常处理

应该将项目所有的异常,进行统一管理
qingcheng_common_web工程创建com.qingcheng.controller包,包下创建类

/**
* 统一异常处理类
*/
@ControllerAdvice
public class BaseExceptionHandler {

@ExceptionHandler(Exception.class)
@ResponseBody
public Result error(Exception e) {

e.printStackTrace();
System.out.println("调用了公共异常处理类");
return new Result(1,e.getMessage());
}
}

注意回顾系统架构图,所有的都是围绕其展开

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/100219.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 2019全球最火的编程语言,学哪个前景更好?(转行者必看)

    2019全球最火的编程语言,学哪个前景更好?(转行者必看)

  • android浏览器插件介绍

    android浏览器插件介绍一浏览器插件介绍:  1.1概述浏览插件本质是一个功能模块,是浏览器功能的一种扩充。其载体是dll或则so文件。它依附浏览器完成某一特定的功能。插件需要实现浏览器规定的一些函数,这些函数叫NPAPI.正是插件实现了这些函数才可以和浏览器交互。同时浏览器也为插件提供一些函数。在android平台下还有一些专有的函数。他们的函数名字都有约定。插件提供的方法以NPP_打头。浏览器提供的方法

  • 程序员即装逼又实用的Cmd命令行

    程序员即装逼又实用的Cmd命令行首先windows键+R(+R)打开运行,输入cmd回车打开命令行。1、cleanmgr选择盘符清理垃圾,能加快电脑运行速度。2、chkdsk磁盘检查,能检查磁盘是否有损害。3、devmgmt打开设备管理器4、dxdiag打开DirectX诊断工具,买二手电脑是避免黑商修改电脑配5、ping:ping192.168.0.1判断某台电脑是否能连…

  • K8S常用命令合集

    K8S常用命令合集

  • 基于SSM的校园二手交易平台的设计与实现「建议收藏」

    基于SSM的校园二手交易平台的设计与实现「建议收藏」PS:Java版本:1.7数据库:MySQL框架:Spring+SpringMVC+MyBatis服务器:Tomcat前端解析框架:Thymeleaf开发工具:Idea2017版本管理工具:Maven版本控制工具:GitHub下载地址:https://download.csdn.net/download/wsk1103/10395604一、设计概…

  • springboot集成elasticsearch注意事项

    springboot集成elasticsearch注意事项一、elasticsearch基础  这里假设各位已经简单了解过elasticsearch,并不对es进入更多的,更深层次的解释,如有必要,会在写文章专门进行es讲解。  Elasticsearch是一个基于ApacheLucene(TM)的开源搜索引擎。无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。  但是,Lucene只是一个…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号