小言_互联网的博客

javaweb-青橙项目-1-76

299人阅读  评论(0)

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);
说明:根据主键字段进行删除,方法参数必须包含完整的主键属性

  1. 青橙-工程搭建
    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());
    }
}

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


转载:https://blog.csdn.net/lidashent/article/details/115659185
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场