Spring Boot的项目层级结构
Controller层
业务控制层
它的作用就是架起来外界访问与业务层之间的桥梁,移动端或者前端在调用接口访问相关业务时候,都会通过Controller,由它去调用相关的业务代码,返回给前端跟移动端。
Controller的写法有两种,
-
Controller+RequestMapping
这里用来返网页数据
@Controller public class TestAlpha { @RequestMapping(value = "/sword",method = RequestMethod.GET) public String getSword(){ return "sword"; } }
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wvOlBc9W-1677116348197)(C:\Users\l30043039\AppData\Roaming\Typora\typora-user-images\image-20230222104733586.png)]
-
RestController+RequestMapping
这里用来返回对象,对象会被自动转换成一个JSON格式
@RestController public class TestBeta { @Autowired private StudentService studentService; @RequestMapping(value = "student",method = RequestMethod.GET) public List<Student> getStudentList(){ return studentService.getStudentList(); } }
Service层
业务层代码逻辑
用来处理具体的业务,比如用户的增删改查(CURD–Create,Update,Retrive,Delte)发送验证码或者邮件等等,业务层肯定是少不了数据的支持,所以Dao层就出现了
为了应对复杂的业务逻辑,也可以在service下加一个Impl包,在service中进行写一个接口,在Impl中通过@Service进行注解。这样就能在Impl中实现所有的业务逻辑,通过@Autowired对类进行自动装配(一般为Dao层的数据查询结果),这样就可以对JPA或者Mybatis等持久化层框架对数据库来进行操作,
Service层
package com.example.muyuchenzi.service;
import com.example.muyuchenzi.bean.entity.DivvyTrip;
import com.example.muyuchenzi.dao.DivvyTripDao;
import com.example.muyuchenzi.dao.model.DivvyTripPo;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import java.util.zip.DataFormatException;
public interface DivvyTripService {
List<DivvyTripPo> getAllDivvyTripList(String memberCasual,Integer number);
List<DivvyTrip> getNumberListAllDivvy(String rideType, Integer number) throws DataFormatException;
}
impl
package com.example.muyuchenzi.service.impl;
import com.example.muyuchenzi.bean.entity.DivvyTrip;
import com.example.muyuchenzi.dao.DivvyTripDao;
import com.example.muyuchenzi.dao.model.DivvyTripPo;
import com.example.muyuchenzi.service.DivvyTripService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.zip.DataFormatException;
@Service
public class DivvyTripServiceImpl implements DivvyTripService {
@Autowired
DivvyTripDao divvyTripDao;
public String dateExchange(String date) throws DataFormatException {
SimpleDateFormat simpleDateFormatAlpha = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat simpleDateFormatBeta = new SimpleDateFormat("yyyy-MM-dd");
try {
Date dateParsed = simpleDateFormatAlpha.parse(date);
String format = simpleDateFormatBeta.format(dateParsed);
return format;
} catch (ParseException e) {
throw new DataFormatException("Date Format Error");
}
}
public String getColorType() {
ArrayList<String> colorArrayList = new ArrayList<>(List.of("green", "blue", "red", "gray", "black", "white", "gray", "temp"));
Random random = new Random();
String choice = colorArrayList.get(random.nextInt(colorArrayList.size()));
return choice;
}
@Override
public List<DivvyTripPo> getAllDivvyTripList(String memberCasual, Integer number) {
List<DivvyTripPo> all = divvyTripDao.getListAllDivvy(memberCasual, number);
return all;
}
@Override
public List<DivvyTrip> getNumberListAllDivvy(String rideType, Integer number) throws DataFormatException {
List<DivvyTripPo> numberDivvyList = divvyTripDao.getNumListDivvy(rideType, number);
List<DivvyTrip> divvyTripsList = new ArrayList<>();
for (DivvyTripPo ele : numberDivvyList) {
DivvyTrip divvyTrip = new DivvyTrip();
divvyTrip.setId(ele.getRideId());
divvyTrip.setIdLength(ele.getRideId().length());
divvyTrip.setRideType(ele.getRideType());
divvyTrip.setStartDay(dateExchange(ele.getStartAt()));
divvyTrip.setEndDay(dateExchange(ele.getEndedAt()));
divvyTrip.setColorType(getColorType());
divvyTripsList.add(divvyTrip);
}
return divvyTripsList;
}
}
Dao层
数据持久化层,用来处理与数据库打交道,Dao层一般有两个框架:JPA和Mybatis两个。
- 项目复杂程度一般,追求稳定,迭代速率低的可以用JPA;
- 项目较复杂,需求变更频繁,迭代速度快的可以用MyBatis;
这两个持久化层的框架都是很方便,一般会在Dao层下写一个model包,这个包相对于entity下的类来说,entity下的数据是需要跟数据库表中中的字段进行一一对应的,到那时在model下的数据可以理解为给前端提供的数据模型,例如entity下的UserList类是对应db里user_list数据表,如果用JPA来操作的话,可以在entity下写一个@Table注解:
@Table(name = “google_playstore”, uniqueConstraints = {@UniqueConstraint(columnNames = {“index”})}, schema = “public”),model下的User可以对JPA返回的数据,进行操作,但是不会有@Table这样的注解,比如根据某一列或者两列进行计算衍生出来的数据,
Dao interface
public interface DivvyTripDao extends JpaRepository<DivvyTripPo, Integer>, JpaSpecificationExecutor<DivvyTripPo> {
@Query(
value = "select * from divvy_tripdata where member_casual=:memberCasual and index<:index", nativeQuery = true
)
List<DivvyTripPo> getListAllDivvy(@Param("memberCasual") String memberCasual, @Param("index") Integer index);
@Query(
value = "select * from divvy_tripdata where rideable_type=:rideType and index<:index", nativeQuery = true
)
List<DivvyTripPo> getNumListDivvy(@Param("rideType") String rideType, @Param("index") Integer index);
}
model 层
@Getter
@Setter
@Entity
@ToString
public class DivvyTripPo {
@Id
private Integer index;
@Column(name = "ride_id")
private String rideId;
@Column(name = "rideable_type")
private String rideType;
@Column(name = "started_at")
private String startAt;
@Column(name = "ended_at")
private String endedAt;
@Column(name = "member_casual")
private String memberCasual;
}
这三层一般不是严格区分的,其实也可以全部写到一个地方,但是为了后续的维护和项目的变动而言,把整体的结构分层分级,对项目的维护是非常有必要的。
Controller只是一个转发前端或者移动端请求的中间者或者转发者,不应该在Controller中暴露Service的业务逻辑,一般而言,一个Controller–>Service–>Dao–>一个数据库表,当然也可以使用一个Controller对应多个Service,一个Service对应多个Dao,但是Controller、Service、Dao层之间不应该互相调用,这样直接导致了层级的错乱。
备注:
为了应对一些很多列或者表,需要不断地在entity或者model层写一些实体类,所以这种重复性的工作可以使用JPA support这个插件来直接对大量的实体类进行使用lombok来操作,简便了很多重复性的工作,比较好用。如果有类似的JSON请求数据,也可以使用GsonFormatPlus插件对数据的列名进行提取,也是一个很方便的数据
![在这里插入图片描述](https://img-blog.csdnimg.cn/283c45488c324362b339c6dfeda7ab74.png