概述
最近由於入職華海智匯,所以文章也少了,並不是自己懈怠了,而是華海的保密措施不允許我上班寫文章了,更何況還有無盡的加班。。。。。。。。。唉,所幸現在習慣了好多,現在覺著該記錄一下知識了。目前市場上,要實現Java專案主要有Maven和Gradle兩種框架,其中Gradle是新興勢力,Maven是老牌勢力,其實我更加喜歡用Gradle,因為更加便捷,無奈,現在市面上Maven仍然是主流,因為穩定,更因為許多老專案都是Maven搭建的。。。。。。今天這篇文章主要是介紹兩種實現springboot的方式,以防以後忘記
第一種:Domain(entity)-Mapper-Service-Controller
這種方式是我的老師教給我的方式,我也認為是最簡單的方式,也是我的最愛,不過卻是不常見的
例如:
實體類層:Domain(entity)
package com.example.pmxt.domain;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
@TableName("sys_region")
public class Region {
@NotNull(message = "id不能為空")
// @NotBlank(message = "id不能為空")
// @Length(min = 6,max = 6,message = "長度必須為6")
@ExcelProperty("編號")
private Integer id;
@NotNull(message = "名稱不能為空")
@NotBlank(message = "名稱不能為空")
@ExcelProperty("名稱")
private String name;
@NotNull(message = "父類id不能為空")
// @NotBlank(message = "父類id不能為空")
// @Length(min = 6,max = 6,message = "長度必須為6")
@ExcelProperty("父類id")
private Integer parentId;
@ExcelProperty("備註")
private String remark;
}
這一層在兩種方式中並無區別,就是建立實體類,方便管理。
Mapper層
這一層主要有兩種實現方式:註解和寫<這種標籤,註解比較多,因為簡便,標籤的話,應該是老程式設計師專屬吧,註解如下:
package com.example.pmxt.modules.region;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.pmxt.domain.Region;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface RegionMapper extends BaseMapper<Region> {
// @Select("SELECT sys_region.id,sys_region.name,sys_region.parent_id from sys_region,busi_bd.szd where sys_region.id = busi_bd.szd union SELECT sys_region.id,sys_region.name,sys_region.parent_id from sys_region,busi_bd where sys_region.id = concat(left(busi_bd.szd,4),'00') union SELECT sys_region.id,sys_region.name,sys_region.parent_id from sys_region,busi_bd where sys_region.id = concat(left(busi_bd.szd,2),'0000');")
// List<Region> selectbybd();
@Select("select * from sys_region where name = #{name}")
Region getByname(String name);
@Select("select parent_id from sys_region where name = #{name};")
Integer getparentIdByName(String name);
@Select("select id from sys_region where name = #{name};")
Integer getIdByName(String name);
@Select("select * from sys_region where concat(id) like concat(left(concat(#{id}),2),'%');")
List<Region> getByProvince(Integer id);
@Select("select * from sys_region where concat(id) like concat(left(concat(#{id}),4),'%');")
List<Region> getByCity(Integer id);
@Select("select * from sys_region where id = #{id}")
List<Region> getByCounty(Integer id);
}
注意BaseMapper來自於Mybatis-plus導包
主要就是註解+SQL語句後,下面跟個方法名
Service層
這塊是兩種方式差別最大的一個,這種方式只需要一個Service類就好了,但是需要一個工具類BaseService。
BaseService:
package com.example.pmxt.common;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
public class BaseService<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> {
}
所有的Service都可以繼承這個BaseService,這樣就不用寫ServiceImpl了,只需要解除安裝Service中就行了
Service:
package com.example.pmxt.modules.region;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.example.pmxt.common.BaseService;
import com.example.pmxt.domain.Region;
import lombok.SneakyThrows;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
@Service
@Transactional
public class RegionService extends BaseService<RegionMapper,Region> {
private final RegionMapper mapper;
@Autowired
public RegionService(RegionMapper mapper) {
this.mapper = mapper;
}
@SneakyThrows
public boolean importFileToDB(boolean deleteHistory, MultipartFile file) {
//是否刪除資料庫表中歷史資料
if (deleteHistory) {
this.remove(null);
}
//讀取excel表格中資料
EasyExcel.read(file.getInputStream(), Region.class, new ReadListener<Region>() {
//定義一個常量BATCH_SIZE與一個列表ls
private static final int BATCH_SIZE = 1000;
private List<Region> ls = Lists.newArrayList();
//重寫invoke方法
@Override
public void invoke(Region data, AnalysisContext context) {
//System.err.println(data);
//列表裡新增Flowfee類的資料
ls.add(data);
//每1000條放到資料庫裡面
if (ls.size() >= BATCH_SIZE) {
RegionService.this.saveBatch(ls);
ls.clear();
}
}
//重寫doAfterAllAnalysed方法,處理剩下的資料,例如1050條,其中1000條在上面已經放到資料庫,剩下的50條下面處理
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
RegionService.this.saveBatch(ls);
}
}).sheet().doRead();
return true;
}
public Integer getparentIdByName(String name){
return mapper.getparentIdByName(name);
}
public Integer getIdByName(String name){
return mapper.getIdByName(name);
}
public List<Region> gettable(String name){
if (mapper.getByname(name)==null){
return null;
}
Integer id = mapper.getIdByName(name);
if ("0000".equals(String.valueOf(id).substring(2))){
return mapper.getByProvince(id);
}else if ("00".equals(String.valueOf(id).substring(4))){
return mapper.getByCity(id);
}else {
return mapper.getByCounty(id);
}
}
}
Controller層
這一層是用於給前端寫介面的類,兩種方法基本一致
package com.example.pmxt.modules.region;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.example.pmxt.common.ReturnResult;
import com.example.pmxt.domain.Region;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@Validated
@RequestMapping("/regions")
public class RegionController {
private final RegionService service;
@Autowired
public RegionController(RegionService service) {
this.service = service;
}
@GetMapping()
public ReturnResult getAllRegion(){
//這裡用的MyBatis Plus
List<Region> dtos = service.list();
//配置
TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
// 自定義屬性名 都要預設值的
treeNodeConfig.setIdKey("id");
// 最大遞迴深度
treeNodeConfig.setDeep(4);
//轉換器
List<Tree<Integer>> treeNodes = TreeUtil.build(dtos, 0, treeNodeConfig,
(treeNode, tree) -> {
tree.setId(treeNode.getId());
tree.setParentId(treeNode.getParentId());
tree.setName(treeNode.getName());
});
return ReturnResult.buildSuccessResult(treeNodes);
}
@GetMapping("/name")
public ReturnResult getByName(@NotNull(message = "parentid不能為空") String name){
Integer parentid = service.getparentIdByName(name);
//這裡用的MyBatis Plus
List<Region> dtos = service.gettable(name);
if (dtos == null){
return ReturnResult.buildFailureResult("該地區不存在");
}
//配置
TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
// 自定義屬性名 都要預設值的
treeNodeConfig.setIdKey("id");
// 最大遞迴深度
treeNodeConfig.setDeep(3);
//轉換器
List<Tree<Integer>> treeNodes = TreeUtil.build(dtos, parentid, treeNodeConfig,
(treeNode, tree) -> {
tree.setId(treeNode.getId());
tree.setParentId(treeNode.getParentId());
tree.setName(treeNode.getName());
});
return ReturnResult.buildSuccessResult(treeNodes);
}
// @GetMapping("/selectbybd")
// public ReturnResult selectbybd(){
// return ReturnResult.buildSuccessResult(service.selectbybd());
// }
@PostMapping()
public ReturnResult addRegion(@RequestBody @Validated Region region){
if (region == null){
return ReturnResult.buildFailureResult("行政區劃不能為空");
}
return ReturnResult.buildSuccessResult(service.save(region));
}
@DeleteMapping("/{id}")
public ReturnResult deleteRegionById(@PathVariable @NotNull(message = "id不能為空") Integer id){
if(id == null){
return ReturnResult.buildFailureResult("id不能為空");
}
Region r = service.getById(id);
if (r != null){
return ReturnResult.buildSuccessResult(service.removeById(id));
}else {
return ReturnResult.buildFailureResult("id不存在");
}
}
@PutMapping()
public ReturnResult updateRegion(@RequestBody Region region){
if (region == null){
return ReturnResult.buildFailureResult("行政區劃不能為空");
}
Region r = service.getById(region.getId());
if (r != null) {
return ReturnResult.buildSuccessResult(service.updateById(region));
}else {
return ReturnResult.buildFailureResult("id不存在");
}
}
//@PostMapping定義IP地址對映方法與位置,@ApiOperation是swagger測試註解
@PostMapping("/uploadregion")
public ReturnResult excelToDatabase( @RequestParam boolean deleteHistory,
@RequestPart("file") MultipartFile file) {
if(service.importFileToDB(deleteHistory, file)){
return ReturnResult.buildSuccessResult("新增成功",null);
}else {
return ReturnResult.buildFailureResult("新增失敗",null);
}
}
@DeleteMapping("deletes")
public ReturnResult deleteregions(Integer [] ids){
if (ids.length == 0){
return ReturnResult.buildFailureResult("行政區劃不能為空");
}else {
return ReturnResult.buildSuccessResult(service.removeBatchByIds(Arrays.asList(ids)));
}
}
}
第二種:Domain(entity)-Mapper-Service-ServiceImpl-Controller
這種方法主要就差在Service層,其餘層可以參考上面
Service層
Service:
public interface UserSerivce extends IService<User> {
}
這種方法Service要先繼承IService工具類,實際上ServiceImpl已將包含了IService中的所有方法
ServiceImpl:
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserSerivce {
}
這就需要多寫一個Impl類,實際上兩者原理一樣,第二種多了個ServiceImpl<UserMapper, User> 實現 UserSerivce介面,而UserSerivce介面又要繼承IService
最後說明這兩種方法應該在Maven和Gradle框架中都可以使用,至少Maven是都可以的,因為我試過了,,Gradle中我用過第一種,第二種還沒用過,不過既然原理一致,應該都可以使用;
這篇文章只當自己對喜愛方法的紀念吧。。。。