| 
 
| 4. 青橙-工程搭建 
 4.1 准备工作
 
 (1)配置maven本地仓库  【资料/本地仓库】
 
 (2)创建数据库表  【资料/建表语句】
 
 (3)注册中心zookeeper   【资料/配套软件 】
 
 4.2 模块依赖关系图
 
 我们的工程有三种模块:(1)公共模块 (2)服务层模块 (3)web层模块。
 
 公共模块主要由公共配置和公共类构成。模块依赖关系入下图:
 
 
 
 4.3 工程搭建
 
 4.3.1 父工程与公共模块
 
 (1)创建父工程qingcheng_parent  pom.xml内容参见资源/配置文件/主架构/父工程/pom.xml
 
 (2)创建公共模块qingcheng_common,pom.xml内容参见资源/配置文件/主架构/公共模块/父公共模块/pom.xml     resources下创建applicationContext-common.xml
 
 <context:property-placeholder location="classpath*:*.properties" />
 
 resources下创建dubbo-address.properties
 
 dubbo.address=192.168.25.130:2181
 
 resources下创建log4j.properties
 
 ### direct log messages to stdout ###
 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
 log4j.appender.stdout.Target=System.err
 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
 log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
 
 ### direct messages to file mylog.log ###
 log4j.appender.file=org.apache.log4j.FileAppender
 log4j.appender.file.File=c:\\mylog.log
 log4j.appender.file.layout=org.apache.log4j.PatternLayout
 log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
 
 ### set log levels - for more verbose logging change 'info' to 'debug' ###
 
 log4j.rootLogger=debug, stdout
 
 (3)创建qingcheng_common_service ,pom.xml 参见资源/配置文件/主架构/公共模块/服务公共模块/pom.xml
 
 resources下创建applicationContext-dao.xml
 
 <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">
 <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>
 <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
 
 resources下创建applicationContext-dubbo.xml
 
 <dubbo:protocol name="dubbo" port="${dubbo.port}"/>
 <dubbo:application name="${dubbo.application}" />
 <dubbo:registry protocol="zookeeper" address="192.168.25.130:2181" />
 <dubbo:annotation package="com.qingcheng.service" />
 
 (4)创建qingcheng_common_web模块,pom.xml
 
 <dependency>
 <groupId>com.qingcheng</groupId>
 <artifactId>qingcheng_common</artifactId>
 <version>1.0-SNAPSHOT</version>
 </dependency>
 <dependency>
 <groupId>commons-fileupload</groupId>
 <artifactId>commons-fileupload</artifactId>
 </dependency>
 <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>org.springframework.security</groupId>
 <artifactId>spring-security-taglibs</artifactId>
 </dependency>
 
 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}" />
 <dubbo:registry protocol="zookeeper" address="${dubbo.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>
 
 
 <dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <version>1.16.16</version>
 <scope>provided</scope>
 </dependency>
 
 (6)创建服务接口层模块  qingcheng_interface ,pom.xml
 
 <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>
 <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
 
 <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>
 
 <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    品牌表
 
 字段名称          字段含义          字段类型           字段长度        备注
 id            品牌id          INT
 name          品牌名称          VARCHAR        100
 image         品牌图片地址        VARCHAR        1000
 letter        品牌的首字母        CHAR           1
 seq           排序            INT
 
 
 
 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,包下创建数据访问层接口
 
 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();
 }
 
 }
 
 启动工程,浏览器测试:http://localhost:9101/brand/findAll.do
 
 5.3.2 品牌分页列表
 
 接口定义:
 
 url
 
 /brand/findPage.do
 
 http请求方式
 
 GET
 
 请求参数
 
 参数          必选          类型          说明
 page        true        int         页码
 size        true        int         每页记录数
 
 例子:
 
 GET /brand/findPage.do?page=1&size=10
 
 
 返回格式
 
 {rows:[{
 "id": 品牌id,
 "name": 品牌名称,
 "image": 品牌图片地址,
 "letter": 品牌的首字母,
 "seq": 排序,
 
 },
 .......
 ],
 total:100}
 
 
 代码实现:
 
 (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);
 }
 
 启动工程,浏览器测试:http://localhost:9101/brand/findPage.do?page=1&size=10
 
 5.3.3 品牌条件查询
 
 url
 
 /brand/findList.do
 
 http请求方式
 
 POST
 
 请求参数
 
 参数               必选          类型          说明
 searchMap        true        Map         条件对象,格式如实体对象
 
 例子:
 
 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")
 public List<Brand> findList(@RequestBody Map<String,Object> searchMap){
 return brandService.findList(searchMap);
 }
 
 5.3.4 品牌条件+分页查询
 
 url
 
 /brand/findPage.do
 
 http请求方式
 
 POST
 
 请求参数
 
 参数               必选          类型          说明
 searchMap        true        Map         条件对象,格式如实体对象
 page             true        int         页码(GET)
 size             true        int         每页记录数(GET)
 
 例子:
 
 POST /brand/findPage.do?page=1&size=10
 {
 "name": 品牌名称,
 "letter": 品牌的首字母
 }
 
 
 返回格式:
 
 | 
 |