SSM整合1

Posted by Forezp on May 11, 2016

最近实在太忙,之前写的《rxjava系列文章》告一段落,还有两篇会在一月中旬补上,感谢大家。这篇文章讲述mybatis搭建DAO层,另外这系列文章是我看完《java高并发秒杀系列》的课程整理的,所以文章采用的例子也来源于这系列课程。

一.环境/工具

1.开发工具idea

2.数据库mysql

3.javaweb容器 tomcat

4.构建项目工具maven

关于这几个工具下载安装,环境的搭建就不介绍,自行百度。

二.采用maven 构建项目

采用命令构架,当然也可以采用ide 直接构建。

构建命令:

mvn archetype:generate -DgroupId=org.forezp -DartifactId=minnkill -DarchetypeArtifactId=maven-archetype-webapp

低版本maven需要将generate 改为create.

三.补全SSM框架相关依赖

下面是SSM框架所需的所有框架

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
135
136
137
138
139
140
141
142
143
<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.seckill</groupId>
  <artifactId>seckill</artifactId>
  <packaging>war</packaging>
  <version>1.0.0</version>
  <name>seckill Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <!--使用junit4,4以上使用注解-->
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
    <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!--补全项目依赖-->
    <!--1:日志,java日志:slf4j,log4j,logback,common-logging
     使用:slf4j+logBack
    -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.5.6</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <version>1.1.1</version>
    </dependency>
    <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.35</version>
    <scope>runtime</scope>
  </dependency>
    <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.1.2</version>
    </dependency>
    <dependency>
      <groupId>commons-dbcp</groupId>
      <artifactId>commons-dbcp</artifactId>
      <version>1.4</version>
    </dependency>
    <!--DAO框架:MyBatis依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.3.0</version>
    </dependency>
    <!--myBatis自身实现的spring整合依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.2.3</version>
    </dependency>
    <!--3:Servlet web相关依赖-->
    <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>

    <!--4:spring依赖-->
    <!--spring核心依赖-->
    <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>
    <!--spring dao层依赖-->
    <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>
    <!--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>
    <!--spring test相关依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>

    <!--引入一些工具类-->
    <dependency>
      <groupId>commons-collections</groupId>
      <artifactId>commons-collections</artifactId>
      <version>3.2</version>
    </dependency>


  </dependencies>
  <build>
    <finalName>seckill</finalName>
  </build>
</project>

四.建数据库

仿java高并发秒杀系列》的视频,建了两张表,一张上库存表,一张上秒杀表,我直接贴sql语句了,比较简单。

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
--创建数据库
CREATE DATABASE seckill;
--使用数据库
use seckill;

--库存表
CREATE TABLE seckill(
`seckill_id` bigint NOT NULL AUTO_INCREMENT COMMENT '商品库存id',
`name` VARCHAR(120) NOT NULL COMMENT '商品名称',
`number` int  NOT NULL COMMENT '库存数量',
`start_time` timestamp NOT NULL  DEFAULT "2016-05-07 13:28:00",
`end_time` timestamp NOT NULL  DEFAULT "2016-05-07 13:28:00",
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP  COMMENT '创建时间',
 PRIMARY KEY (seckill_id),
 key idx_start_time(start_time),
key idx_end_time(end_time),
 key idx_create_time(create_time)
)EnGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8 COMMENT='秒杀库存表';

---初始化数据
insert into seckill(name,number,start_time,end_time)
VALUES
 ('1000元秒杀iphone6',100,'2015-11-01 00:00:00','2015-11-02 00:00:00'),
 ('500元秒杀ipad2',200,'2015-11-01 00:00:00','2015-11-02 00:00:00'),
 ('300元秒杀小米4',300,'2015-11-01 00:00:00','2015-11-02 00:00:00'),
 ('200元秒杀红米note',400,'2015-11-01 00:00:00','2015-11-02 00:00:00');

 --秒杀成功明细表
 --用户登录认证相关的信息
 create table success_killed(
 `seckill_id` bigint NOT NULL COMMENT '秒杀商品id',
 `user_phone` bigint NOT NULL COMMENT '用户手机号',
`state` tinyint NOT NULL DEFAULT 0 COMMENT '状态标示:-1:无效 0:成功 1:已付款',
`create_time` TIMESTAMP NOT NULL COMMENT '创建时间',
PRIMARY  KEY (seckill_id,user_phone),/*联合主键*/
KEY idx_create_time(create_time)
 )EnGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='秒杀明细表';

五.DAO层实体编写和接口编写

1.创建org.forezp.entity包,根据数据库字段,编写实体。 下面是Seckill库存实体:

1
2
3
4
5
6
7
8
9
10
public class Seckill {
    private long seckillId;
    private String name;
    private int number;
    private Date startTime;
    private Date endTime;
    private Date createTime;
    //这里省去了写getter setter方法,在实际项目补上	
}
  1. 创建org.forezp.dao包 编写Seckill接口
1
2
3
4
5
6
7
8
public interface SeckillDao {
    //减库存
    int reduceNumber(@Param("seckillId")long seckillId,@Param("killTime")Date killTime);
    //根据Id查询秒杀对象
    Seckill queryById(long seckillId);
    //根据偏移量查询秒杀列表
    List<Seckill> queryAll(@Param("offset")int offset,@Param("limit")int limit);
   

采用mapper实现接口

在resources目录下创建maaper文件夹,所有的接口实现类放在这里 ,另外项目采用xml的方式实现接口。采用这种方式的好处有很多,比如可以采用包扫描,更少的配置,所有的sql语句都放在这里,有利于统一规范,代码的可维护性和可读性也大大提高。

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
<?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="org.forezp.dao.SeckillDao">

