ssm(Spring、Springmvc、Mybatis)实战之淘淘商城-第二天(非原创)

文章大纲

一、课程介绍
二、整合淘淘商城ssm项目
三、Mybatis分页插件PageHelper使用
四、整合测试
五、项目源码与资料下载
六、参考文章

一、课程介绍

一共14天课程
(1)第一天:电商行业的背景。淘淘商城的介绍。搭建项目工程。Svn的使用。
(2)第二天:框架的整合。后台管理商品列表的实现。分页插件。
(3)第三天:后台管理。商品添加。商品类目的选择、图片上传、富文本编辑器的使用。
(4)第四天:商品规格的实现。
(5)第五天:商城前台系统的搭建。首页商品分类的展示。Jsonp。
(6)第六天:cms系统的实现。前台大广告位的展示。
(7)第七天:cms系统添加缓存。Redis。缓存同步。
(8)第八天:搜索功能的实现。使用solr实现搜索。
(9)第九天:商品详情页面的展示。
(10)第十天:单点登录系统。Session共享。
(11)第十一天:购物车订单系统的实现。
(12)第十二天:nginx。反向代理工具。
(13)第十三天:redis集群的搭建、solr集群的搭建。系统的部署。
(14)项目总结。

二、整合淘淘商城ssm项目

1. 后台所用技术

框架:Spring + SpringMVC + Mybatis
前端:EasyUI
数据库:mysql

2. 数据库操作

2.1 创建数据库
  使用Navicat for MySQL工具,连接mysql之后,新建一个数据库

导入.sql文件
  在该文章的资料下载内容中找到taotao.sql文件,在数据库操作工具中选择数据库名,右键选择运转SQL文件

  选择文件路径

  导入数据成功

3. 整合思路

3.1 持久层
  mybatis整合spring,通过spring管理SqlSessionFactory、mapper代理对象。需要mybatis和spring的整合包。

3.2 业务逻辑层
  所有的实现类都放到spring容器中管理。由spring创建数据库连接池,并有spring管理实务。

3.3 表现层
  Springmvc整合spring框架,由springmvc管理controller

4. 持久层整合实战

  在taotao-manager-web项目的资源文件下新建SqlMapConfig.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

</configuration>

  在taotao-manager-web项目的资源文件下新建applicationContext-dao.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop" 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.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

    <!-- 数据库连接池 -->
    <!-- 加载配置文件 -->
    <context:property-placeholder location="classpath:properties/*.properties"/>

    <!-- 数据库连接池   使用的是阿里巴巴的,其他的也可以,只是这个比较高效-->
    <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>

    <!-- 配置SqlsessionFactory  使用的是单例模式-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

        <!-- 加载mybatis的配置文件 -->
        <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml"/>

        <!-- 配置数据源 -->
        <property name="dataSource" ref="dataSource"/>

    </bean>

    <!--
        配置包扫描器,扫描mapper接口生成代理对象放到spring容器中
        basePackage 属性是让你为映射器接口文件设置基本的包路径。
         你可以使用分号或逗号 作为分隔符设置多于一个的包路径。每个映射器将会在指定的包路径中递归地被搜索到。
     -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

        <!-- 指定要扫描的包 -->
        <property name="basePackage" value="com.taotao.mapper"/>

    </bean>

</beans>

  在taotao-manager-web项目的资源文件下新建db.properties来管理Service实现类

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/taotao?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

温馨提示:
  在上面的配置文件中,我们使用了阿里巴巴封装的的数据库连接池。Druid是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。Druid已经在阿里巴巴部署了超过600个应用,经过多年多生产环境大规模部署的严苛考验。

5. 业务逻辑层整合

  在taotao-manager-web项目的资源文件下新建applicationContext-service.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop" 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.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

    <!-- 配置包扫描器,扫描@Service主键的类 -->
    <context:component-scan base-package="com.taotao.service"/>
