SSM练手之小米商城-笔记

2020-03-03  本文已影响0人  zfz_amzing

2、mybatis逆向工程

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

1、创建商城项目

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

maven项目

引入逆向工程依赖

<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)依赖添加

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的单元测试,需要以下依赖

 <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)相应数据封装

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

在项目中定义工具类型,封装响应数据: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、首页数据加载

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

开发业务处理层

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类中不包含图片的地址,在类中添加图片地址的属性

private List<GoodsImages> goodsImages;

    public List<GoodsImages> getGoodsImages() {
        return goodsImages;
    }

    public void setGoodsImages(List<GoodsImages> goodsImages) {
        this.goodsImages = goodsImages;
    }
<!--修改了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>
  <!-- 改造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

开发首页视图:/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

二级类型查看

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

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);
    }
}

网页视图处理

上一篇下一篇

猜你喜欢

热点阅读