	<update id="reduceNumber">
		update
		seckill
		set
		number = number-1
		where seckill_id = #{seckillId}
		and
		start_time <![CDATA[ <= ]]>
		#{killTime}
		and end_time >= #{killTime}
		and number > 0;
	</update>
	
	 <select id="queryById" resultType="Seckill" parameterType="long">
        select seckill_id,name,number,start_time,end_time,create_time from seckill
        where seckill_id = #{seckillId}
    </select>
    
   
   <select id="queryAll" resultType="Seckill">
        select seckill_id,name,number,start_time,end_time,create_time
        from seckill
        order by create_time desc
        limit #{offset},#{limit}
    </select>
    
   
</mapper>

###六. mybatis的配置

创建mybatis-config.xml 全局配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?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">
  

 <!-- 配置全局属性 -->	
 
<settings>
        <!--使用jdbc的getGeneratedKeys 获取数据库的自增主键值-->
        <setting name="useGeneratedKeys" value="true"/>
        <!--使用别名替换列名 默认true
        select name as title from table
        -->
        <setting name="useColumnLabel" value="true"/>
        <!--开启驼峰命名转换-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>

    </settings>

</configuration>

创建jdbc.properties文件 数据库配置文件和连接数据库驱动。

1
2
3
4
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/seckill?useUnicode=true&characterEncoding=utf8
username=root
password=123

七.mybatis和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
42
43
44
<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
>

    <!--配置整合mybatis过程-->

    <!--1.配置数据库相关参数-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

      <!--2.配置连接池属性-->   
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">

        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/seckill"/>
        <property name="username" value="root"/>
        <property name="password" value="123"/>
       
    </bean>


    <!--3.配置SqlSessionFactory对象-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--注入数据库连接池-->
        <property name="dataSource" ref="dataSource"/>
        <!--配置mybatis全局配置文件:mybatis-config.xml-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--扫描entity包,使用别名,多个用;隔开-->
        <property name="typeAliasesPackage" value="org.forezp.entity"/>
        <!--扫描sql配置文件:mapper需要的xml文件-->
        <property name="mapperLocations" value="classpath: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="org.forezp.dao"/>
    </bean>
</beans>

就这样mybatis和spring就整合好了,spring 提供了的ioc容器,为我们管理bean,我们不需要管理bean的生命周期.

###八.单元测试

采用junit单元测试,spring 对junit做了很好的支持。只需要配置注解久可以了,

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
/**
 * 配置spring和junit整合,junit启动时加载springIOC容器
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:spring/spring-dao.xml"})
public class SeckillDaoTest {


    @Test
    public void reduceNumber() throws Exception {
        Date killTIme=new Date();
        int updateCount =seckillDao.reduceNumber(1000L,killTIme);
        System.out.println(updateCount);
		//结果第一次执行为1 后面为0 

    }
    //注入Dao实现类依赖
    @Resource
    private SeckillDao seckillDao;
    @Test
    public void queryById() throws Exception {
        long id=1001;
        Seckill seckill=seckillDao.queryById(id);
        System.out.println(seckill.getName());
        System.out.println(seckill);
        //运行结果
        /** 500元秒杀ipad2*/
      /**  Seckill{seckillId=1001, name='500元秒杀ipad2',number=200, startTime=Sun Nov 01 00:00:00 CST 2015, endTime=Mon Nov 02 00:00:00 CST 2015, createTime=Sun Nov 27 10:44:30 CST 2016}*/
    }

    @Test
    public void queryAll() throws Exception {
        //java没有保存形参的记录,queryAll(int offeset,int limit)->queryAll(arg0,arg1),通过@param注解来解决

        List<Seckill> seckills=seckillDao.queryAll(0,100);
        for(Seckill seckill:seckills){
            System.out.println(seckill);
        }
    }

}

到此为止,mybatis实现数据库的连接,和dao层代码的编写以及mybatis 和spring的整合 。我觉得学习路上虽然很孤单,但如果有一个分享的心态和持续学习的动力,生活也算是充实的,自己成长了,技术也提高了,回报也高了,生活品质也随之提高。所以无论做什么,自己快乐,并且能提高自己的快乐,且以此为目的就够了,祝自己好运。

源码下载

优秀文章推荐:

  • [史上最简单的 SpringCloud 教程 终章](http://blog.csdn.net/forezp/article/details/70148833)
  • [史上最简单的 SpringCloud 教程 第一篇: 服务的注册与发现(Eureka)](http://blog.csdn.net/forezp/article/details/69696915)
  • [史上最简单的SpringCloud教程 第七篇: 高可用的分布式配置中心(Spring Cloud Config)](http://blog.csdn.net/forezp/article/details/70037513)

拍摄于深圳大沙河公园


欢迎关注我的公众号

扫码关注公众号有惊喜

(转载本站文章请注明作者和出处 方志朋的博客

本文为[原创]文章,转载请标明出处。
本文链接:https://www.fangzhipeng.com/j2ee/2016/05/11/ssm3/
本文出自方志朋的博客
阿里云1023 腾讯云1023