• SSM框架简介及整合教程


    1.Spring

    Spring 框架是 Java 应用最广的框架,它的成功来源于理念,而不是技术本身,它的理念包括 IoC (控制反转)A面向切面编程)。Spring框架是个轻量级的Java EE框架,所谓轻量级,是指不依赖于容器就能运行的。简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

    2.Spring MVC

    作用于web层,相当于controller,与struts中的action一样,都是用来处理用户请求的。同时,相比于struts2来说,更加细粒度,它是基于方法层面的,而struts是基于类层面的。Spring MVC 分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。

    Struts2 与 SpringMVC 的对比:

    3.MyBatis

    MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

    Hibernate 和 MyBatis 的对比:

    • Hibernate功能强大,数据库无关性好,O/R映射能力强,如果你对Hibernate相当精通,而且对Hibernate进行了适当的封装,那么你的项目整个持久层代码会相当简单,需要写的代码很少,开发速度很快,非常爽。
    • Hibernate的缺点就是学习门槛不低,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好Hibernate方面需要你的经验和能力都很强才行。
    • MyBatis入门简单,即学即用,提供了数据库查询的自动对象绑定功能,而且延续了很好的SQL使用经验,对于没有那么高的对象模型要求的项目来说,相当完美。
    • MyBatis的缺点就是框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。

    4.SSM框架整合

    本项目将以购物为背景,主要包括商品信息及库存【因为想顺便学习一下事务的处理】、订单信息。下面将从数据库创建、项目结构说明、配置文件、业务代码等方面进行一步步说明。

    4.1 数据库创建

    1. 商品表

    初始化表数据

    2. 订单表

    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE `orderinfo` (
    `order_id` varchar(20) NOT NULL COMMENT '订单编号',
    `goods_id` bigint(18) NOT NULL COMMENT '商品ID',
    `user_id` bigint(10) NOT NULL COMMENT '用户ID',
    `order_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '下单时间' ,
     PRIMARY KEY (`order_id`),
     INDEX `idx_order_id` (`order_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='订单表'

    OK,至此表结构及初始化数据构建完成,下面说下基于Mavan的项目结构。

    4.2 项目结构说明

    因为项目是使用maven来管理jar包的,先来贴一下,pom.xml的配置

    pom.xml

    为了避免学习小伙伴崇尚拿来主义【也就是去除了xmlns之类的东西】,这里只放项目依赖的jar包的dependencies;本案例将本着“需则用”的原则,避免在网上看到的各种乱七八糟的依赖都丢进来的情况,造成资源浪费和干扰阅读。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    <dependencies>
          <!-- 单元测试 -->
          <dependency>
              <groupId>junit</groupId>
              <artifactId>junit</artifactId>
              <version>4.11</version>
          </dependency>
      
          <!-- 1.日志 slf4j-->
          <dependency>
              <groupId>ch.qos.logback</groupId>
              <artifactId>logback-classic</artifactId>
              <version>1.1.1</version>
          </dependency>
      
          <!-- 2.数据库连接驱动 -->
          <dependency>
              <groupId>mysql</groupId>
              <artifactId>mysql-connector-java</artifactId>
              <version>5.1.37</version>
              <scope>runtime</scope>
          </dependency>
          <!-- 2.数据库连接池 -->
          <dependency>
              <groupId>c3p0</groupId>
              <artifactId>c3p0</artifactId>
              <version>0.9.1.2</version>
          </dependency>
      
          <!-- 3.MyBatis 以及 spring-mybatis -->
          <dependency>
              <groupId>org.mybatis</groupId>
              <artifactId>mybatis</artifactId>
              <version>3.3.0</version>
          </dependency>
          <dependency>
              <groupId>org.mybatis</groupId>
              <artifactId>mybatis-spring</artifactId>
              <version>1.2.3</version>
          </dependency>
      
          <!-- 4.Servlet 相关依赖 -->
          <dependency>
              <groupId>taglibs</groupId>
              <artifactId>standard</artifactId>
              <version>1.1.2</version>
          </dependency>
          <dependency>
              <groupId>jstl</groupId>
              <artifactId>jstl</artifactId>
              <version>1.2</version>
          </dependency>
          <dependency>
              <groupId>com.fasterxml.jackson.core</groupId>
              <artifactId>jackson-databind</artifactId>
              <version>2.5.4</version>
          </dependency>
          <dependency>
              <groupId>javax.servlet</groupId>
              <artifactId>javax.servlet-api</artifactId>
              <version>3.1.0</version>
          </dependency>
      
          <!-- 5.Spring -->
      
          <!-- 5.1 Spring核心 :core bean context -->
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-core</artifactId>
              <version>4.1.7.RELEASE</version>
          </dependency>
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-beans</artifactId>
              <version>4.1.7.RELEASE</version>
          </dependency>
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-context</artifactId>
              <version>4.1.7.RELEASE</version>
          </dependency>
          <!-- 5.2 Spring jdbc依赖,事务依赖 -->
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-jdbc</artifactId>
              <version>4.1.7.RELEASE</version>
          </dependency>
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-tx</artifactId>
              <version>4.1.7.RELEASE</version>
          </dependency>
          <!-- 5.3 Spring web依赖>
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-web</artifactId>
              <version>4.1.7.RELEASE</version>
          </dependency>
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-webmvc</artifactId>
              <version>4.1.7.RELEASE</version>
          </dependency>
          <!-- 5.4 Spring test -->
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-test</artifactId>
              <version>4.1.7.RELEASE</version>
          </dependency>
      
          <!-- 6.redis客户端:Jedis【不使用的话可以直接去除】 -->
          <dependency>
              <groupId>redis.clients</groupId>
              <artifactId>jedis</artifactId>
              <version>2.7.3</version>
          </dependency>
          <dependency>
              <groupId>com.dyuproject.protostuff</groupId>
              <artifactId>protostuff-core</artifactId>
              <version>1.0.8</version>
          </dependency>
          <dependency>
              <groupId>com.dyuproject.protostuff</groupId>
              <artifactId>protostuff-runtime</artifactId>
              <version>1.0.8</version>
          </dependency>
      
          <!-- 7.工具类 -->
          <dependency>
              <groupId>commons-collections</groupId>
              <artifactId>commons-collections</artifactId>
              <version>3.2</version>
          </dependency>
      </dependencies>

    *项目结构图

    src/test/java:用于junit的测试类 src/main/java:
    dao:数据库处理
    service:业务处理
    enums:项目枚举
    mapper:dao中方法对应mybatis映射文件,Sql就在这里面
    web:控制器,controller
    entity:项目中的实体类,如:商品类和订单类

    4.3 配置文件

    jdbc.properties

    logback.xml

    这里直接用的是控制台输出,如果是生产环境,可以根据具体的需求进行配置。

    mybatis-config

    这里主要是MyBaties全局配置文件的配置,可以将一些类的别名、主键自增配置、驼峰命名规则配置等。

    spring 相关配置文件

    为了更加清晰的了解spring各个组件的作用,这里将数据源的配置、事务配置和视图解析器的配置分开来。

    spring-dao.xml

    这里面主要就是spring配置整合mybatis的具体过程,具体包括:

    1. 引入数据库配置文件
    2. 配置数据源【数据库连接池】
    3. 配置SqlSessionFactory对象
    4. 配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    <!-- 1.配置数据库相关参数properties的属性:${url} -->
    <context:property-placeholder location="classpath:jdbc.properties" />
      
    <!-- 2.数据库连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
       <!-- 配置连接池属性 -->
       <property name="driverClass" value="${jdbc.driver}" />
       <property name="jdbcUrl" value="${jdbc.url}" />
       <property name="user" value="${jdbc.username}" />
       <property name="password" value="${jdbc.password}" />
      
       <!-- c3p0连接池的私有属性 -->
       <property name="maxPoolSize" value="30" />
       <property name="minPoolSize" value="10" />
       <!-- 关闭连接后不自动commit -->
       <property name="autoCommitOnClose" value="false" />
       <!-- 获取连接超时时间 -->
       <property name="checkoutTimeout" value="10000" />
       <!-- 当获取连接失败重试次数 -->
       <property name="acquireRetryAttempts" value="2" />
    </bean>
      
    <!-- 3.配置SqlSessionFactory对象 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
       <!-- 注入数据库连接池 -->
       <property name="dataSource" ref="dataSource" />
       <!-- 配置MyBaties全局配置文件:mybatis-config.xml -->
       <property name="configLocation" value="classpath:mybatis-config.xml" />
       <!-- 扫描entity包 使用别名 -->
       <property name="typeAliasesPackage" value="com.glmapper.framerwork.entity" />
       <!-- 扫描sql配置文件:mapper需要的xml文件 -->
       <property name="mapperLocations" value="com.glmapper.framerwork.mapper/*.xml" />
    </bean>
      
    <!-- 4.配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
       <!-- 注入sqlSessionFactory -->
       <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
       <!-- 给出需要扫描Dao接口包 -->
       <property name="basePackage" value="com.glmapper.framerwork.dao" />
    </bean>

    spring-service

    实际的开发过程中事务一般都是在service层进行操作。因此用一个单独的spring-service.xml来进行事务的相关的配置

    spring-web.xml

    配置SpringMVC;需要说明一下,一般我们在实际的开发过程中,会配置json2map解析。这里没有用到就不贴出来,读者可以自行网上搜索一波。

    web.xml

    <!-- 编码过滤器 -->
    <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <async-supported>true</async-supported>
    <init-param>
    <param-name>encoding</param-name>
    <param-value>UTF-8</param-value>
    </init-param>
    </filter>
    <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- Spring监听器 -->
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- 防止Spring内存溢出监听器 -->
    <listener>
    <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
    </listener>
    <!-- 配置DispatcherServlet -->
    <servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 配置springMVC需要加载的配置文件
    spring-dao.xml,spring-service.xml,spring-web.xml
    Mybatis - > spring -> springmvc
    -->
    <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring/spring-*.xml</param-value>
    </init-param>
    </servlet>
    <servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <!-- 默认匹配所有的请求 -->
    <url-pattern>/</url-pattern>
    </servlet-mapping>

    至此,所有的配置文件结束,下面将进行具体的代码环节

    4.4 业务代码

    这里mapper中的xml文件就不贴了,自行脑补。。。。

    实体类:包括商品和订单

    商品类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    /**
     * 商品信息类
     * @author glmapper
     *
     */
    public class Goods {
        private long goodsId;// 商品ID
        private String goodsName;// 商品名称
        private int number;// 商品库存
      
        public long getGoodsId() {
            return goodsId;
        }
        public void setGoodsId(long goodsId) {
            this.goodsId = goodsId;
        }
        public String getGoodsName() {
            return goodsName;
        }
        public void setGoodsName(String goodsName) {
            this.goodsName = goodsName;
        }
        public int getNumber() {
            return number;
        }
        public void setNumber(int number) {
            this.number = number;
        }
    }

    订单类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    /**
     * 订单信息类
     * @author glmapper
     *
     */
    public class OrderInfo {
        private String orderId;//订单ID
        private long goodsId;//商品ID
        private long userId;//用户ID
        private Date orderTime;//下单时间
        public String getOrderId() {
            return orderId;
        }
        public void setOrderId(String orderId) {
            this.orderId = orderId;
        }
        public long getGoodsId() {
            return goodsId;
        }
        public void setGoodsId(long goodsId) {
            this.goodsId = goodsId;
        }
        public long getUserId() {
            return userId;
        }
        public void setUserId(long userId) {
            this.userId = userId;
        }
        public Date getOrderTime() {
            return orderTime;
        }
        public void setOrderTime(Date orderTime) {
            this.orderTime = orderTime;
        }
    }
    • 商品dao
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    public interface GoodsDao {
      
        /**
         * 通过ID查询单件商品信息
         *
         * @param id
         * @return
         */
        Goods queryById(long id);
      
        /**
         * 查询所有商品信息
         *
         * @param offset 查询起始位置
         * @param limit 查询条数
         * @return
         */
        List<Goods> queryAll(@Param("offset") int offset, @Param("limit") int limit);
      
        /**
         * 减少商品库存
         *
         * @param bookId
         * @return 如果影响行数等于>1,表示更新的记录行数
         */
        int reduceNumber(long goodsId);
      
    }
    • 订单dao
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public interface OrderInfoDao {
      
      /**
       * 插入订单记录
       *
       * @param OrderInfo orderInfo
       * @return 插入的行数
       */
      int insertOrderInfo(OrderInfo orderInfo);
      
      /**
       * 通过主键查询订单记录,返回订单实体
       * @param orderId
       * @return
       */
      OrderInfo queryByOrderId(String orderId);
    }
    • 下单服务接口orderService
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    @Service("orderService")
    public class OrderServiceImpl implements OrderService {
      //log生成器
      private Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);
      
      // 注入dao依赖【商品dao,订单dao】
      @Autowired
      private GoodsDao goodsDao;
      @Autowired
      private OrderInfoDao orderInfoDao;
      
      @Override
      public Goods getById(long goodsId) {
          // TODO Auto-generated method stub
          return goodsDao.queryById(goodsId);
      }
      
      @Override
      public List<Goods> getList(int offset,int limit) {
          // TODO Auto-generated method stub
          return goodsDao.queryAll(offset, limit);
      }
      
      @Override
      @Transactional
      public OrderInfo buyGoods(long goodsId, long userId) {
          //扣减库存,插入订单 =一个事务  如果失败则执行回滚
          try {
              // 减库存
              int update = goodsDao.reduceNumber(goodsId);
              if (update <= 0) {// 库存不足
                  throw new NoNumberException("no number");
              } else {
                  // 执行预约操作
                  OrderInfo orderInfo=new OrderInfo();
                  orderInfo.setGoodsId(goodsId);
                  orderInfo.setUserId(userId);
                  orderInfo.setOrderTime(new Date());
                  String orderId=getRandomOrderId(goodsId);
                  orderInfo.setOrderId(orderId);
                  int insert = orderInfoDao.insertOrderInfo(orderInfo);
                  if (insert <= 0) {// 重复预约
                      throw new RepeatAppointException("repeat appoint");
                  } else {// 预约成功
                      return orderInfo;
                  }
              }
          } catch (Exception e) {
              //这里可以丰富下具体的返回信息
              logger.error("下单失败");
          }
          return null;
      }
      
      private String getRandomOrderId(long goodsId) {
          SimpleDateFormat dateFormater = new SimpleDateFormat("yyyyMMddhhmmss");
          String prefix=dateFormater.format(new Date());
          String goodsIdStr=goodsId+"";
          String temp="";
          for (int i = 0; i < 6; i++) {
              Random random=new Random(goodsIdStr.length()-1);
              temp+=goodsIdStr.charAt(random.nextInt());
          }
          return prefix+temp;
      }
    }

    OK,至此所有核心代码及配置文件罗列完毕;【mapper中的xml和具体的controller就不贴了,相信大家对这个也不陌生。本文主要意图在于梳理下自己学习中的一些点,SSM框架在实际的应用开发中还会有很多其他的开源技术结合进来,如:quartz,redis等。当前本文的列子就是一个空壳子,以备参考吧】

  • 相关阅读:
    排序
    git常用操作_分支合并_新建工程等
    ibatis 中调用存储过程
    IDEA试用期结束激活问题
    kafka本地工程的调用说明
    python yield 和 yield from用法总结
    ubuntu14.06 Lts开启ssh服务
    QT-1-环境搭建QT5.4.1&MinGW4.9.1
    虚拟机Ping不通主机解决
    CRC类(处理ITU表)
  • 原文地址:https://www.cnblogs.com/niudaxianren/p/9988024.html
Copyright © 2020-2023  润新知