長期讀者,第一次發帖。
我需要幫助。我無法弄清楚 URL 引數 ? 資料庫。
情況: 我把 .../users/?role=admin&title=manager 放入郵遞員
預期: 所有作為經理和管理員的用戶的 json。
實際: 我的電腦炸了。
@RestController
@RequestMapping(path = USERS_PATH)
@Log4j2
public class UserController
// other code...
@GetMapping
public ResponseEntity<List<User>> getUserQuery(
@RequestParam( required = false, name = "name") String name,
@RequestParam( required = false, name = "title") String title,
@RequestParam( required = false, name = "roles") String roles,
@RequestParam( required = false, name = "email") String email,
@RequestParam( required = false, name = "password") String password
) {
log.info("Request received for getUserQuery");
return new ResponseEntity<>(userService.doSomething???(), HttpStatus.OK); // stuff I don't understand yet)
}
我的問題: 在控制器之后,什么進入 UserService 和 UserRepository?
額外資訊: 我正在使用 Spring Boot 和 H2,但稍后可能需要切換到 PostgreSQL DB。
我有下面的代碼作為在服務層上放置和發布期間檢查唯一電子郵件的代碼,但我無法得到類似的東西來解決這個問題。
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
@Query("SELECT u FROM User u WHERE u.email = ?1")
Optional<User> findUserByEmail(String email);
}
Rant: 這似乎是一件非常普遍的事情,我應該已經知道該怎么做了。我不。我已經在互聯網上閱讀了大約 5 個小時。仍然沒有答案。我學到了關于規范、Querydsl、@ModelAtribute、DAO 和映射 RequestParams 的東西。但是,我找不到如何連接這些點。所以,我去了一個完整的穴居人,并嘗試使用 StringBuilder 和一堆邏輯來制作一個 @Query 引數......我開始螺旋上升了。
無論如何,我想避免規范和 Querydsl。只需使用@Query 和 JPA,但更重要的是,我想要一個干凈的解決方案/最佳實踐。
uj5u.com熱心網友回復:
這是一個作業片段。我認為您的存盤庫有問題。您正在使用 @Query 以及對查詢的開箱即用支持。
服務和存盤庫中的內容:存盤庫層(repo)類用于抽象與資料庫的互動。
服務層與 repo 層互動并對存盤庫層回傳的資料進行按摩。
UserEntity
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
@Getter
@Setter
@Entity
@Table(name = "users")
@NoArgsConstructor
public class UserEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "designation")
private String designation;
@Column(name = "email")
private String email;
}
UserRepository
import com.example.code.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface UserRepository extends JpaRepository<UserEntity, Long> {
Optional<UserEntity> findByName(String name);
List<UserEntity> findByDesignation(String designation);
Optional<UserEntity> findByEmail(String email);
}
UserService
import java.util.Collection;
public interface UserService {
void createUser(UserDTO userDTO);
Collection<UserDTO> getUsers(
String username,
String designation,
String email
);
}
UserServiceImpl
import com.example.code.dto.UserDTO;
import com.example.code.entity.UserEntity;
import com.example.code.mapper.UserMapper;
import com.example.code.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.apache.catalina.User;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
@Override
public void createUser(UserDTO userDTO) {
UserEntity userEntity = new UserEntity();
userEntity.setName(userDTO.getName());
userEntity.setDesignation(userDTO.getDesignation());
userEntity.setEmail(userDTO.getEmail());
userRepository.save(userEntity);
}
@Override
public Collection<UserDTO> getUsers(String username, String designation, String email) {
Set<UserDTO> userDTOS = new HashSet<>();
if( !username.isBlank() && !username.isEmpty() && userRepository.findByName(username).isPresent() ) {
userDTOS.add(UserMapper.toDto(
userRepository.findByName(username).get()
));
}
if(!designation.isBlank() && !designation.isEmpty()) {
userDTOS.addAll(
userRepository.findByDesignation(designation)
.stream()
.map(UserMapper::toDto)
.collect(Collectors.toSet())
);
}
if( !email.isBlank() &&
!email.isEmpty() &&
userRepository.findByEmail(email).isPresent() ) {
userDTOS.add(UserMapper.toDto(
userRepository.findByEmail(email).get()
));
}
return userDTOS;
}
}
UserMapper
import com.example.code.dto.UserDTO;
import com.example.code.entity.UserEntity;
public class UserMapper {
public static UserDTO toDto(UserEntity entity) {
UserDTO userDTO = new UserDTO();
userDTO.setName(entity.getName());
userDTO.setDesignation(entity.getDesignation());
userDTO.setEmail(entity.getEmail());
return userDTO;
}
}
TestController
@RestController
@RequestMapping("/test")
@RequiredArgsConstructor
public class TestController {
private final UserService userService;
@PostMapping
public ResponseEntity<String> createUser(@RequestBody final UserDTO userDTO) {
try {
userService.createUser(userDTO);
}catch (Exception e) {
return ResponseEntity.internalServerError().body("Failure");
}
return ResponseEntity.ok("Success");
}
@GetMapping
public ResponseEntity<Collection<UserDTO>> getUsers(
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "designation", required = false) String designation,
@RequestParam(value = "email", required = false) String email
) {
return ResponseEntity.ok(userService.getUsers(name, designation, email));
}
}
uj5u.com熱心網友回復:
5.1.6 Query By Example,我們開始:
我們的 repo 中不需要任何東西,因為JpaRepository“它已經在船上了”!
我們的服務看起來像:
package com.example;
import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers.exact;
import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers.ignoreCase;
import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers.startsWith;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service;
@Service
public class PersonService {
@Autowired
JpaRepository<Person, Long> personRepository;
public List<Person> find(String name, String title, String roles, String email, String password) {
Person person = Person.of(name, title, roles, email, password);
ExampleMatcher matcher = ExampleMatcher
.matchingAny()
.withIgnoreNullValues()
.withMatcher("name", ignoreCase())
.withMatcher("title", startsWith().ignoreCase())
.withMatcher("roles", ignoreCase())
.withMatcher("email", ignoreCase())
.withMatcher("password", exact());
return personRepository.findAll(Example.of(person, matcher));
}
} // UN-TESTED, but compilable ;)
...但我們看到:僅使用這五個引數就可以進行多少“調整”。
用法:
...
Query by Example 非常適合以下幾個用例:
使用一組靜態或動態約束查詢您的資料存盤。
頻繁重構域物件而不必擔心破壞現有查詢。
獨立于底層資料存盤 API 作業。
Query by Example 也有幾個限制:
不支持嵌套或分組的屬性約束,例如
firstname = ?0 or (firstname = ?1 and lastname = ?2).僅支持字串的開始/包含/結束/正則運算式匹配以及其他屬性型別的精確匹配。
uj5u.com熱心網友回復:
我得到了這個作業,但我不知道這是否是最佳實踐。
控制器:
@GetMapping
public ResponseEntity<List<User>> getUserQuery(
@RequestParam( required = false, name = "name") String name,
@RequestParam( required = false, name = "title") String title,
@RequestParam( required = false, name = "roles") String roles,
@RequestParam( required = false, name = "email") String email,
@RequestParam( required = false, name = "password") String password
) {
log.info("Request received for getUserQuery");
return new ResponseEntity<>(userService.QueryUsers(name, title, roles, email, password), HttpStatus.OK); // stuff I don't understand yet)
}
服務:
public List<User> QueryUsers(String name, String title, String roles,String email,String password) {
if (name == null && title == null && roles == null && email == null && password == null) {
return userRepository.findAll(Sort.by(Direction.ASC, "id"));
}
//TODO: make to lower case
List<User> users = new ArrayList<>();
users.addAll(userRepository.findAllUsersByName(name));
users.addAll(userRepository.findAllUsersByTitle(title));
users.addAll(userRepository.findAllUsersByRoles(roles));
users.addAll(userRepository.findAllUsersByEmail(email));
users.addAll(userRepository.findAllUsersByPassword(password));
return users;
}
存盤庫:
@Query("SELECT u FROM User u WHERE u.name = ?1")
Collection<? extends User> findAllUsersByName(String name);
@Query("SELECT u FROM User u WHERE u.title = ?1")
Collection<? extends User> findAllUsersByTitle(String title);
@Query("SELECT u FROM User u WHERE u.roles = ?1")
Collection<? extends User> findAllUsersByRoles(String roles);
@Query("SELECT u FROM User u WHERE u.email = ?1")
Collection<? extends User> findAllUsersByEmail(String email);
@Query("SELECT u FROM User u WHERE u.password = ?1")
Collection<? extends User> findAllUsersByPassword(String password);
似乎有效,但我需要更多地測驗它。
uj5u.com熱心網友回復:
SQL AND,OR子句的組合應該可以滿足您的目的。下面給出了一個使用服務和存盤庫類的示例。
用戶服務
public List<User> doingSomething(String name, String title, String roles, String email,String password) {
return userRepository.detailQuery(name, title, roles, email, password);
}
用戶庫
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
@Query("SELECT u FROM User u WHERE (:name is null or u.name = :name) and (:title is null or u.title = :title) and (:roles is null or u.roles = :roles) and (:email is null or u.email = :email) and (:password is null or u.password = :password)")
List<User> detailQuery(@Param("name") String name,
@Param("title") String title,
@Param("roles") String roles,
@Param("email") String email,
@Param("password") String password);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/374049.html
