我是 Spring boot/JPA 的初学者,我试图用一种方法消除代码中的紧密耦合,显然唯一有效的解决方案是紧密耦合的代码,但这是一种不好的做法。 所以我有一个名为“用户”的实体和一个名为“位置”的实体。 TL DR User 有一系列包含对象的位置,基本上:
{id: "12f4", userId: "1", name: "haus", latitude: "12", longitude: "34"}
问题依赖于位置实体。我有这个位置实体:
@Entity
@Table(name = "locations")
public class Location {
@Id
@GeneratedValue
private UUID locationId;
private String locationName;
private String latitude;
private String longitude;
@Column(name = "user_id")
private UUID userId;
GETTERS AND SETTERS...
public UUID getUserId() {
return userId;
}
public void setUserId(UUID userId) {
this.userId = userId;
}
然后我就有了我的存储库 LocationRespository
public interface LocationRepository extends JpaRepository<Location, UUID>{
}
之后我就有了我的LocationService(接口)
public interface LocationService {
Location createLocation(Location location, UUID userId);
List<Location> getAllLocations();
... rest of the code
}
之后我有了我的 LocationServiceImpl (类)
@Service
public class LocationServiceImpl implements LocationService {
private final LocationRepository locationRepository;
@Autowired
public LocationServiceImpl(LocationRepository locationRepository, UserRepository userRepository) {
this.locationRepository = locationRepository;
}
@Override
public Location createLocation(Location location, UUID userId) {
HERE IS THE PROBLEM
location.setUserId(userId);
return this.locationRepository.save(location);
}
和我的控制器:
@RestController
@RequestMapping("/api/v1/locations")
public class LocationController {
private final LocationService locationService;
@Autowired
public LocationController(LocationService locationService) {
this.locationService = locationService;
}
@PostMapping("/create/{userId}")
public Location createLocation(@PathVariable("userId") UUID userId, @RequestBody Location location) {
return locationService.createLocation(location, userId);
}
如何从这里删除这个错误代码:(Service Impl)
location.setUserId(userId);
在我使用邮递员的情况下,我传递了 userId 的 uri,如下所示: http://localhost:5000/api/v1/locations/create/b7999c24-8d80-4560-aead-5d801e833e0b
我也有这样的身体: { "locationName": "达姆施塔特 zwei", “纬度”:“1321234”, “经度”:“4256363” }
唯一的问题是删除紧耦合代码,因为它直接从我的实体调用设置器到服务中。 我该如何解决这个问题?
首先,在移除setter之前,可以发现在API中直接使用Locationentity作为@RequestBody有一个问题。
另外,直接返回一个实体作为服务的返回类型也会导致同样的问题,如果存在双向关联,会出现递归,出现StackOverFlow。
//DTO(Data Transfer Object)
public record LocationCreateRequest(
String locationName,
String latitude,
String longitude
) {
}
public record LocationCreateRepsonse(
String id,
String locationName,
String latitude,
String longitude
) {
}
@RestController
@RequestMapping("/api/v1/locations")
public class LocationController {
private final LocationService locationService;
@Autowired
public LocationController(LocationService locationService) {
this.locationService = locationService;
}
@PostMapping("/create/{userId}")
public LocationCreateRepsonse createLocation(@PathVariable("userId") UUID userId, @RequestBody LocationCreateRequest request) {
return locationService.createLocation(request, userId);
}
}
现在让我们删除 setter。
@Service
public class LocationServiceImpl implements LocationService {
private final LocationRepository locationRepository;
@Autowired
public LocationServiceImpl(LocationRepository locationRepository, UserRepository userRepository) {
this.locationRepository = locationRepository;
}
@Override
public LocationCreateResponse createLocation(LocationCreateRequest request, UUID userId) {
Location location = new Location(request, userId); //or Location.from(request, userId); <- static factory method
this.locationRepository.save(location);
return new LocationCreateResponse(location); //or LocationCreateResponse.from(location);
}
}
@Entity
@Table(name = "locations")
@NoArgsConstructor
public class Location {
@Id
@GeneratedValue
private UUID locationId;
private String locationName;
private String latitude;
private String longitude;
@Column(name = "user_id")
private UUID userId;
public Location(LocationCreateRequest request, UUID userId) {
this.locationId = request.locationId();
this.locationName = request.locationName();
this.latitude = request.latitude();
this.longitude = request.longitude();
this.userId = userId;
}
}
希望对您有帮助:)