java - 使用 Java Spring JPA 和 crud 更新数据库记录
问题描述
尝试通过创建一个用于存储足球队的简单项目来学习 Java Spring。我正在使用 JPA 将数据存储到数据库中。目前,我可以使用我的登录用户将“团队”保存到我的数据库中。现在我希望更新团队更改或用户犯错等情况的记录。
有人可以帮助我并提供最佳方法吗?
1个团队模型类
@Data
@Entity
@Table(name="User_Team")
public class Team implements Serializable {
@OneToOne
private User user;
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
@NotBlank(message="Team Name is required")
private String teamName;
@NotBlank(message="Location is required")
private String location;
@NotBlank(message="Nickname required")
private String nickName;
private String yearEstablished;
public Sport sport;
private Divison divison;
}
2. 团队仓库
@Repository
public interface TeamRepository extends CrudRepository<Team, Long> {
Team findAllById(Long id);
}
3. 团队控制器
@Slf4j
@Controller
@RequestMapping("/team")
@SessionAttributes("Team")
public class TeamController {
private TeamRepository teamRepository;
public TeamController(TeamRepository teamRepository) {
this.teamRepository = teamRepository;
}
@Autowired
TeamRepository service;
@PostMapping
public String processOrder(@Valid Team team, Errors errors,
SessionStatus sessionStatus,
@AuthenticationPrincipal User user) {
if (errors.hasErrors()) {
return "team";
}
team.setUser(user);
service.save(team);
sessionStatus.setComplete();
return "redirect:/team";
}
@GetMapping
public String displayTeam(Model model) {
model.addAttribute("team", service.findAll());
return "/team";
}
}
4. 团队 HTML
<!DOCTYPE html>
<!--suppress ALL -->
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Team</title>
<link rel="stylesheet" th:href="@{/styles.css}" />
</head>
<body>
<div class="hero-image">
<div class="hero-text">
<h1 style="font-size:50px">Team</h1>
</div>
</div>
<div class="tab">
<button class="tablinks"><a href="team">Team Info</a></button>
<button class="tablinks"><a href="player">Players Info</a></button>
<button class="tablinks"><a href="fixtures">Fixtures</a></button>
</div>
<div id="Home" class="tabcontent">
<h3>Home</h3>
</div>
<div id="About" class="tabcontent">
<h3>Team Info</h3>
</div>
<div id="Contact" class="tabcontent">
<h3>Player Info</h3>
</div>
<table>
<tr>
<th>Team name</th>
<th>Location</th>
<th>Nickname</th>
<th>Year Formed</th>
<th>Sport</th>
<th>Division</th>
</tr>
<tr th:each = "about: ${team}">
<td th:text="${about.teamName}"></td>
<td th:text="${about.location}"></td>
<td th:text="${about.nickName}"></td>
<td th:text="${about.yearEstablished}"></td>
<td th:text="${about.sport}"></td>
<td th:text="${about.divison.displayValue}"></td>
</tr>
<!--<input type="file" name="pic" accept="image/*">
<input type="submit">-->
</table>
<button class="open-button" onclick="openForm()">Add your team</button>
<div class="form-popup" id="myForm">
<form method="POST" th:action="@{/team}" class="form-container" id="aboutForm">
<label for="teamName">Team name: </label>
<input type="text" name="teamName"/><br/>
<label for="location">Location: </label>
<input type="text" name="location"/><br/>
<label for="nickName">Nickname: </label>
<input type="text" name="nickName"/><br/>
<label for="yearEstablished">Year Formed: </label>
<input type="text" name="yearEstablished"/><br/>
<label for="sport">Sport:</label>
<select name="sport">
<option th:each="colorOpt : ${T(sportsapp.sportsapp.Sport).values()}"
th:value="${colorOpt}" th:text="${colorOpt.displayName}"></option>
</select>
<label for="divison">Divison:</label>
<select name="divison">
<option th:each="colorOpt : ${T(sportsapp.sportsapp.Divison).values()}"
th:value="${colorOpt}" th:text="${colorOpt.displayValue}"></option>
</select>
<div class="mytest">
<input type="submit" value="Add"/>
</div>
<input type="button" class="btn cancel" onclick="closeForm()" value="Close"/>
</form>
</div>
<script>
function openForm() {
document.getElementById("myForm").style.display = "block";
}
function closeForm() {
document.getElementById("myForm").style.display = "none";
}
</script>
</body>
</html>
解决方案
TeamRepository 有一个方法 save()。
使用 save() 方法,您可以创建和更新类对象。如果对象存在,它将更新它,如果对象不存在,它将创建它。
简而言之,修改您想要的对象并将其保存为:
public void updateTeam(Team k) {
this.service.save(k);
}
编辑
与数据库和前端交互的完整过程取决于您的喜好。有很多不同的方法可以实现这一点,但我个人使用这种方法来使事情顺利进行:
@Entity
@Table(name = "user", catalog = "filesystem", schema = "")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "User.findAll", query = "SELECT u FROM User u")
, @NamedQuery(name = "User.findByName", query = "SELECT u FROM User u WHERE u.name = :name")
, @NamedQuery(name = "User.findByJobTitle", query = "SELECT u FROM User u WHERE u.jobTitle = :jobTitle")
, @NamedQuery(name = "User.findByMail", query = "SELECT u FROM User u WHERE u.mail = :mail")
, @NamedQuery(name = "User.findByDateRegisted", query = "SELECT u FROM User u WHERE u.dateRegisted = :dateRegisted")
, @NamedQuery(name = "User.findByDateActivated", query = "SELECT u FROM User u WHERE u.dateActivated = :dateActivated")
, @NamedQuery(name = "User.findByActive", query = "SELECT u FROM User u WHERE u.active = :active")})
public class User implements Serializable, UserDetails {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@NotNull
@Column(columnDefinition = "BINARY(16)", name = "unique_id", updatable = false, nullable = false)
@ApiModelProperty(notes = "UUID format.") //swagger attribute level configuration (discription)
private UUID uniqueId;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 155)
@Column(name = "name")
private String name;
@Basic(optional = true)
@Size(min = 1, max = 155)
@Column(name = "jobTitle")
private String jobTitle;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 155)
@Column(name = "mail")
private String mail;
@Basic(optional = true)
@Column(name = "date_registed")
@Temporal(TemporalType.TIMESTAMP)
private Date dateRegisted;
@Column(name = "date_activated")
@Temporal(TemporalType.TIMESTAMP)
private Date dateActivated;
@Basic(optional = true)
@Column(name = "active")
private short active;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "userId", fetch = FetchType.LAZY)
private UserToken userToken;
public User() {
}
public User(UUID uniqueId) {
this.uniqueId = uniqueId;
}
public User(UUID uniqueId, String name, String jobTitle, String mail, Date dateRegisted, short active) {
this.uniqueId = uniqueId;
this.name = name;
this.jobTitle = jobTitle;
this.mail = mail;
this.dateRegisted = dateRegisted;
this.active = active;
}
public User(UserProfile_MGR user_model) {
this.uniqueId = UUID.fromString(user_model.getId());
this.name = user_model.getDisplayName();
this.jobTitle = user_model.getJobTitle();
this.mail = user_model.getMail();
this.dateRegisted = new Date();
this.active = 1;
}
public User(com.microsoft.graph.models.extensions.User user) {
this.uniqueId = UUID.fromString(user.id);
this.name = user.displayName;
this.jobTitle = user.jobTitle;
this.mail = user.mail;
this.dateRegisted = new Date();
this.active = 1;
}
public UUID getUniqueId() {
return uniqueId;
}
public void setUniqueId(UUID uniqueId) {
this.uniqueId = uniqueId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getJobTitle() {
return jobTitle;
}
public void setJobTitle(String jobTitle) {
this.jobTitle = jobTitle;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public Date getDateRegisted() {
return dateRegisted;
}
public void setDateRegisted(Date dateRegisted) {
this.dateRegisted = dateRegisted;
}
public Date getDateActivated() {
return dateActivated;
}
public void setDateActivated(Date dateActivated) {
this.dateActivated = dateActivated;
}
public short getActive() {
return active;
}
public void setActive(short active) {
this.active = active;
}
public UserToken getUserToken() {
return userToken;
}
public void setUserToken(UserToken userToken) {
this.userToken = userToken;
}
@Override
public int hashCode() {
int hash = 0;
hash += (uniqueId != null ? uniqueId.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof User)) {
return false;
}
User other = (User) object;
if ((this.uniqueId == null && other.uniqueId != null) || (this.uniqueId != null && !this.uniqueId.equals(other.uniqueId))) {
return false;
}
return true;
}
@Override
public String toString() {
return "com.usermanagement.api.entity.User[ uniqueId=" + uniqueId + " ]";
}
// JWT Essential information
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return new ArrayList<>();
}
@Override
@JsonIgnore
public String getPassword() {
return this.uniqueId.toString();
}
@Override
@JsonIgnore
public String getUsername() {
return this.name;
}
@Override
@JsonIgnore
public boolean isAccountNonExpired() {
return false;
}
@Override
@JsonIgnore
public boolean isAccountNonLocked() {
return false;
}
@Override
@JsonIgnore
public boolean isCredentialsNonExpired() {
return false;
}
@Override
public boolean isEnabled() {
return ((this.active == 0) ? false : true);
}
}
接下来是 CRUD 存储库,请注意 CRUD 存储库默认实现基本交互方法,例如保存、删除、选择等。如果您需要更高级的东西,可以在实体上创建命名查询并在 CRUD 界面上“启用”它们:
public interface UserRepositoryInterface extends CrudRepository<User, UUID> {
public List<User> findByMail(String mail);
}
接下来,您拥有实现或自动装配 CRUD 接口的存储库:
@Repository
public class UserRepository {
@Autowired
private UserRepositoryInterface userRepository;
public List<User> findUsers() {
Iterable<User> source = userRepository.findAll();
List<User> target = new ArrayList<>();
source.forEach(target::add);
return target;
}
public User findUser(UUID uuid) throws UserNotFound {
Optional<User> user = userRepository.findById(uuid);
if (!user.isPresent()) {
throw new UserNotFound("We where not able to identify the user resource.");
}
return user.get();
}
public User createUser(User user) throws UserAlreadyExistsException {
try {
this.findUser(user.getUniqueId());
throw new UserAlreadyExistsException("User Allready Exists in the Database");
} catch (UserNotFound ex) {
userRepository.save(user);
}
return user;
}
public void updateUserProfile(User user) throws UserNotFound {
if (findUser(user.getUniqueId()).getUniqueId() == null) {
throw new UserNotFound("User did not found.");
}
userRepository.save(user);
}
public void deleteUserById(UUID uuid) throws UserNotFound {
User user = findUser(uuid);
userRepository.deleteById(user.getUniqueId());
}
}
您可以将存储库自动连接到 @Service 或直接连接到您的 @RestController Rsource,由您决定:
@RestController
@RequestMapping("/users")
public class UserResource {
@Autowired
private UserRepository userRepository;
//retrieveAllUsers
@RequestMapping(method = RequestMethod.GET, path = "/")
public Iterable<User> findAllUsers() {
return userRepository.findUsers();
}
//Delete /users/{id}
@RequestMapping(method = RequestMethod.DELETE, path = "/users/{uuid}")
public ResponseEntity<Object> deleteUserById(@PathVariable UUID uuid) throws UserNotFound {
userRepository.deleteUserById(uuid);
return ResponseEntity.status(200).body(new Message("ok"));
}
}
最后,我用来与我的服务交互的方法是这样的普通 js:
function base_Get_request(url,callback) {
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
callback(xhr.response);
}
}
xhr.open('GET', url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send();
}
URL 是我要使用的服务的 URL,回调是成功时将调用的函数,一个简短的模板可能是这样的:
function tempCallback(data){
let temp = JSON.parse(data);
console.log(temp)
}
希望能帮助到你。
推荐阅读
- python - 我正在尝试将一个变量从一个 python 文件传递到另一个 python 文件
- sabre - OTA_AirRulesRQ API 失败
- python - 在布尔数组上移动窗口总和,带有步骤。
- asp.net-core-signalr - 如何扩展 SignalR ChannelReader?
- android - 在 PlayStore 上托管时,Youtube Data Api 在发布 APK 中不起作用
- c# - 如何使用 c# 处理包含数字/英文字符(双向文本)的希伯来语?
- elasticsearch - 如何使用 RestHighLevelClient 从弹性搜索中的索引中删除所有文档
- sql - 使用子查询将 OUTER APPLY 重写为 Redshift
- java - 从属性文件加载 Aspect 切入点表达式
- django - 循环中的Django prefetch_related,出了什么问题?