发表于: 2017-08-01 22:31:24
2 1124
今天做的事:
SSM框架的代码已经码完了,然后现在过程,逻辑实现等等也都理解了,遇到的不认识,不熟悉的知识点也都了解的差不多了,接下来就是使用jetty启动服务,然后先用postman测试一下后端接口,最后把前端页面写出来,然后将这一整套过程移植到任务一的代码逻辑上,最后将效果都展示出来,任务二就可以提交了,初步估计大概还需要个三四天,也可能提前或延后。
话不多说,先把今天学的知识罗列一下
首先service层的代码如下
这里的业务逻辑是顺接上一篇日报的
首先创建一个枚举类,用来限定范围
AppointStateEnum.java
package com.ts.enums;
/**
* Created by Administrator on 2017/07/31.
*/
public enum AppointStateEnum {
SUCCESS(1,"预约成功"),NO_NUMBER(0,"库存不足"),REPEAT_APPOINT(-1,"重复预约"),INNER_ERROR(-2,"系统异常");
private int state;
private String stateInfo;
private AppointStateEnum(int state,String stateInfo){
this.state = state;
this.stateInfo = stateInfo;
}
public int getState(){
return state;
}
public String getStateInfo(){
return stateInfo;
}
public static AppointStateEnum stateOf(int index){
for(AppointStateEnum state : values()) {
if(state.getState() == index) {
return state;
}
}
return null;
}
}
这里将枚举的概念讲一下:
枚举
枚举就像一个限制集,当我们需要对一个值取一个特定范围时就需要使用枚举了,如果超出定义范围,就会报错(或者我们定义一个方法,不让超出范围)
枚举的values()方法;
可以将所定义的枚举类转换成一个枚举类型的数组,通过for循环遍历可以实现获取枚举的所有想得到的数据
for(enum enum_name : values()){
//method code
}
接下来我们设置一个构造器,用来区分成功和失败
AppointExecution.java
package com.ts.dto;
import com.ts.entities.Appointment;
import com.ts.enums.AppointStateEnum;
/**
* Created by Administrator on 2017/07/31.
*/
public class AppointExecution {
private long bookId;
private int state;
private String stateInfo;
private Appointment appointment;
public AppointExecution(){
}
//预约失败构造器
public AppointExecution(long bookId, AppointStateEnum stateEnum){
this.bookId = bookId;
this.state = stateEnum.getState();
this.stateInfo = stateEnum.getStateInfo();
}
//预约成功构造器
public AppointExecution(long bookId,AppointStateEnum stateEnum,Appointment appointment){
this.bookId = bookId;
this.state = stateEnum.getState();
this.stateInfo = stateEnum.getStateInfo();
this.appointment = appointment;
}
public long getBookId() {
return bookId;
}
public void setBookId(long bookId) {
this.bookId = bookId;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public String getStateInfo() {
return stateInfo;
}
public void setStateInfo(String stateInfo) {
this.stateInfo = stateInfo;
}
public Appointment getAppointment() {
return appointment;
}
public void setAppointment(Appointment appointment) {
this.appointment = appointment;
}
@Override
public String toString() {
return "AppointExecution{" +
"bookId=" + bookId +
", state=" + state +
", stateInfo='" + stateInfo + '\'' +
", appointment=" + appointment +
'}';
}
}
接下来定义泛型
Result.java
package com.ts.dto;
/**
* Created by Administrator on 2017/08/01.
*/
//封装json对象,所有返回结果都使用它
public class Result<T> {
private boolean success;
private T data;
private String error;
public Result(){
}
//成功时构造器
public Result(boolean success,T data){
this.success = success;
this.data =data;
}
//错误时构造器
public Result(boolean success,String error){
this.success = success;
this.error = error;
}
public boolean getSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
}
介绍一下泛型
泛型
定义格式:public class Result<T>{}
其中T代表任意类型,这个泛型指的就是,我们可以自定义T的类型,比如String,Integer等等,在新建对象时,只需要声明T为什么类型即可。当然也包括我们自定义的类。
然后是service层的接口及实现类
BookService.java
package com.ts.service;
import com.ts.dto.AppointExecution;
import com.ts.entities.Book;
import java.util.List;
/**
* Created by Administrator on 2017/07/31.
*/
public interface BookService {
//查询一本书
// @param bookId
// @return
Book getById(long bookId);
//查询所有图书
// @return
List<Book> getList();
//预约图书
// @param bookId
// @param studentId
// @return
AppointExecution appoint(long bookId,long studentId);
}
BookServiceImpl.java
package com.ts.service;
import com.ts.dao.AppointmentDao;
import com.ts.dao.BookDao;
import com.ts.dto.AppointExecution;
import com.ts.entities.Appointment;
import com.ts.entities.Book;
import com.ts.enums.AppointStateEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* Created by Administrator on 2017/07/31.
*/
@Service
public class BookServiceImpl implements BookService{
@Autowired
private BookDao bookDao;
@Autowired
private AppointmentDao appointmentDao;
@Override
public Book getById(long bookId){
return bookDao.queryById(bookId);
}
@Override
public List<Book> getList(){
return bookDao.queryAll(0,1000);
}
@Override
@Transactional
/**
* 使用注解控制事务方法的优点: 1.开发团队达成一致约定,明确标注事务方法的编程风格
* 2.保证事务方法的执行时间尽可能短,不要穿插其他网络操作,RPC/HTTP请求或者剥离到事务方法外部
* 3.不是所有的方法都需要事务,如只有一条修改操作,只读操作不需要事务控制
*/
public AppointExecution appoint(long bookId,long studentId){
try{
//减库存
int update = bookDao.reduceNumber(bookId);
if(update<=0){
//库存不足
return new AppointExecution(bookId, AppointStateEnum.NO_NUMBER);
} else{
//执行预约操作
int insert = appointmentDao.insertAppointment(bookId,studentId);
if(insert<=0){
//重复预约
return new AppointExecution(bookId,AppointStateEnum.REPEAT_APPOINT);
}else{
//预约成功
Appointment appointment = appointmentDao.queryByKeyWithBook(bookId,studentId);
return new AppointExecution(bookId,AppointStateEnum.SUCCESS,appointment);
}
}
}catch(Exception e){
return new AppointExecution(bookId,AppointStateEnum.INNER_ERROR);
}
}
}
这里使用了事务,但是并没有使用事务回滚功能,现在暂时没接触到,不过是个很重要的功能,以后会深入学习
然后是service层的配置文件
spring-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: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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 扫描service包下所有使用注解的类型 -->
<context:component-scan base-package="com.ts.service"/>
<!-- 配置事务管理器 -->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置基于注解的声明式事务 -->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
<import resource="spring-dao.xml"/>
</beans>
可以看到这里使用了配置事务的相关标签
最后是service测试类
import com.ts.dto.AppointExecution;
import com.ts.service.BookService;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Created by Administrator on 2017/07/31.
*/
public class BookServiceImplTest extends BaseTest {
@Autowired
private BookService bookService;
@Test
public void testAppoint() throws Exception{
long bookId = 1001;
long studentId = 123456789L;
AppointExecution execution = bookService.appoint(bookId,studentId);
System.out.println(execution);
}
}
这个测试类有一个逻辑上的bug
就是每次执行事务,即使重复预约也会出现扣除图书数量的操作,没有实现事务回滚,造成数据丢失,但是鉴于能力有限,时间有限,就暂时没有解决这个逻辑bug
最后,到这里已经实现了三层架构的BLL以及DAL两层了,就差UI层了,不过前端页面还没写,后端接口也还没测,就先不贴controller的代码了。
然后贴一下今天了解的其他知识点
标签<context:component-scan base-package=""/>
组件自动扫描机制,会在包路径下寻找标注注解的类,并把这些类纳入Spring容器中管理。这样就极大简化了xml文件中对于bean定义的配置,压缩文件大小。
几个注解
@RequestMapping
用来处理请求地址映射的注解,用于类或方法上;
有如下六个属性:
1.value:指定请求实际地址,url
2.method:指定请求方法,GET,PUT,POST,DELETE等
3.consumes:指定处理请求的提交内容类型,如application/json, text/html
4.produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
5.params:指定request中必须包含某些参数值时,才让该方法处理
6.headers:指定request中必须包含某些特定的header值,才能让该方法处理请求
@PathVariable 处理request uri部分的注解
如@RequestMapping("/{booId}")中的booId就需要使用@PathVariable绑定传过来的值到方法参数上
@ModelAttribute用于方法上时
通常用来处理@RequestMapping之前,为请求绑定一个需要从后台查询的model
这里顺便提一下model.addAttribute(“sss”,sss)——渲染
这个方法就是向前台视图传递参数
@Responsebody表示该方法的返回结果直接写入HTTP response body中
一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上@Responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。比如异步获取json数据,加上@Responsebody后,会直接返回json数据。
mybatis使用@Param注解时,在配置文件中可以使用${}的格式,如果没有该注解,必须使用#{}
这些都在controller的代码块中,之后的日报会贴出来
明天计划:测完后端接口,开始写前端页面,用jetty启动服务。
问题:暂无
收获:一些知识点,以及看了一点业务逻辑。
评论