一:DAO实体编码

1:首先,在src目录下,新建org.myseckill.entity包,用于存放实体类:

2:实体类设计

根据前面创建的数据库表以及映射关系,创建实体类。

表一:秒杀商品表

对应实体类:

package org.myseckill.entity;

import java.util.Date;

public class Seckill {
private String SeckillId; private String name; private int number; private Date startTime; private Date endTime; private Date createTime; public String getSeckillId() {
return SeckillId;
} public void setSeckillId(String seckillId) {
SeckillId = seckillId;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getNumber() {
return number;
} public void setNumber(int number) {
this.number = number;
} public Date getStartTime() {
return startTime;
} public void setStartTime(Date startTime) {
this.startTime = startTime;
} public Date getEndTime() {
return endTime;
} public void setEndTime(Date endTime) {
this.endTime = endTime;
} public Date getCreateTime() {
return createTime;
} public void setCreateTime(Date createTime) {
this.createTime = createTime;
} @Override
public String toString() {
return "Seckill [SeckillId=" + SeckillId + ", name=" + name
+ ", number=" + number + ", startTime=" + startTime
+ ", endTime=" + endTime + ", createTime=" + createTime + "]";
} }

表二:秒杀成功记录表

对应实体类:

package org.myseckill.entity;

import java.util.Date;

public class SuccessKilled {
private long SeckillId; private long userPhone; private int state; private Date createTime; //映射关系:多对一
private Seckill seckill; public long getSeckillId() {
return SeckillId;
} public void setSeckillId(long seckillId) {
SeckillId = seckillId;
} public String getUserPhone() {
return userPhone;
} public void setUserPhone(String userPhone) {
this.userPhone = userPhone;
} public int getState() {
return state;
} public void setState(int state) {
this.state = state;
} public Date getCreateTime() {
return createTime;
} public void setCreateTime(Date createTime) {
this.createTime = createTime;
} public Seckill getSeckill() {
return seckill;
} public void setSeckill(Seckill seckill) {
this.seckill = seckill;
} @Override
public String toString() {
return "SuccessKilled [SeckillId=" + SeckillId + ", userPhone="
+ userPhone + ", state=" + state + ", createTime=" + createTime
+ ", seckill=" + seckill + "]";
} }

二:DAO类编码

1:在src.org.myseckill目录下,再新建一个包dao,用于存放dao接口。

2:编写操作seckill表的dao接口类:

package org.myseckill.dao;

import java.util.Date;
import java.util.List; import org.apache.ibatis.annotations.Param;
import org.myseckill.entity.Seckill; //操作秒杀商品表,主要是增删改查
public interface SeckillDao { //删:根据秒杀的商品ID减少对应ID的商品数量
//参数使用@Param为参数值赋予一个名字,对应xml中sql语句的{参数名}
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); }

3:编写操作successKilled表的dao接口类:

package org.myseckill.dao;

import org.apache.ibatis.annotations.Param;
import org.myseckill.entity.Seckill;
import org.myseckill.entity.SuccessKilled; public interface SuccessKilledDao { //增:增加一条秒杀成功的记录,传入秒杀的商品ID以及进行秒杀操作的手机号
int insertSuccessKilled(@Param("seckillId")long seckillId,@Param("userPhone")long userPhone);
//查:查找某用户对某商品的秒杀记录
SuccessKilled queryByIdWithSeckill(@Param("seckillId")long seckillId,@Param("userPhone")long userPhone); }

三:Mybatis映射文件编写

配置类文件一致放在src/main/resources目录下管理。

1:在resources目录下新建 mybatis-config.xml,Mybatis的全局配置文件,再创建一个文件夹mapper用于存放mybatis关于不同数据库表的操作映射文件

2:编写mybatis-config.xml

首先,到Mybatis官网上,复制配置文件的dtd头。网址:http://www.mybatis.org/mybatis-3/zh/getting-started.html

然后,配置数据源、mapper等。

<?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> <settings>
<!-- 使用jdbc的getGeneratedKeys 获取数据库自增主键值 -->
<setting name="useGeneratedKeys" value="true"/>
<!-- 使用列别名替换列名 默认:true -->
<setting name="useColumnLabel" value="true"/>
<!-- 开启驼峰命名转换 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>

3:在mapper目录下,为对应的dao接口编写同名的xml映射文件:

SeckillDao.xml:

<?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.myseckill.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" parameterType="long" resultType="Seckill">
select seckill_id, name, number, start_time, end_time, create_time
from seckill
where seckill_id = #{seckillId}
</select> <select id="queryAll" resultType="Seckill" parameterType="int">
select seckill_id, name, number, start_time, end_time, create_time
from seckill
order by create_time desc
limit #{offset},#{limit}
</select> </mapper>

SuccessKilledDao.xml

