举例:购买商品 trans_sale 项目
本例要实现购买商品,模拟用户下订单,向订单表添加销售记录,从商品表减少库存。
Step0:创建数据库表( Sequl Ppro演示 )
创建两个数据库表 sale,goods
-
sale 销售表,建表:
CREATE TABLE `sale` ( `id` int NOT NULL AUTO_INCREMENT, `gid` int NOT NULL, `nums` int DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-
goods 商品表,建表
CREATE TABLE `goods` ( `id` int NOT NULL, `name` varchar(100) DEFAULT NULL, `amount` int DEFAULT NULL, `price` float DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
Step1:maven 依赖 pom.xml
<dependencies>
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!---spring核心ioc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!---spring的事务-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!--spring访问数据库-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<!--mybatis和spring集成依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.5</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<!--阿里公司的数据库连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.23</version>
</dependency>
</dependencies>
<!--插件-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
Step2:创建实体类 Sale 与 Goods
public class Sale {
private Integer id;
private Integer gid;
private Integer nums;
// Getter & Stter
public class Goods {
private Integer id;
private String name;
private Integer amount;
private Float price;
// Getter * Setter
Step3:定义 dao 接口(SaleDao,GoodsDao)
public interface SaleDao {
//增加销售记录
int insertSale(Sale sale);
}
public interface GoodsDao {
//更新库存
//goods表示本次用户购买的商品信息
int updateGoods(Goods goods);
//查询商品的信息
Goods selectGoods(Integer id);
}
Step4:定义 dao 接口对应的 sql 映射文件
- SaleDao.xml
<mapper namespace="com.Arbin.dao.SaleDao"> <insert id="insertSale"> insert into sale(gid,nums) values(#{gid},#{nums}) </insert> </mapper>
- GoodsDao.xml
<mapper namespace="com.Arbin.dao.GoodsDao"> <select id="selectGoods" resultType="com.Arbin.domain.Goods"> select id,name,amount,price from goods where id=#{gid} </select> <update id="updateGoods"> update goods set amount = amount - #{amount} where id=#{id} </update> </mapper>
Step5:定义异常类
定义 service 层可能抛出的异常类NotEnoughException
//自定义的运行时异常
public class NotEnoughException extends RuntimeException {
public NotEnoughException() {
super();
}
public NotEnoughException(String message) {
super(message);
}
}
Step6:定义 Service 接口
public interface BuyGoodsService {
//购买商品的方法,goodsId:购买商品的编号,nums:购买商品的数量
public void buy(Integer goodsId,Integer amount);
}
Step7:定义 Service 的实现类
1. 类定义
public class BuyGoodsServiceImpl implements BuyGoodsService {
2.Dao属性
private SaleDao saleDao;
private GoodsDao goodsDao;
public void setSaleDao(SaleDao saleDao) {
this.saleDao = saleDao;
}
public void setGoodsDao(GoodsDao goodsDao) {
this.goodsDao = goodsDao;
}
3.Buy方法
public void buy(Integer goodsId, Integer nums) throws NotEnoughException {
//记录销售信息,向销售表添加记录
Sale sale = new Sale();
sale.setGid(goodsId);
sale.setNums(nums);
saleDao.insertSale(sale);
//更新库存
Goods goods = goodsDao.selectGoods(goodsId);
if( goods == null){
//商品不存在
throw new NullPointerException("编号:"+goodsId+",商品不存在");
}else if (goods.getAmount() < nums){
throw new NotEnoughException("编号:"+goodsId+",商品库存不足");
}
//修改库存
Goods buyGoods = new Goods();
buyGoods.setId(goodsId);
buyGoods.setAmount(nums);
goodsDao.updateGoods(buyGoods);
}
Step8:定义 MyBatis 主配置文件(mybatis.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>
<!--设置别名-->
<typeAliases>
<!--name:实体类所在的包名-->
<package name="com.Arbin.domain"/>
</typeAliases>
<!--sql mapper(sql映射文件)的位置-->
<mappers>
<package name="com.Arbin.dao"/>
</mappers>
</configuration>
Step9:修改 Spring 配置文件内容(applicationContext.xml)
- 声明MyBatis对象
<!--将数据库的配置信息写在独立的文件,编译修改数据库的配置内容--> <context:property-placeholder location="jdbc.properties"/> <!--声明数据源DataSource,使用Druid数据库连接池--> <bean id="muDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="clone"> <!--set注入给DruidDataSource提供连接数据库信息--> <!--数据库的url--> <property name="url" value="${jdbc.url}" /> <!--setUrl()--> <!--数据库的用户名--> <property name="username" value="${jdbc.username}"/> <!--数据库访问密码--> <property name="password" value="${jdbc.passowrd}"/> <!--数据库最大连接数--> <property name="maxActive" value="${jdbc.max}"/> </bean> <!--声明SqlSessionFactoryBean类,创建SqlSessionFactory对象--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="muDataSource"/> <property name="configLocation" value="classpath:mybatis.xml"/> </bean> <!--声明MyBatis的扫描器对象,创建Dao接口de实现类对象,即Dao对象--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <property name="basePackage" value="com.Arbin.dao"/> </bean>
- 声明业务层对象
<!--声明service--> <bean id="buySerbice" class="com.Arbin.service.impl.BuyGoodsServiceImpl"> <property name="goodsDao" ref="goodsDao"/> <property name="saleDao" ref="saleDao"/> </bean>
Step10:定义测试类
public class MyTest {
@Test
public void test01(){
String config = "applicationContext.xml";
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(config);
//从容器获取service
BuyGoodsService service = (BuyGoodsService) ctx.getBean("buyService");
//调用方法
service.buy(1001,10);
}
}