Service层Spring开发

Service层Spring开发

新建service包和exception包和dto包
exception包用来存放自定义异常
dto用来存放定义的结果集数据类型

service包接口

CourseService.java

package me.debugjoker.service;

import me.debugjoker.dto.CourseExecution;
import me.debugjoker.dto.Exposer;
import me.debugjoker.entity.Course;
import me.debugjoker.exception.ChooseCloseException;
import me.debugjoker.exception.ChooseException;
import me.debugjoker.exception.RepeatChooseException;

import java.util.List;

public interface CourseService {

/**
* 查询所有的课程 * @return
*/
  List<Course> getCourseList();

/**
* 查询一个课程记录 * @param courseId
* @return
*/
  Course queryCourseById(long courseId);

/**
* 选课开始时暴露选课地址,未开始时输出系统时间和秒杀时间
* @param courseId
*/
  Exposer exportCourseUrl(long courseId);

/**
* 开始执行选课操作 
*/  
    CourseExecution executeCourseChoose(long courseId, long studentId, String md5)throws ChooseException,ChooseCloseException,RepeatChooseException;

}

dto包下的数据类

Exposer.java

package me.debugjoker.dto;

/**
 * 暴露选课地址DTO
 */
public class Exposer {

    /*是否开启选课*/
    private boolean isExposed;
    /* 加密措施*/
    private String md5;
    /*课程id*/
    private long courseId;
    /*系统当前时间*/
    private long now;
    /*选课开始时间*/
    private long start;
    /*选课结束时间*/
    private long end;

    public Exposer(boolean isExposed, String md5, long courseId) {
        this.isExposed = isExposed;
        this.md5 = md5;
        this.courseId = courseId;
    }

    public Exposer(boolean isExposed, long now, long start, long end) {
        this.isExposed = isExposed;
        this.now = now;
        this.start = start;
        this.end = end;
    }

    public Exposer(boolean isExposed, long courseId) {
        this.isExposed = isExposed;
        this.courseId = courseId;
    }

    public boolean isExposed() {
        return isExposed;
    }

    public void setExposed(boolean exposed) {
        isExposed = exposed;
    }

    public String getMd5() {
        return md5;
    }

    public void setMd5(String md5) {
        this.md5 = md5;
    }

    public long getCourseId() {
        return courseId;
    }

    public void setCourseId(long courseId) {
        this.courseId = courseId;
    }

    public long getNow() {
        return now;
    }

    public void setNow(long now) {
        this.now = now;
    }

    public long getStart() {
        return start;
    }

    public void setStart(long start) {
        this.start = start;
    }

    public long getEnd() {
        return end;
    }

    public void setEnd(long end) {
        this.end = end;
    }
}

CourseExecution.java

package me.debugjoker.dto;

import me.debugjoker.entity.SuccessChoose;

/**
 * 选课之后结果对象封装
 */
public class CourseExecution {

    private long seckillId;
    //选课结果状态
    private int state;
    //状态表示
    private String stateInfo;
    //选课成功对象
    private SuccessChoose successChoose;

    public long getSeckillId() {
        return seckillId;
    }

    public void setSeckillId(long seckillId) {
        this.seckillId = seckillId;
    }

    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 SuccessChoose getSuccessChoose() {
        return successChoose;
    }

    public void setSuccessChoose(SuccessChoose successChoose) {
        this.successChoose = successChoose;
    }

    public CourseExecution(long seckillId, int state, String stateInfo, SuccessChoose successChoose) {
        this.seckillId = seckillId;
        this.state = state;
        this.stateInfo = stateInfo;
        this.successChoose = successChoose;
    }

    public CourseExecution(long seckillId, int state, String stateInfo) {
        this.seckillId = seckillId;
        this.state = state;
        this.stateInfo = stateInfo;
    }
}

自定义异常类exception包下

package me.debugjoker.exception;

/**
 * 选课相关异常
 */
public class ChooseException extends RuntimeException {

    public ChooseException(String message) {
        super(message);
    }

    public ChooseException(String message, Throwable cause) {
        super(message, cause);
    }
}
package me.debugjoker.exception;

/**
 * 选课关闭异常
 */
public class ChooseCloseException extends ChooseException {

    public ChooseCloseException(String message) {
        super(message);
    }

    public ChooseCloseException(String message, Throwable cause) {
        super(message, cause);
    }
}
package me.debugjoker.exception;

/**
 * 重复选课异常
 */
public class RepeatChooseException extends ChooseException{

    public RepeatChooseException(String message) {
        super(message);
    }

    public RepeatChooseException(String message, Throwable cause) {
        super(message, cause);
    }
}

Service实现

service下新建impl包
CourseServiceImpl.java