<?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.seckill.dao.SuccessKilledDao">
<insert id="insertSuccessKilled">
<!-- ignore:主键冲突时,返回0,不报错 -->
insert ignore into success_killed(seckill_id,user_phone,state)
values(#{seckillId},#{userPhone},0)
</insert>
<select id="queryByIdWithSeckill" resultType="SuccessKilled">
select
sk.seckill_id,
sk.user_phone,
sk.create_time,
sk.state,
s.seckill_id "seckill.seckill_id",//多对一关系:SuccessKilled实体中的seckill成员属性的属性值赋值
s.name "seckill.name",
s.number "seckill.number",
s.start_time "seckill.start_time",
s.end_time "seckill.end_time",
s.create_time "seckill.create_time"
from success_killed sk
inner join seckill s on sk.seckill_id = s.seckill_id
where sk.seckill_id=#{seckillId} and sk.user_phone=#{userPhone}
</select>
</mapper>

四:整合Spring与Mybatis

整合的目标:更少的编码(mabatis接口无需手动实现)、更少的配置(包扫描)、dao托管(spring自动注入dao实现类)、灵活性(自定制sql语句、自由传参、结果集自动转换)

1:在resources目录下新建一个文件夹spring,用于保存Spring相关的配置文件。

在spring下新建spring-dao.xml,用于整合mabatis。

在resources下新建一个jdbc.properties文件,配置数据库连接相关。

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

2:编写spring-dao.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 1:配置数据库参数文件所在 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties" />
</bean> <!-- 2:配置数据库连接池:使用c3p0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driver}" />
<property name="jdbcUrl" value="${url}" />
<property name="user" value="${username}" />
<property name="password" value="${password}" />
<!-- c3p0连接池的私有属性 -->
<property name="maxPoolSize" value="30" />
<property name="minPoolSize" value="10" />
<!-- 关闭连接后不自动commit -->
<property name="autoCommitOnClose" value="false" />
<!-- 获取连接超时时间 -->
<property name="checkoutTimeout" value="1000" />
<!-- 当获取连接失败重试次数 -->
<property name="acquireRetryAttempts" value="2" />
</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.myseckill.entity"/>
<!-- 扫描sql映射文件:mapper需要的xml文件 -->
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean> <!-- 4:配置扫描 Dao接口包,由factory动态实现Dao接口,注入到Spring容器中-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入sqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!-- 给出需要扫描的Dao接口 -->
<property name="basePackage" value="org.myseckill.dao"/>
</bean> </beans>

五:单元测试

在test/main/java下,新建包org.myseckill.dao,并创建SeckillDao的测试类:SeckillDaoTest。

package org.myseckill.dao;

import java.util.Date;
import java.util.List; import javax.annotation.security.RunAs; import org.junit.Test;
import org.junit.runner.RunWith;
import org.myseckill.entity.Seckill;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/spring-dao.xml")
public class SeckillDaoTest {
//要测试SeckillDao,则定义这样一个对象,并由spring自动注入
@Autowired
private SeckillDao seckillDao; @Test
public void testQueryById(){
long id = 1000;
Seckill seckill = seckillDao.queryById(id);
System.out.println(seckill);
} @Test
public void testQueryAll(){
//java没有保存形参的记录:queryAll(int offset,int limit) --> queryAll(arg0, arg1)
//所以需要:queryAll(@Param("offset")int offset, @Param("limit")int limit);
List<Seckill> list = seckillDao.queryAll(0,100);
for (Seckill seckill:list) {
System.out.println(seckill);
}
} @Test
public void testReduceNumber(){
int updateCount = seckillDao.reduceNumber(1000, new Date());
System.out.println(updateCount);
}
}

同理,创建SuccessKilledDaoTest

package org.myseckill.dao;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.myseckill.dao.SuccessKilledDao;
import org.myseckill.entity.SuccessKilled;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/spring-dao.xml")
public class SuccessKilledDaoTest {
@Autowired
SuccessKilledDao successKilledDao; @Test
public void testInsertSuccessKilled(){
int insertCount = successKilledDao.insertSuccessKilled(1001, 15764210366L);
System.out.println(insertCount);
} @Test
public void testQueryByIdWithSeckill(){
SuccessKilled successKilled = successKilledDao.queryByIdWithSeckill(1000, 15764210366L);
System.out.println(successKilled);
System.out.println(successKilled.getSeckill());
} }

测试记录一:ClassNotFound:com.mysql.Driver加载失败

原因排除:

首先检查是否没导入这个jar包,由于是用maven管理的,检查pom.xml已经导入了这个包,依赖库里也已经下载;

然后检查是否下载的包损坏或版本不对:手动下载mysql-connector-java-5.1.5.jar包,拷贝到目录下并添加到buildPath,测试通过。

结论:是pom.xml中导入的jar包版本不对,换成5.1.5的即可。

测试记录二:BindingException: Invalid bound statement (not found)

Mybatis接口绑定错误:

首先检查是否dao接口中的方法与xml中配置的id名字不一;

然后检查是否xml中mapper标签的namespace属性与dao接口路径不一致;