</beans>

  在taotao-manager-web项目的资源文件下新建applicationContext-trans.xml配置进行事务管理

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" 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.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

    <!-- 
        事务配置
        
        在一个业务的实现过程中,可能需要多条sql完成对数据库的操作,比如账户登录,需要匹配用户名和密码,
        然后要增加积分,还要记录登录的ip和时间,这可能需要三个sql语句,这三个语句应当是一个整体,
        任意一个sql执行不成功,都表示这个业务没有执行完成,这就有了事务的概念。
        
        事务具有同步的特点,一条sql执行失败,其他sql都不会执行,即要么都执行,要么都不执行。
     -->
    <!-- 配置事务管理组件  -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        
        <!-- 数据源   bcp是连接池组件(org.apache.commons.dbcp2.BasicDataSource)的bean -->
        <property name="dataSource" ref="dataSource" />
        
    </bean>
    
    <!--配置切面行为     通知 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- 
                传播行为
                事务传播行为类型

                    说明
    
                    PROPAGATION_REQUIRED
                    如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
                    
                    PROPAGATION_SUPPORTS
                    支持当前事务,如果当前没有事务,就以非事务方式执行。
            
                    PROPAGATION_MANDATORY
                    使用当前的事务,如果当前没有事务,就抛出异常。
                    
                    PROPAGATION_REQUIRES_NEW
                    新建事务,如果当前存在事务,把当前事务挂起。
                    
                    PROPAGATION_NOT_SUPPORTED
                    以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
                    
                    PROPAGATION_NEVER
                    以非事务方式执行,如果当前存在事务,则抛出异常。
                    
                    PROPAGATION_NESTED
                    如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
             
                    事务属性中的readOnly标志表示对应的事务应该被最优化为只读事务。
                    如果值为true就会告诉Spring我这个方法里面没有insert或者update,
                    你只需要提供只读的数据库Connection就行了
                    这种执行效率会比read-write的Connection高,所以这是一个最优化提示。
                    在一些情况下,一些事务策略能够起到显著的最优化效果
             -->
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="create*" propagation="REQUIRED" />
            <tx:method name="delete*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="find*" propagation="SUPPORTS" read-only="true" />
            <tx:method name="select*" propagation="SUPPORTS" read-only="true" />
            <tx:method name="get*" propagation="SUPPORTS" read-only="true" />
        </tx:attributes>
    </tx:advice>
    
    <!--  配置切面  切面          com.taotao.service下所有方法       -->
    <aop:config>
        <aop:advisor advice-ref="txAdvice"
            pointcut="execution(* com.taotao.service.*.*(..))" />
    </aop:config>
</beans>

6. 表现层整合实战

  在taotao-manager-web项目的资源文件下新建Springmvc.xml配置文件

<?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: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-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.taotao.controller" />
    <mvc:annotation-driven />
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

  在taotao-manager-web项目的web.xml中添加以下内容

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>taotao-manager-web</display-name>
    <welcome-file-list>
        <welcome-file>login.html</welcome-file>
    </welcome-file-list>
    <!-- 加载spring容器 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/applicationContext*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- 解决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>


    <!-- springmvc的前端控制器 -->
    <servlet>
        <servlet-name>taotao-manager</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- contextConfigLocation不是必须的, 如果不配置contextConfigLocation, springmvc的配置文件默认在:WEB-INF/servlet的name+"-servlet.xml" -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>taotao-manager</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

7. 整合静态页面

  在文章的资料下载内容中,将css、jsp、js等资源拷贝到taotao-manager-web项目中

  由于在web.xml中定义的url拦截形式为“/”表示拦截所有的url请求,包括静态资源例如css、js等。所以需要在springmvc.xml中添加资源映射标签:

    <mvc:resources location="/WEB-INF/js/" mapping="/js/**"/>
    <mvc:resources location="/WEB-INF/css/" mapping="/css/**"/>

  在taotao-manager-mapper的pom文件下添加以下内容

<!-- 如果不添加此节点mybatis的mapper.xml文件都会被漏掉。 -->
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>

