美文网首页
SSM练手之小米商城-笔记

SSM练手之小米商城-笔记

作者: zfz_amzing | 来源:发表于2020-03-03 17:05 被阅读0次

    2、mybatis逆向工程

    逆向工程是通过数据库中已经存在的数据表,反向生成Java中的实体类Java中的实体类(生成对应的持久层代码)

    1、创建商城项目

    代码生成器作为商城项目的一个工具组件存在。

    maven项目

    引入逆向工程依赖

    • mybatis-generator-core
    • mybatis-connector-java
    <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.19</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-core</artifactId>
                <version>1.4.0</version>
            </dependency>
    

    2、配置生成规则

    逆向工程的生成规则,就是描述数据库中的那些表,生成对应的Java中的实体类,同时生成映射配置文件。这个生成规则就是一个普通的配置文件。

    在项目的主目录中创建一个配置文件:generator.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE generatorConfiguration
            PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
            "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
    
    <generatorConfiguration>
    <!--    <classPathEntry location="/Program Files/IBM/SQLLIB/java/db2java.zip" />-->
    
        <context id="DB2Tables" targetRuntime="MyBatis3">
            <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                            connectionURL="jdbc:mysql:localhost:3306/xiaomi"
                            userId="root"
                            password="123456">
            </jdbcConnection>
    
            <javaTypeResolver >
                <property name="forceBigDecimals" value="false" />
            </javaTypeResolver>
    
            <javaModelGenerator targetPackage="com.zfz.xiaomi.entry" targetProject=".\src\main\java">
                <property name="enableSubPackages" value="true" />
                <property name="trimStrings" value="true" />
            </javaModelGenerator>
    
            <sqlMapGenerator targetPackage="mapper"  targetProject=".\src\main\resources">
                <property name="enableSubPackages" value="true" />
            </sqlMapGenerator>
    
            <javaClientGenerator type="XMLMAPPER" targetPackage="com.zfz.xiaomi.dao"  targetProject=".\src\main\java">
                <property name="enableSubPackages" value="true" />
            </javaClientGenerator>
    
    <!--        映射关系-->
            <table tableName="consumer" domainObjectName="Consumer"></table>
            <table tableName="goods" domainObjectName="Goods"></table>
            <table tableName="goods_images" domainObjectName="GoodsImages"></table>
            <table tableName="goods_type" domainObjectName="GoodsType"></table>
            <table tableName="goods_service" domainObjectName="GoodsService"></table>
            <table tableName="goods_package" domainObjectName="GoodsPackage"></table>
            <table tableName="goods_configure" domainObjectName="GoodsConfigure"></table>
            <table tableName="goods_cart" domainObjectName="GoodsCart"></table>
            <table tableName="goods_order" domainObjectName="GoodsOrder"></table>
            <table tableName="goods_order_item" domainObjectName="GoodsOrderItem"></table>
            <table tableName="goods_shipping_address" domainObjectName="GoodsShippingAddress"></table>
            
    
        </context>
    </generatorConfiguration>
    

    3、逆向工程

    通过配置文件指定的生成规则,自动构建实体类和数据访问类,参考官方文档

    public class CodeGenerator {
        public static void main(String[] args) throws  Exception{
            List<String> warnings = new ArrayList<String>();
            boolean overwrite = true;
            File configFile = new File("generator.xml");
            ConfigurationParser cp = new ConfigurationParser(warnings);
            Configuration config = cp.parseConfiguration(configFile);
            DefaultShellCallback callback = new DefaultShellCallback(overwrite);
            MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
            myBatisGenerator.generate(null);
        }
    }
    
    

    3、SSM项目整合

    (1)配置文件整合

    spring配置文件:src/main/resources/applicationContext.xml

    springMVC配置文件:src/main/resources/springMVC.xml

    mybatis配置文件:src/main/rescources/mybatis-config.xml

    数据源配置文件:scr/main/resoucres/db.properties

    在启动时,框架初始化需要在web.xml中添加启动配置

    在项目中创建对应的配置文件,同时添加web支持

    (2)依赖添加

    • spring-core
    • spring-context
    • spring-beans
    • spring-expression
    • spring-insuiession
    • spring-jdbc
    • spring-orm
    • spring-web
    • spring-webmvc
    • mybatis
    • mybatis-spring
    • c3p0
    • mysql-connector-java
    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>org.example</groupId>
        <artifactId>Xiaomi</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <dependencies>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.19</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-core</artifactId>
                <version>1.4.0</version>
            </dependency>
        </dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.4</version>
        </dependency>
    
    
    </project>
    

    (3)细化配置信息

    4、单元测试

    (1)引入依赖

    基于spring的单元测试,需要以下依赖

    • spring-test
    • junit
    • spring-aop
    • aspectj
     <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>5.2.1.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>5.2.1.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.9.5</version>
            </dependency>
    
    

    (2)单元测试代码

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = {"classpath:applicationContext.xml"})
    public class DaoTest {
        @Autowired
        private ConsumerMapper consumerMapper;
    
        @Test
        public void testConsumerInsert(){
            Consumer consumer = new Consumer("zfz","123");
            //讲consumer添加到数据库 insertSelective在只有部分属性有值时使用
            consumerMapper.insertSelective(consumer);
            System.out.println("insertSelective执行完成");
        }
     }
        
    

    5、业务模型开发&封装响应

    从业务模型处理>>复杂业务模型操作

    登录、注册>>首页数据加载-->搜索>>购物车>>订单

    (1)登录业务

    首先创建用户相关业务处理类:com.zfz.xiaomi.service.ConsumerService.java

    @Service
    public class ConsumerService {
    
        @Autowired
        private ConsumerMapper consumerMapper;
    
        public boolean findConsumerWithUsernameAndPassword(Consumer consumer ){
            ConsumerExample ce = new ConsumerExample();
            ce.createCriteria().andUsernameEqualTo(consumer.getUsername()).andPasswordEqualTo(consumer.getPassword());
            List<Consumer> consumerList = consumerMapper.selectByExample(ce);
    
            return consumerList != null && consumerList.size() == 1;
        }
    }
    
    

    创建用户相关业务的访问接口/控制器:com.zfz.xiaomi.controller.ConsumerController.java

    @Controller
    @RequestMapping("/consumer")
    public class ConsumerController {
    
        @Autowired
        private ConsumerService consumerService;
    
        @PostMapping("/login/auth")
        public String login(@RequestParam String username,@RequestParam String password){
            System.out.println("接收到请求:/consumer/login/auth");
            System.out.println("账号:"+username+"密码:"+password);
            Consumer consumer = new Consumer(username,password);
            boolean result = consumerService.findConsumerWithUsernameAndPassword(consumer);
            System.out.println("登录结果: "+ result);
            return result ? "success" : "error";
        }
    }
    
    

    针对登录业务进行响应数据封装

    基于web业务的单元测试

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = {"classpath:applicationContext.xml", "classpath:springMVC.xml"})
    @WebAppConfiguration
    public class WebTest {
    
        //声明一个模拟请求的对象
        private MockMvc mockMvc;
        //需要一个web容器
        @Autowired
        private WebApplicationContext context;
    
        @Before
        public  void SetUp(){
            mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
        }
    
        @Test
        public void testLogin() throws Exception {
            //发送post请求
            MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/consumer/login/auth")
                    .param("username", "zfz")
                    .param("password", "123")).andReturn();
    
            System.out.println(mvcResult.getResponse().getContentAsString());
        }
    }
    
    

    (2)相应数据封装

    关于数据接口,提供给客户端调用,并且返回符合预期标准的数据访问接口,通常会有如下的要求

    • 固定格式的参数,根据需求提供调用接口即可
    • 返回数据-错误码:快捷判断响应结果是否正确的错误标志,HTTP:200 正确;404 未找到资源; 500 服务器内部错误
    • 返回数据-错误描述:针对错误码具体错误信息的描述
    • 返回数据-数据封装:具体包含的一个或者多个数据

    在项目中定义工具类型,封装响应数据:com.zfz.xiaomi.utils.ResponsMessage.java

    public class ResponseMessage {
        private  String errorCode;
        private  String errMsg;
        private Map<String,Object> objectMap = new HashMap<>();
    
        public String getErrorCode() {
            return errorCode;
        }
    
        public void setErrorCode(String errorCode) {
            this.errorCode = errorCode;
        }
    
        public String getErrMsg() {
            return errMsg;
        }
    
        public void setErrMsg(String errMsg) {
            this.errMsg = errMsg;
        }
    
        public Map<String, Object> getObjectMap() {
            return objectMap;
        }
    
        public void setObjectMap(Map<String, Object> objectMap) {
            this.objectMap = objectMap;
        }
        
        public ResponseMessage addObject(String key, Object value){
            this.objectMap.put(key, value);
            return this;
        }
        
        //处理成功相应的方法
        public static ResponseMessage success(){
            ResponseMessage rm = new ResponseMessage();
            rm.setErrorCode("100");
            rm.setErrMsg("处理成功");
            return rm;
        }
        public static ResponseMessage error(){
            ResponseMessage rm = new ResponseMessage();
            rm.setErrorCode("200");
            rm.setErrMsg("处理失败");
            return rm;
        }
        
    }
    

    重构登陆业务

    
        @PostMapping("/login/auth")
        @ResponseBody //@responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据。
        public ResponseMessage login(@RequestParam String username, @RequestParam String password){
            System.out.println("接收到请求:/consumer/login/auth");
            System.out.println("账号:"+username+"密码:"+password);
            Consumer consumer = new Consumer(username,password);
            boolean result = consumerService.findConsumerWithUsernameAndPassword(consumer);
            System.out.println("登录结果: "+ result);
            return result ? ResponseMessage.success() : ResponseMessage.error();
        }
    

    6、登录

        <script>
            $(function() {
               // 点击登录按钮时,发送ajax请求
               $("#login-btn").click(function() {
                   // 发送ajax请求
                   $.ajax({
                       url: "/xiaomi/consumer/login/auth",
                       method: "post",
                       data: {
                           "username": $("#username").val(),
                           "password": $("#password").val()
                       },
                       success:function(response) {
                           console.log("请求发送成功");
                           console.log(response);
                           if(response.errorCode === "100") {
                               // 登录成功
                               alert("用户登录成功!");
                               window.location = "/xiaomi/index.jsp";
                           } else {
                               // 登录失败
                               $("#error-username").text("账号或者密码有误,请重新登录").css({"color": "red"});
                           }
                       },
                       error: function() {
                           console.log("请求发送失败..");
    
                       }
                   });
               });
            });
        </script>
    

    7、用户注册

    业务层:com.zfz.xiaomi.service.ConsumerService.java

    ​ 添加注册方法:register()

    public String register(Consumer consumer){
            //验证用户名是否存在
            ConsumerExample ce = new ConsumerExample();
            ce.createCriteria().andUsernameEqualTo(consumer.getUsername());
    
            List<Consumer> consumerList = consumerMapper.selectByExample(ce);
            if(consumerList.size() > 0){
                return "注册失败,用户名已存在";
            }
            return "注册成功";
        }
    

    业务层:com.zfz.xiaomi.service.ConsumerController.java

    ​ 添加注册方法:register()

      @PostMapping(value = "/register",produces = {"application/json;charset=UTF-8"})
        @ResponseBody
        public ResponseMessage register(@RequestParam String username, @RequestParam String password){
            Consumer consumer = new Consumer(username,password);
            String result = consumerService.register(consumer);
            //判断结果
            if (result.contains("注册成功")){
                return  ResponseMessage.success();
            }
            return ResponseMessage.error().addObject("msg",result);
    
        }
    

    网页视图及功能完善

    web/register.jsp+'jquery'脚本

    <script src="js/jquery/jquery-3.4.1.js"></script>
        <script>
            $(function() {
                // 点击注册按钮时,发送请求
                $("#register-btn").click(function() {
                    // 发送Ajax请求
                    $.ajax({
                        url: "/xiaomi/consumer/register",
                        method: "POST",
                        data: {
                            "username": $("#username").val(),
                            "password": $("#password").val()
                        },
                        success: function(response) {
                            if(response.errorCode === "100") {
                                alert("Congratulations,账号注册成功,请登录吧");
                                window.location = "/xiaomi/login.jsp";
                            }else{
                                $("#errorMsg").text(response.objectMap.msg).css({"color": "red"});
                            }
                        },
                        error: function() {
                            $("#errorMsg").text("请求迷路了,小二正在赶来的路上,请稍后再试..").css({"color": "red"});
                        }
                    });
                });
            });
        </script>
    

    8、首页数据加载

    首页中需要的数据从后台获取并添加

    • 商品类型
    • 每种类型下的商品

    开发业务处理层

    • 商品类型: com.zfz.xiaomi.service.GoodsTypeService.java

    • 商品:com.zfz.xiaomi.service.GoodsShippingService.java

      反例:项目设计时充分考虑不同的代码层、组件模块之间的命名规则和规范。避免出现不同模块、不同代码层出现相同/相似名称的类型,降低代码质量和可读性

    image-20200224185908599.png

    GoodsTypeService.java

    @Service
    public class GoodsTypeService {
    
        @Autowired
        private GoodsTypeMapper goodsTypeMapper;
        /**
         * 查询一级商品类型
         * @return 返回所有的一级商品类型
         */
        public List<GoodsType> findTopLevel(){
            GoodsTypeExample gte = new GoodsTypeExample();
            gte.createCriteria().andPidIsNotNull();
            return goodsTypeMapper.selectByExample(gte);
        }
    
        /**
         * 查询二级商品类型
         * @param top 一级商品类型
         * @return 返回对应的二级商品类型
         */
        public List<GoodsType> findSecondLevel(GoodsType top){
            GoodsTypeExample gte = new GoodsTypeExample();
            gte.createCriteria().andPidEqualTo(top.getId());
            return goodsTypeMapper.selectByExample(gte);
        }
    }
    
    

    GoodsShippingService.java

    @Service
    public class GoodsShippingService {
        
        @Autowired
        private GoodsMapper goodsMapper;
    
        /**
         * 根据商品类型查询商品
         * @param goodsType 商品类型
         * @return 属于指定商品类型的所有商品
         */
        public List<Goods> findGoodsWithType(GoodsType goodsType){
            GoodsExample ge = new GoodsExample();
            ge.createCriteria().andGoodsTypeIdEqualTo(goodsType.getId());
            return goodsMapper.selectByExample(ge);
        }
    }
    

    首页数据加载完善

    生成的Goods类中不包含图片的地址,在类中添加图片地址的属性

    • com.zfz.xiaomi.entry.Goods.java
    private List<GoodsImages> goodsImages;
    
        public List<GoodsImages> getGoodsImages() {
            return goodsImages;
        }
    
        public void setGoodsImages(List<GoodsImages> goodsImages) {
            this.goodsImages = goodsImages;
        }
    
    • mapper/GoodsMapper.xml
    <!--修改了selectByExample,使其能在goodsImages表中查询到图片地址 -->
    <select id="selectByExample" parameterType="com.zfz.xiaomi.entry.GoodsExample" resultMap="ResultMapWithGoodsImages">
        <!--
          WARNING - @mbg.generated
          This element is automatically generated by MyBatis Generator, do not modify.
          This element was generated on Sun Feb 23 17:50:08 CST 2020.
        -->
        select g.id, g.name,g.price,g.stock,g.goods_type_id,g.remark,
               gi.id giid,gi.path, gi.title, gi.alt
        from goods g
        left join goods_images gi
        on g.id = gi.goods_id
        <if test="_parameter != null">
          <include refid="Example_Where_Clause" />
        </if>
        <if test="orderByClause != null">
          order by ${orderByClause}
        </if>
      </select>
    
    • mapper/GoodsMapper.xml
      <!-- 改造resultMap -->
      <resultMap extends="BaseResultMap" id="ResultMapWithGoodsImages" type="com.zfz.xiaomi.entry.Goods">
    
        <result column="remark" jdbcType="LONGVARCHAR" property="remark" />
        <collection property="goodsImages" ofType="com.zfz.xiaomi.entry.GoodsImages">
          <id column="giid" property="id"/>
          <result column="path" property="path"/>
          <result column="title" property="title"/>
          <result column="alt" property="alt"/>
        </collection>
      </resultMap>
    

    开发首页控制器com.zfz.xiaomi.controller.IndexController.java

    • initIndex(..):加载首页数据的控制器方法,前端网页中通过JQuery Ajax请求获取数据

    开发首页视图:/web/index.jsp渲染展示商品

    9、商品搜索

    基本搜索功能,直接和数据库交互,通过sql语句完成商品数据的检索
    企业项目需要的搜索功能,很少会直接和数据库进行交互,一般情况下会使用数据中间件框架elasticesearch

    (1)、商品按名称模糊搜索

    业务层方法开发:com.zfz.xiaomi.service.GoodsShipService.java

      /**
         * 根据名称模糊搜索商品数据
         * @param name 商品名称
         * @return 返回符合条件的商品
         */
        public List<Goods> searchGoodsWithName(String name ){
            GoodsExample ge = new GoodsExample();
            ge.createCriteria().andNameLike("%" + name + "%");
            return goodsMapper.selectByExample(ge);
        }
    

    控制层方法com.zfz.xiaomi.controller.UtilsController.java

        @GetMapping("/search/{name}")
        @ResponseBody
        private ResponseMessage searchGoodsWithName(@PathVariable String name){
            List<Goods> goodsList = goodsShippingService.searchGoodsWithName(name);
            return goodsList.size() > 0 ? ResponseMessage.success().addObject("goodsList", goodsList)
                                        : ResponseMessage.error();
        }
    

    单元测试

     @Test
        public void testSearchGoods(){
            List<Goods> goodsList = goodsShippingService.searchGoodsWithName("小米");
            goodsList.forEach(goods -> System.out.println(goods));
        }
    

    网页视图开发

        <!-- 搜索框 index.jsp-->
        <form action="#" id="search">
            <input type="text">
            <button></button>
        </form>
    

    (2)、商品按类型检索

    一级类型查看

    首页导>>根据一级类型查看所有商品

    业务层:com.zfz.xiaomi.service.GoodsShippingService

        /**
         * 根据二级类型查询商品数据
         * @param goodsType 一级类型
         * @return 返回所有商品
         */
        public List<Goods> findGoodsWithTopType(GoodsType goodsType){
            //查询一级类型下的所有二级类型
            List<GoodsType> gt = goodsTypeService.findSecondLevel(goodsType);
            //查询所有二级类型下所有商品
            List<Goods> goodsList = new ArrayList<>();
            for (GoodsType goodsType1 : gt){
                List<Goods> goodses = this.findGoodsWithType(goodsType1);
                goodsList.addAll(goodses);
            }
            return goodsList;
        }
    

    控制层:com.zfz.xiaomi.controller.UtilsController

    /**
         * 根据类型查看商品
         * @param level level 类型级别 1一级类型 2 二级类型
         * @param goodTypeId 类型编号
         * @return 返回响应数据
         */
        @GetMapping("search/{level}/{gtId}")
        public ResponseMessage searchGoodsWithType(@PathVariable Integer level, @PathVariable Integer goodTypeId){
    
            GoodsType goodsType = goodsTypeService.findById(goodTypeId);
            List<Goods> goodsList = null;
            if (level == 1){
                goodsList = goodsShippingService.findGoodsWithTopType(goodsType);
            } else if (level == 2){
                goodsList = goodsShippingService.findGoodsWithType(goodsType);
            }
            return goodsList != null && goodsList.size() > 0
                    ? ResponseMessage.success().addObject("goodsList", goodsList)
                    : ResponseMessage.error();
        }
    

    视图处理web/goodslist2.jsp

    • index.jsp 导航发起
    • 跳转到指定页面goodslist2.jsp
    • 在商品列表页面中,获取查询参数,发送请求获取数据

    二级类型查看

    楼层商品>>根据二级类型查看更多

    10、商品详情处理

    业务模型处理方法:com.zfz.xiaomi.service.GoodsShippingService.java
    开发业务层处理方法:findGoodsWithId(..),完善对应的GoodsMapper.xml

    /**
         * 根据id查询商品
         * @param id 商品的id 
         * @return 查询到的商品
         */
        public Goods findGoodWithId(Integer id){
            return goodsMapper.selectByPrimaryKey(id);
        }
    

    商品详情控制器接口开发:com.zfz.xiaomi.controller.GoodsController.java

    @Controller
    @RequestMapping("/goods")
    public class GoodsController {
        
        @Autowired
        private GoodsShippingService goodsShippingService;
        
        @GetMapping("/detail/{gid}")
        @ResponseBody
        public ResponseMessage findGoodsWithId(@PathVariable Integer gid){
            Goods goods = goodsShippingService.findGoodWithId(gid);
            return ResponseMessage.success().addObject("goods",goods);
        }
    }
    

    网页试图处理:‘web/detail.jsp’
    跳转index.jsp||goodslist.jsp>>detail.jsp?gid=***发送Ajax请求获取对应的商品信息

    11、购物车

    商品加入购物车

    detail.jsp商品详情页>>加入购物车>>加入购物车流程

    业务处理层:com.damu.xiaomi.service.ShopCartService.java

    public class ShopCartService {
    
        @Autowired
        private GoodsCartMapper goodsCartMapper;
    
        /**
         * 判断某个商品在购物车中是否存在
         * @param consumer 指定用户
         * @param goods 指定商品
         * @return
         */
        private List<GoodsCart> checkGoods(Consumer consumer, Goods goods){
            //查询指定的商品在当前用户的购物车中是否存在
            GoodsCartExample gce = new GoodsCartExample();
            gce.createCriteria().andConsumerIdEqualTo(consumer.getId()).andGoodsIdEqualTo(goods.getId());
            //查询操作
            List<GoodsCart> cartList = goodsCartMapper.selectByExample(gce);
            return  cartList;
        }
        
        /**
         * 指定商品加入购物车
         * @param goods 要加入购物车的商品
         * @return 返回加入结果
         */
        public boolean addGoodsToShopCart(Consumer consumer,Goods goods){
            List <GoodsCart> cartList = this.checkGoods(consumer, goods);
            if (cartList.size() > 0){
                //更新购买数量
                int count = cartList.get(0).getBuyCount();
                cartList.get(0).setBuyCount(count + 1);
                //更新小计金额
                double totalPrice = cartList.get(0).getSubtotal()/count * cartList.get(0).getBuyCount();
                cartList.get(0).setSubtotal(totalPrice);
            }else {
                //新增商品
                GoodsCart goodsCart = new GoodsCart(goods.getId(),1,new Date(), goods.getPrice(), consumer.getId());
                goodsCartMapper.insertSelective(goodsCart);
            }
            return true;
        }
    
        /**
         * 从购物车中删除商品
         * @param goods 要删除的商品
         * @return 返回删除结果
         */
        public boolean removeGoodsFromShopCart(Consumer consumer,Goods goods){
            List<GoodsCart> cartList = this.checkGoods(consumer, goods);
            if (cartList.size() > 0){
                goodsCartMapper.deleteByPrimaryKey(cartList.get(0).getId());
                return true;
            }
            System.out.println("商品不存在");
            return false;
        }
    
        /**
         * 查询指定用户购物车中的所有商品
         * @param consumer 指定用户
         * @return 返回该用户购物车的所有商品
         */
        public List<GoodsCart> findAllGoodsCartWithConsumer(Consumer consumer){
            GoodsCartExample gce = new GoodsCartExample();
            gce.createCriteria().andConsumerIdEqualTo(consumer.getId());
            return goodsCartMapper.selectByExample(gce);
        }
        
        
    }
    
    

    重构登陆业务com.zfz.xiaomi.controller.ConsumerCroller.java

    1. 验证密码+账号
    2. 登记用户 -- 会话跟踪【session】
        @PostMapping(value = "/login/auth",produces = {"application/json;charset=UTF-8"})
        @ResponseBody //@responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据。
        public ResponseMessage login(@RequestParam String username, @RequestParam String password,
                                     HttpSession session){
            System.out.println("接收到请求:/consumer/login/auth");
            System.out.println("账号:"+username+"密码:"+password);
            Consumer consumer = new Consumer(username,password);
            consumer = consumerService.findConsumerWithUsernameAndPassword(consumer);
            System.out.println("登录结果: "+ consumer);
            //记录登录用户
            session.setAttribute("loginConsumer", consumer);
            return consumer != null  ? ResponseMessage.success() : ResponseMessage.error();
        }
    

    控制层:com.zfz.xiaomi.controller.ShopCartController.java

    @Controller
    @RequestMapping("/shopcart")
    public class ShopCartController {
    
        @Autowired
        private ShopCartService shopCartService;
        @Autowired
        private GoodsShippingService goodsShippingService;
    
    
        /**
         * 商品加入购物车
          * @param goodsId 商品id
         * @param session session中携带consumer信息
         * @return 成功或失败
         */
        @GetMapping("/add/{goodsId}")
        @ResponseBody
        public ResponseMessage addGoodsToCart(@PathVariable Integer goodsId, HttpSession session){
            //获取当前用户
            Consumer consumer = (Consumer) session.getAttribute("loginConsumer");
            if (consumer == null)
                return ResponseMessage.error();
    
            //加入商品到购物车
            Goods goods = goodsShippingService.findGoodWithId(goodsId);
            shopCartService.addGoodsToShopCart(consumer,goods);
            return ResponseMessage.success();
        }
    
        /**
         * 从购物车中删除指定商品
         * @param goodsId 商品id
         * @param session session中携带consumer信息
         * @return 成功或失败
         */
        @GetMapping("/remove/{goodsId}")
        public ResponseMessage removeGoodsToCart(@PathVariable Integer goodsId, HttpSession session){
            //获取当前用户
            Consumer consumer = (Consumer) session.getAttribute("loginConsumer");
            if (consumer == null)
                return ResponseMessage.error();
            Goods goods = goodsShippingService.findGoodWithId(goodsId);
            shopCartService.removeGoodsFromShopCart(consumer,goods);
            return ResponseMessage.success();
    
        }
        @GetMapping("/chk")
        public ResponseMessage findAllWithConsumer(HttpSession session){
            //获取当前用户
            Consumer consumer = (Consumer) session.getAttribute("loginConsumer");
            if (consumer == null)
                return ResponseMessage.error();
            List<GoodsCart> cartList = shopCartService.findAllGoodsCartWithConsumer(consumer);
            return ResponseMessage.success().addObject("cartList",cartList);
        }
    }
    

    网页视图处理

    • 添加商品到购物车的操作:详情页完成
    • 查看购物车商品:购物车页面
    • 从购物车中删除对应的商品:购物车页面

    相关文章

      网友评论

          本文标题:SSM练手之小米商城-笔记

          本文链接:https://www.haomeiwen.com/subject/kawhlhtx.html