package me.debugjoker.service.impl;

import me.debugjoker.dao.CourseDao;
import me.debugjoker.dao.SuccessChooseDao;
import me.debugjoker.dto.CourseExecution;
import me.debugjoker.dto.Exposer;
import me.debugjoker.entity.Course;
import me.debugjoker.entity.SuccessChoose;
import me.debugjoker.enums.CourseStateEnum;
import me.debugjoker.exception.ChooseCloseException;
import me.debugjoker.exception.ChooseException;
import me.debugjoker.exception.RepeatChooseException;
import me.debugjoker.service.CourseService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.util.Date;
import java.util.List;

@Service public class CourseServiceImpl implements CourseService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
  private CourseDao courseDao;

    @Autowired
  private SuccessChooseDao successChooseDao;

    //MD5加密混淆值
  private final String slat = "skcAsw;sjc,q01;'`l0QWcjeJ.";

    public List<Course> getCourseList() {
        return courseDao.queryAll(0, 100);
    }

    public Course queryCourseById(long courseId) {
        return courseDao.queryById(courseId);
    }

    public Exposer exportCourseUrl(long courseId) {
        Course course = courseDao.queryById(courseId);
        if (course == null) {
            //没有查到这门课
  return new Exposer(false, courseId);
        }
        Date startTime = course.getStartTime();
        Date endTime = course.getEndTime();
        Date nowTime = new Date();
        //判断选课是否开始
  if (nowTime.getTime() < startTime.getTime() || nowTime.getTime() > endTime.getTime()) {
            //选课未开始或者选课已经结束 不暴露选课URL地址
  return new Exposer(false, courseId, nowTime.getTime(), startTime.getTime(), endTime.getTime());
        }
        String md5 = getMD5(courseId);
        return new Exposer(true, md5, courseId);
    }

    //注解开启事务
  @Transactional
  public CourseExecution executeCourseChoose(long courseId, long studentId, String md5) throws ChooseException, ChooseCloseException, RepeatChooseException {
        if (md5 == null || !md5.equals(getMD5(courseId))) {
            throw new ChooseException("MD5数据被篡改");
        }
        //执行选课逻辑
  Date nowTime = new Date();
        try {
            int updateCount = courseDao.reduceNumber(courseId, nowTime);
            if (updateCount <= 0) {
                //选课失败
  throw new ChooseCloseException("选课已结束");
            } else {
                int insertCount = successChooseDao.insertSuccessChoose(courseId, studentId);
                if (insertCount <= 0) {
                    throw new RepeatChooseException("重复选课");
                } else {
                    SuccessChoose successChoose = successChooseDao.queryByIdwithCourse(courseId, studentId);
                    return new CourseExecution(courseId, CourseStateEnum.SUCCESS, successChoose);
                }
            }
        } catch (ChooseCloseException e) {
            throw e;
        } catch (RepeatChooseException e) {
            throw e;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new ChooseException("内部逻辑异常" + e.getMessage());
        }
    }

    //根据课程id生成MD5字符串串
  private String getMD5(long seckillId) {
        String base = seckillId + "/" + slat;
        String md5 = DigestUtils.md5DigestAsHex(base.getBytes());
        return md5;
    }
}

新建enums包创建数据字典枚举类

package me.debugjoker.enums;

/**
 * 数据字典枚举
 */
public enum CourseStateEnum {
    SUCCESS (1,"选课成功"),
    END(0,"选课已结束"),
    REPEAT_CHOOSE(-1,"重复选课"),
    INNER_ERROR(-2,"系统异常"),
    DATA_REWRITE(-3,"数据篡改");

    private int state;

    private String stateInfo;

    CourseStateEnum(int state, String stateInfo) {
        this.state = state;
        this.stateInfo = stateInfo;
    }

    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 static CourseStateEnum stateEnum(int index){
        for (CourseStateEnum stateEnum : values()){
            if (stateEnum.getState() == index){
                return stateEnum;
            }
        }
        return null;
    }
}

Spring整合service

resources/spring下新建spring-service.xml
使用@Service和@Autowired 配置声明式事务@Transactional

<?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" xmlns:tx="http://www.springframework.org/schema/tx"
       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="me.debugjoker.service"/>

    <!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据库连接池-->
        <property name="dataSource" ref="dataSource"/>

    </bean>

    <!--配置基于注解的声明式事务 默认使用注解来管理事务行为-->
    <tx:annotation-driven transaction-manager="transactionManager"/>


</beans>

配置logback.xml

<?xml version="1.0" encoding="UTF-8" ?>
<configuration debug="true">

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoders are  by default assigned the type
             ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

猜你喜欢

转载自blog.csdn.net/debugjoker/article/details/81461886