SSM实战——秒杀系统之DAO层实体定义、接口设计、mybatis映射文件编写、整合Spring与Mybatis的更多相关文章

  1. SSM实战——秒杀系统之Service层接口设计与实现、Spring托管、声明式事务

    一:Service层接口设计 准备工作:新建三个包:service包.exception包.dto包,分别用来存放业务接口.自定义异常类.dto类. 1:定义接口 package org.myseck ...

  2. SSM实战——秒杀系统之Web层Restful url设计、SpringMVC整合、页面设计

    一:Spring整合SpringMVC 1:编写web.xml,配置DispatcherServlet <web-app xmlns="http://java.sun.com/xml/ ...

  3. SSM实战——秒杀系统之创建项目、管理依赖、设计数据库

    注:本项目使用Myeclipse开发. 一:项目创建 1:使用Myeclipse创建一个web project,命名为MySeckill,并转换为Maven项目. 2:创建项目文件目录如下: 上面四个 ...

  4. SSM实战——秒杀系统前言

    项目来源:慕课网http://www.imooc.com/u/2145618/courses?sort=publish 项目开发流程:整合SSM框架——项目需求分析与实现——解决高并发优化 所用技术: ...

  5. SSM实战——秒杀系统之高并发优化

    一:高并发点 高并发出现在秒杀详情页,主要可能出现高并发问题的地方有:秒杀地址暴露.执行秒杀操作. 二:静态资源访问(页面)优化——CDN CDN,内容分发网络.我们把静态的资源(html/css/j ...

  6. [MyBatis]DAO层只写接口,不用写实现类

    团队开发一个项目,由老大架了一个框架,遇到了DAO层不用写接口了,我也是用了2次才记住这个事的,因为自己一直都是习惯于写DAO层的实现类,所以,习惯性的还是写了个实现类.于是遇到错误了. 找不到那个方 ...

  7. 5.7 Liquibase:与具体数据库独立的追踪、管理和应用数据库Scheme变化的工具。-mybatis-generator将数据库表反向生成对应的实体类及基于mybatis的mapper接口和xml映射文件(类似代码生成器)

    一. liquibase 使用说明 功能概述:通过xml文件规范化维护数据库表结构及初始化数据. 1.配置不同环境下的数据库信息 (1)创建不同环境的数据库. (2)在resource/liquiba ...

  8. 通过数据库中的表,使用 MyEclipse2017的反向生成工具-->hibernate反转引擎引擎(MyEclipse2017自带的插件) 来反转生成实体类和对应的映射文件

    通过数据库中的表,使用 MyEclipse2017的反向生成工具-->hibernate反转引擎引擎(MyEclipse2017自带的插件) 来反转生成实体类和对应的映射文件   文章目录 Ja ...

  9. SSM实现秒杀系统案例

    ---------------------------------------------------------------------------------------------[版权申明:本 ...

随机推荐

  1. dip和px的相互转化

    /** * 根据手机的分辨率从 dp 的单位 转成为 px(像素) */ public static int dip2px(Context context, float dpValue) { fina ...

  2. [Android Pro] AndroidStudio IDE界面插件开发(Hello World篇)

    转载请注明出处:[huachao1001的专栏:http://blog.csdn.net/huachao1001/article/details/53856916] 工欲善其事必先利其器,自打从Ecl ...

  3. confluence知识管理、团队协作软件

    Confluence搭建 参见 https://confluence.atlassian.com/display/CONF54/Installing+the+Confluence+EAR-WAR+Ed ...

  4. Tmux教程

    常用命令如下: (Ctrl+B) + (Shift+5) 打开一个新窗口 (Ctrl+B) + right/left 在不同窗口之间切换 (Ctrl+B) + [ 或 ] 进入复制模式,查看历史记录 ...

  5. git error: RPC failed; curl 56 GnuTLS recv error 解决方案

    // git 报错情况: error: RPC failed; curl 56 GnuTLS recv error (-110): The TLS connection was non-properl ...

  6. iOS:UICollectionView的扩展应用

    一.介绍 CollectionView是iOS中一个非常重要的控件,它可以实现很多的炫酷的效果,例如轮播图.瀑布流.相册浏览等.其实它和TableView很相似,都是对cell进行复用,提高系统性能. ...

  7. OpenCV教程(48) 特征值匹配

          OpenCV中通过下面的代码,可以匹配两幅的图像的特征值. // Read input images cv::Mat image1= cv::imread("../church0 ...

  8. 浅谈 Boost.Asio 的多线程模型

    Boost.Asio 有两种支持多线程的方式,第一种方式比较简单:在多线程的场景下,每个线程都持有一个io_service,并且每个线程都调用各自的io_service的run()方法. 另一种支持多 ...

  9. 通过js去掉所有的html标签,得到HTML标签中的所有内容

    <script> //替换掉所有的 html标签,得到Html标签中的内容 var s="<P><FONT face=宋体 color=#000000> ...

  10. Flask Restful服务简单实现

    官网:http://flask.pocoo.org/docs/1.0/quickstart/#routing 1.安装 windows下:pip3 install Flask 具体参照:windows ...