温馨提示:如果不添加此内容,在项目编译后,target文件夹中会漏掉mapper.xml文件内容,导致项目访问失败

8. Springmvc和spring的父子容器关系

例如:
在applicationContext-service中配置:

<!-- 扫描包加载Service实现类 -->
<context:component-scan base-package="com.taotao"></context:component-scan>

会扫描@Controller、@Service、@Repository、@Compnent

Springmvc.Xml中不扫描。因为配置的是在spring容器中
结论:springmvc。不能提供服务,因为springmvc子容器中没有controller对象。如果没有spring容器,则可以把所有注解放在spring mvc容器中。为什么要用spring和spring mvc容器,是为了扩展性强。

三、Mybatis分页插件PageHelper使用

  PageHelper目前支持Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库分页,使用前需要导入maven相关依赖

       <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
        </dependency>

1. SqlMapConfig.xml中配置插件

<?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE configuration
                PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageHelper">
        <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库-->
        <property name="dialect" value="mysql"/>
    </plugin>
</plugins>
</configuration>

2. 代码中使用分页功能

设置分页信息

//获取第1页,10条内容,默认查询总数count
    PageHelper.startPage(1, 10);

    //紧跟着的第一个select方法会被分页
List<Country> list = countryMapper.selectIf(1);

获取分页信息

//分页后,实际返回的结果list类型是Page<E>,如果想取出分页信息,需要强制转换为Page<E>,
Page<Country> listCountry = (Page<Country>)list;
listCountry.getTotal();

分页测试

public class TestPageHelper {

    @Test
    public void testPageHelper() {
        //创建一个spring容器
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-*.xml");
        //从spring容器中获得Mapper的代理对象
        TbItemMapper mapper = applicationContext.getBean(TbItemMapper.class);
        //执行查询,并分页
        TbItemExample example = new TbItemExample();
        //分页处理
        PageHelper.startPage(2, 10);
        List<TbItem> list = mapper.selectByExample(example);
        //取商品列表
        for (TbItem tbItem : list) {
            System.out.println(tbItem.getTitle());
        }
        //取分页信息
        PageInfo<TbItem> pageInfo = new PageInfo<>(list);
        long total = pageInfo.getTotal();
        System.out.println("共有商品:"+ total);
        
    }
}

四、整合测试

对应的jsp为:
item-list.jsp

请求的url:
/item/list
请求的参数:
page=1&rows=30
响应的json数据格式:
Easyui中datagrid控件要求的数据格式为:
{total:”2”,rows:[{“id”:”1”,”name”,”张三”},{“id”:”2”,”name”,”李四”}]}

1. 在taotao-common中创建EasyUIDataGridResult.java

package com.taotao.common.pojo;

import java.util.List;

/**
 * 查询商品列表的数据包装
 * 
 * Easyui中datagrid控件要求的数据格式为:
{total:”2”,rows:[{“id”:”1”,”name”,”张三”},{“id”:”2”,”name”,”李四”}]}

 */
public class EasyUIDataGridResult {

    private long total;//总的商品列表数量   满足Easyui中datagrid控件要求
    
    private List<?> rows;//每个列表的数据字段
    
    public EasyUIDataGridResult(long total, List<?> rows) {
        this.total = total;
        this.rows = rows;
    }
    
    public long getTotal() {
        return total;
    }
    public void setTotal(long total) {
        this.total = total;
    }
    public List<?> getRows() {
        return rows;
    }
    public void setRows(List<?> rows) {
        this.rows = rows;
    }
    
    
}

2. 在taotao-manager-mapper项目中新建TbItemMapper.java和TbItemMapper.xml

package com.taotao.mapper;

import com.taotao.pojo.TbItem;
import com.taotao.pojo.TbItemExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;

public interface TbItemMapper {
    int countByExample(TbItemExample example);

    int deleteByExample(TbItemExample example);

    int deleteByPrimaryKey(Long id);

    int insert(TbItem record);

    int insertSelective(TbItem record);

    List<TbItem> selectByExample(TbItemExample example);

