- SpringBoot
- 实体类
- `Media.java`
- 持久层
- `IMediaRepository.java`
- 服务
- `IService.java`
- `IQueryService.java`
- `baseService.java`
- 可以这样写
- 还可以这样写
- `MediaService.java`
- 控制器
- `IController.java`
- `baseController.java`
- `MediaController.java`
- 测试接口
输入java -version得到我的java version "16.0.1"。
cd到pom.xml文件所在位置即项目根目录并执行指令./mvnw dependency:list来查看引用版本:
- org.springframework.data:spring-data-jpa:2.5.2
- javax.validation:validation-api:2.0.1.Final
- com.alibaba:fastjson:1.2.78
- org.projectlombok:lombok:1.18.20
- org.springframework:spring-web:5.3.8
- org.springframework.boot:spring-boot:2.5.2
一个很普通的实体类,包名省略。
package com.example.demo.entity;
import com.alibaba.fastjson.annotation.JSONField;
import java.io.Serializable;
import lombok.*;
import javax.persistence.*;
@SuppressWarnings({"LombokEqualsAndHashCodeInspection"})
@EqualsAndHashCode
@ToString
@Getter
@Setter
@Entity
@Table(name = "media")
@AllArgsConstructor
@NoArgsConstructor
public class Media implements Serializable
{
@Id
@JSONField(ordinal = 1)
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", insertable = false, updatable = false)
private Integer id;
@JSONField(ordinal = 2)
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "book_id", updatable = false)
private Integer bookId;
@JSONField(ordinal = 3)
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "url", length = 128)
private String url;
}
持久层
IMediaRepository.java
一个啥也没有的接口。
package com.example.demo.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import com.example.demo.entity.Media; public interface IMediaRepository extends JpaRepository服务, JpaSpecificationExecutor { }
写一些接口。
IService.javapackage com.example.demo.service; import org.springframework.lang.Nullable; public interface IServiceIQueryService.java{ @Nullable T get(K primaryKey); @Nullable T addOrUpdate(T obj); boolean delete(K primaryKey); }
package com.example.demo.service; import java.util.*; public interface IQueryServicebaseService.java{ List find(int index, int size); long count(); List find(int index, int size, Map colAndPatterns); long count(Map colAndPatterns); }
抽象服务类。
可以这样写package com.example.demo.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.*; import com.example.demo.util.Common; import javax.persistence.criteria.*; import javax.validation.constraints.*; import java.util.*; public abstract class baseService还可以这样写& JpaSpecificationExecutor > implements IService , IQueryService { @Autowired protected R repo; // 让@Autowired自己找合适的类注入 ... @SuppressWarnings({"UnnecessarySemicolon", "OverlyBroadCatchBlock"}) @Override public final T addOrUpdate(@NotNull final T obj) { T ret = null; if (canAddOrUpdate(obj)) { try { ret = repo.saveAndFlush(obj); } catch (Exception e) { e.printStackTrace(); } } return ret; } protected abstract boolean canAddOrUpdate(final T obj); }
感觉这个比上面那种要好一点,减少一个泛型参数。
package com.example.demo.service; public abstract class baseServiceMediaService.javaimplements IService , IQueryService { @Autowired protected JpaRepository repo; @Autowired protected JpaSpecificationExecutor queryRepo; // 少一个泛型参数,多注入一次 ... @SuppressWarnings({"UnnecessarySemicolon", "OverlyBroadCatchBlock"}) @Override public final T addOrUpdate(@NotNull final T obj) { T ret = null; if (canAddOrUpdate(obj)) { try { ret = repo.saveAndFlush(obj); } catch (Exception e) { e.printStackTrace(); } finally { ; } } return ret; } protected abstract boolean canAddOrUpdate(final T obj); }
服务类指定了类参数,然后实现之前的baseService的抽象方法。
package com.example.demo.service; import org.springframework.stereotype.Service; import com.example.demo.entity.Media; import com.example.demo.repository.IMediaRepository; @Service(value = "mediaService") public class MediaService extends baseService{ }
或
```java package com.example.demo.service; import org.springframework.stereotype.Service; import com.example.demo.entity.Media; @Service(value = "mediaService") public class MediaService extends baseService控制器 IController.java{ ... }
接口
package com.example.demo.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; public interface IControllerbaseController.java{ @RequestMapping(method = RequestMethod.POST) String add(T body); @RequestMapping(method = RequestMethod.PUT) String update(T body); @RequestMapping(method = RequestMethod.DELETE) String delete(K id); @RequestMapping(value = "/list", method = RequestMethod.GET) String gets(Integer index, Integer size); @RequestMapping(method = RequestMethod.GET) String get(K id); }
package com.example.demo.controller; import com.alibaba.fastjson.JSON; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import com.example.demo.service.baseService; @RestController public abstract class baseControllerMediaController.javaimplements IController { @Autowired protected baseService service; @Override public String add(@RequestBody final T body) { return JSON.toJSONString(service.addOrUpdate(body)); } ... }
方法头顶上的注解也是可以继承的,但是参数注解重写方法就得重新再加一遍,忽略这一点造成的bug很低级。
package com.example.demo.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.entity.Media;
@RestController
@RequestMapping("/media")
public class MediaController extends baseController
{
}
测试接口
跑通。