    TbItem selectByPrimaryKey(Long id);

    int updateByExampleSelective(@Param("record") TbItem record, @Param("example") TbItemExample example);

    int updateByExample(@Param("record") TbItem record, @Param("example") TbItemExample example);

    int updateByPrimaryKeySelective(TbItem record);

    int updateByPrimaryKey(TbItem record);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.taotao.mapper.TbItemMapper" >
  <resultMap id="BaseResultMap" type="com.taotao.pojo.TbItem" >
    <id column="id" property="id" jdbcType="BIGINT" />
    <result column="title" property="title" jdbcType="VARCHAR" />
    <result column="sell_point" property="sellPoint" jdbcType="VARCHAR" />
    <result column="price" property="price" jdbcType="BIGINT" />
    <result column="num" property="num" jdbcType="INTEGER" />
    <result column="barcode" property="barcode" jdbcType="VARCHAR" />
    <result column="image" property="image" jdbcType="VARCHAR" />
    <result column="cid" property="cid" jdbcType="BIGINT" />
    <result column="status" property="status" jdbcType="TINYINT" />
    <result column="created" property="created" jdbcType="TIMESTAMP" />
    <result column="updated" property="updated" jdbcType="TIMESTAMP" />
  </resultMap>
  <sql id="Example_Where_Clause" >
    <where >
      <foreach collection="oredCriteria" item="criteria" separator="or" >
        <if test="criteria.valid" >
          <trim prefix="(" suffix=")" prefixOverrides="and" >
            <foreach collection="criteria.criteria" item="criterion" >
              <choose >
                <when test="criterion.noValue" >
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue" >
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue" >
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue" >
                  and ${criterion.condition}
                  <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
  <sql id="Update_By_Example_Where_Clause" >
    <where >
      <foreach collection="example.oredCriteria" item="criteria" separator="or" >
        <if test="criteria.valid" >
          <trim prefix="(" suffix=")" prefixOverrides="and" >
            <foreach collection="criteria.criteria" item="criterion" >
              <choose >
                <when test="criterion.noValue" >
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue" >
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue" >
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue" >
                  and ${criterion.condition}
                  <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
  <sql id="Base_Column_List" >
    id, title, sell_point, price, num, barcode, image, cid, status, created, updated
  </sql>
  <select id="selectByExample" resultMap="BaseResultMap" parameterType="com.taotao.pojo.TbItemExample" >
    select
    <if test="distinct" >
      distinct
    </if>
    <include refid="Base_Column_List" />
    from tb_item
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null" >
      order by ${orderByClause}
    </if>
  </select>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" >
    select 
    <include refid="Base_Column_List" />
    from tb_item
    where id = #{id,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long" >
    delete from tb_item
    where id = #{id,jdbcType=BIGINT}
  </delete>
  <delete id="deleteByExample" parameterType="com.taotao.pojo.TbItemExample" >
    delete from tb_item
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
  </delete>
  <insert id="insert" parameterType="com.taotao.pojo.TbItem" >
    insert into tb_item (id, title, sell_point, 
      price, num, barcode, 
      image, cid, status, 
      created, updated)
    values (#{id,jdbcType=BIGINT}, #{title,jdbcType=VARCHAR}, #{sellPoint,jdbcType=VARCHAR}, 
      #{price,jdbcType=BIGINT}, #{num,jdbcType=INTEGER}, #{barcode,jdbcType=VARCHAR}, 
      #{image,jdbcType=VARCHAR}, #{cid,jdbcType=BIGINT}, #{status,jdbcType=TINYINT}, 
      #{created,jdbcType=TIMESTAMP}, #{updated,jdbcType=TIMESTAMP})
  </insert>
  <insert id="insertSelective" parameterType="com.taotao.pojo.TbItem" >
    insert into tb_item
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        id,
      </if>
      <if test="title != null" >
        title,
      </if>
      <if test="sellPoint != null" >
        sell_point,
      </if>
      <if test="price != null" >
        price,
      </if>
      <if test="num != null" >
        num,
      </if>
      <if test="barcode != null" >
        barcode,
      </if>
      <if test="image != null" >
        image,
      </if>
      <if test="cid != null" >
        cid,
      </if>
      <if test="status != null" >
        status,
      </if>
      <if test="created != null" >
        created,
      </if>
      <if test="updated != null" >
        updated,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        #{id,jdbcType=BIGINT},
      </if>
      <if test="title != null" >
        #{title,jdbcType=VARCHAR},
      </if>
      <if test="sellPoint != null" >
        #{sellPoint,jdbcType=VARCHAR},
      </if>
      <if test="price != null" >
        #{price,jdbcType=BIGINT},
      </if>
      <if test="num != null" >
        #{num,jdbcType=INTEGER},
      </if>
      <if test="barcode != null" >
        #{barcode,jdbcType=VARCHAR},
      </if>
      <if test="image != null" >
        #{image,jdbcType=VARCHAR},
      </if>
      <if test="cid != null" >
        #{cid,jdbcType=BIGINT},
      </if>
      <if test="status != null" >
        #{status,jdbcType=TINYINT},
      </if>
      <if test="created != null" >
        #{created,jdbcType=TIMESTAMP},
      </if>
      <if test="updated != null" >
        #{updated,jdbcType=TIMESTAMP},
      </if>
    </trim>
  </insert>
  <select id="countByExample" parameterType="com.taotao.pojo.TbItemExample" resultType="java.lang.Integer" >
    select count(*) from tb_item
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
  </select>
  <update id="updateByExampleSelective" parameterType="map" >
    update tb_item
    <set >
      <if test="record.id != null" >
        id = #{record.id,jdbcType=BIGINT},
      </if>
      <if test="record.title != null" >
        title = #{record.title,jdbcType=VARCHAR},
      </if>
      <if test="record.sellPoint != null" >
        sell_point = #{record.sellPoint,jdbcType=VARCHAR},
      </if>
      <if test="record.price != null" >
        price = #{record.price,jdbcType=BIGINT},
      </if>
      <if test="record.num != null" >
        num = #{record.num,jdbcType=INTEGER},
      </if>
      <if test="record.barcode != null" >
        barcode = #{record.barcode,jdbcType=VARCHAR},
      </if>
      <if test="record.image != null" >
        image = #{record.image,jdbcType=VARCHAR},
      </if>
      <if test="record.cid != null" >
        cid = #{record.cid,jdbcType=BIGINT},
      </if>
      <if test="record.status != null" >
        status = #{record.status,jdbcType=TINYINT},
      </if>
      <if test="record.created != null" >
        created = #{record.created,jdbcType=TIMESTAMP},
      </if>
      <if test="record.updated != null" >
        updated = #{record.updated,jdbcType=TIMESTAMP},
      </if>
    </set>
    <if test="_parameter != null" >
      <include refid="Update_By_Example_Where_Clause" />
    </if>
  </update>
  <update id="updateByExample" parameterType="map" >
    update tb_item
    set id = #{record.id,jdbcType=BIGINT},
      title = #{record.title,jdbcType=VARCHAR},
      sell_point = #{record.sellPoint,jdbcType=VARCHAR},
      price = #{record.price,jdbcType=BIGINT},
      num = #{record.num,jdbcType=INTEGER},
      barcode = #{record.barcode,jdbcType=VARCHAR},
      image = #{record.image,jdbcType=VARCHAR},
      cid = #{record.cid,jdbcType=BIGINT},
      status = #{record.status,jdbcType=TINYINT},
      created = #{record.created,jdbcType=TIMESTAMP},
      updated = #{record.updated,jdbcType=TIMESTAMP}
    <if test="_parameter != null" >
      <include refid="Update_By_Example_Where_Clause" />
    </if>
  </update>
  <update id="updateByPrimaryKeySelective" parameterType="com.taotao.pojo.TbItem" >
    update tb_item
    <set >
      <if test="title != null" >
        title = #{title,jdbcType=VARCHAR},
      </if>
      <if test="sellPoint != null" >
        sell_point = #{sellPoint,jdbcType=VARCHAR},
      </if>
      <if test="price != null" >
        price = #{price,jdbcType=BIGINT},
      </if>
      <if test="num != null" >
        num = #{num,jdbcType=INTEGER},
      </if>
      <if test="barcode != null" >
        barcode = #{barcode,jdbcType=VARCHAR},
      </if>
      <if test="image != null" >
        image = #{image,jdbcType=VARCHAR},
      </if>
      <if test="cid != null" >
        cid = #{cid,jdbcType=BIGINT},
      </if>
      <if test="status != null" >
        status = #{status,jdbcType=TINYINT},
      </if>
      <if test="created != null" >
        created = #{created,jdbcType=TIMESTAMP},
      </if>
      <if test="updated != null" >
        updated = #{updated,jdbcType=TIMESTAMP},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.taotao.pojo.TbItem" >
    update tb_item
    set title = #{title,jdbcType=VARCHAR},
      sell_point = #{sellPoint,jdbcType=VARCHAR},
      price = #{price,jdbcType=BIGINT},
      num = #{num,jdbcType=INTEGER},
      barcode = #{barcode,jdbcType=VARCHAR},
      image = #{image,jdbcType=VARCHAR},
      cid = #{cid,jdbcType=BIGINT},
      status = #{status,jdbcType=TINYINT},
      created = #{created,jdbcType=TIMESTAMP},
      updated = #{updated,jdbcType=TIMESTAMP}
    where id = #{id,jdbcType=BIGINT}
  </update>
</mapper>

温馨提示:
该项目很多的mapper都是使用了mybatis的逆向工程生成的,但是在实际操作中,我们应该自己编写,不依赖于工具

3. 在taotao-manager-service中创建ItemService.java和ItemServiceImpl.java

package com.taotao.service;

import com.taotao.common.pojo.EasyUIDataGridResult;
import com.taotao.common.pojo.TaotaoResult;
import com.taotao.pojo.TbItem;
import com.taotao.pojo.TbItemDesc;

/**
 * 商品查询(查询单条记录、查询列表)、添加操作类
 * 
 * @author Administrator
 *
 */
public interface ItemService {

    /**
     * 根据商品id查询商品具体内容
     * 
     * @param itemId 商品ID
     * 
     * @return
     */
    TbItem getItemById(long itemId);
    
    /**
     * 查询商品列表
     * 
     * @param page  页数
     * 
     * @param rows  每页的数目
     * @return
     */
    EasyUIDataGridResult getItemList(int page, int rows);
    
    /**
     * 商品添加功能实现 
     * 
     * @param item  商品详细字段
     * 
     * @param itemDesc 商品描述
     * 
     * @param itemParams
     * @return
     */
    TaotaoResult addItem(TbItem item, TbItemDesc itemDesc, String itemParams);
}

package com.taotao.service.impl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.taotao.common.pojo.EasyUIDataGridResult;
import com.taotao.common.pojo.TaotaoResult;
import com.taotao.common.utils.ExceptionUtil;
import com.taotao.common.utils.IDUtils;
import com.taotao.mapper.TbItemDescMapper;
import com.taotao.mapper.TbItemMapper;
import com.taotao.mapper.TbItemParamItemMapper;
import com.taotao.pojo.TbItem;
import com.taotao.pojo.TbItemDesc;
import com.taotao.pojo.TbItemExample;
import com.taotao.pojo.TbItemExample.Criteria;
import com.taotao.pojo.TbItemParamItem;
import com.taotao.service.ItemService;

/**
 * 商品查询(查询单条记录、查询列表)、添加操作类
 * 
 * @author Administrator
 *
 */
@Service
public class ItemServiceImpl implements ItemService {

    @Autowired
    TbItemMapper itemMapper;//商品表操作
    
    @Autowired
    TbItemDescMapper itemDescMapper;//商品描述表  分开的目的是为了提高查询效率。
    
    @Autowired
    private TbItemParamItemMapper itemParamItemMapper;
    
    @Override
    public TbItem getItemById(long itemId) { 
        
        TbItem item = itemMapper.selectByPrimaryKey(itemId);
        
        return item;
    }
    
    /**
     * 查询商品列表
     * 
     * @param page  页数
     * 
     * @param rows  每页的数目
     * @return
     */
    @Override
    public EasyUIDataGridResult getItemList(int page, int rows) {
        
        //分页处理
        PageHelper.startPage(page, rows);
        //执行查询
        TbItemExample example = new TbItemExample();
        //添加条件
        //Criteria criteria = example.createCriteria();
        //criteria.andIdEqualTo(123l);
        List<TbItem> list = itemMapper.selectByExample(example);
        //取total
        PageInfo<TbItem> pageInfo = new PageInfo<TbItem>(list);
        long total = pageInfo.getTotal();
        
        //创建返回值对象
        EasyUIDataGridResult result = new EasyUIDataGridResult(total, list);
        
        return result;
    }

    /**
     * 添加商品
     */
    @Override
    public TaotaoResult addItem(TbItem item, TbItemDesc itemDesc, String itemParams) {
        try {
            
            //生成商品id
            //可以使用redis的自增长key,在没有redis之前使用时间+随机数策略生成
            Long itemId = IDUtils.genItemId();
            
            //补全不完整的字段
            item.setId(itemId);
            item.setStatus((byte) 1);
            Date date = new Date();
            item.setCreated(date);
            item.setUpdated(date);
            
            //把数据插入到商品表
            itemMapper.insert(item);
            
            //添加商品描述
            itemDesc.setItemId(itemId); 
            itemDesc.setCreated(date);
            itemDesc.setUpdated(date);
            
            //把数据插入到商品描述表
            itemDescMapper.insert(itemDesc);
            
            //把商品的规格参数插入到tb_item_param_item中
            TbItemParamItem itemParamItem = new TbItemParamItem();
            itemParamItem.setItemId(itemId);
            itemParamItem.setParamData(itemParams);
            itemParamItem.setCreated(date);
            itemParamItem.setUpdated(date);
            itemParamItemMapper.insert(itemParamItem);
            
        } catch (Exception e) {
            e.printStackTrace();
            return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));
        }
        
        return TaotaoResult.ok();
    }

}

4. 在taotao-manager-web中创建ItemController.java

@Controller
@RequestMapping("/item")
public class ItemController {
    
    @Autowired
    private ItemService itemService;

    @RequestMapping("/list")
    //设置相应的内容为json数据
    @ResponseBody
    public EasyUIResult getItemlist(@RequestParam(defaultValue="1")Integer page, 
            @RequestParam(defaultValue="30")Integer rows) throws Exception {
        //查询商品列表
        EasyUIResult result = itemService.getItemList(page, rows);
        
        return result;
    }
}

5. 运行项目

  在项目运行前,如果我们的taotao-parent和taotao-common项目代码有更新时,要重新install到本地仓库中,taotao-manager是聚合的父项目,且我们再taotao-manager-web中使用了maven内置的tomcat,所以我们运行聚合项目可以直接运行taotao-manager,maven会自动识别pom、jar、war类型项目,之后完成项目启动,如果使用的是本地tomcat,也可以直接将编译的taotao-manager-web.war包放入tomcat进行运行。

项目启动完成

在浏览器中输入localhost:8080,即可看到以下内容

6. 总结

  在淘淘商城中,前端网页使用的都是jsp,但是在实际的项目中,我们更多的是使用前后端分离方式,所以我们只要能将项目运行起来,然后将我们的重点放在后端技术实现上即可。

五、项目源码与资料下载

链接:https://pan.baidu.com/s/1VuRGe69_R4uqO-SRf2v-5w
提取码:pr3f

六、参考文章

http://yun.itheima.com/course?hm

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容