JHipster:向用户注册其他信息 [英] JHipster: Registering a user with additional information
问题描述
首先,我要感谢" Paul Etienne ",以帮助他问题和答案!下面给出的答案更加详细,并且考虑到JHipster的最新版本(3/17/2018)编写.
First of all, I'd like to thank "Paul Etienne" for his helpful question and answer! The answer bellow is a little bit more detailed and has been written considering the last version of JHipster (3/17/2018).
问题很明显:如何在JHipster项目中向用户实体添加新的数据字段.
The question is clear: how to add new data field(s) to User entity in a JHipster project.
推荐答案
正如JHipster官方网站中提到的,向默认JHipster用户添加新字段/关系的最佳方法是创建一个新实体并将其链接到User一对一的关系您可以在新实体中处理更多关系.我们将此称为新的实体UserExtra.
As it's mentioned in the official JHipster website, the best way to add new fields/relations to the default JHipster User is creating a new Entity and link it to User with a one-to-one relationship. You may handle more relationships in the new Entity. Let's call this new Entity UserExtra.
上面的UML图显示了User和UserExtra之间的组合,这意味着用户具有与用户密切相关的UserExtra,并且没有User不能存在.换句话说,应该首先有一个用户,以便我们可以为其分配电话号码.
The UML diagram above, shows a composition between User and UserExtra meaning that a User has a UserExtra which is strongly dependent to the User and cannot exist without the User. In other words, there should be a user first so we can assign a phone number to.
第1步:创建新实体
我建议使用终端创建新实体:jhipster实体userExtra
I suggest creating the new entity using terminal: jhipster entity userExtra
或
JDL:
第2步:修改新实体
您可以在域文件夹下找到新的实体类:
You may find the new entity class under the domain folder:
我们可以将UserExtra的ID映射到User的ID,以便我们可以将UserExtra的ID用作外键.如果是这样,那么我们就不应再在UserExtra中使用@GeneratedValue注释作为id了.这是一个示例UserExtra类.这是修改后的UserExtra的示例:
We may map the id of UserExtra to the id of User so we can use the id of UserExtra as the foreign-key. If so, then we should not use @GeneratedValue annotation for id in UserExtra anymore. Here is a sample UserExtra class. Here is a sample of a modified UserExtra:
package org.jhipster.domain;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Objects;
/**
* A UserExtra.
*/
@Entity
@Table(name = "user_extra")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class UserExtra implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private Long id;
@OneToOne
@MapsId
private User user;
@Column(name = "phone")
private String phone;
// jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPhone() {
return phone;
}
public UserExtra phone(String phone) {
this.phone = phone;
return this;
}
public void setPhone(String phone) {
this.phone = phone;
}
public User getUser() {
return user;
}
public UserExtra user(User user) {
this.user = user;
return this;
}
public void setUser(User user) {
this.user = user;
}
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
UserExtra userExtra = (UserExtra) o;
if (userExtra.getId() == null || getId() == null) {
return false;
}
return Objects.equals(getId(), userExtra.getId());
}
@Override
public int hashCode() {
return Objects.hashCode(getId());
}
@Override
public String toString() {
return "UserExtra{" +
"id=" + getId() +
", phone='" + getPhone() + "'" +
"}";
}
}
第3步:修改新实体的配置
[如果您在第一步中使用过JDL,则可以跳过此步骤]
[You may skip this step if you've used JDL in the 1st step]
有一个保存实体配置的json文件: 我们需要修改配置.这是修改后的配置json文件的示例:
There is a json file keeping the configuration of the entity: We need to modify the configuration. here is a sample of a modified configuration json file:
{
"fluentMethods": true,
"relationships": [
{
"relationshipType": "one-to-one",
"relationshipName": "user",
"otherEntityName": "user",
"otherEntityField": "id",
"ownerSide": true,
"otherEntityRelationshipName": "userExtra"
}
],
"fields": [
{
"fieldName": "phone",
"fieldType": "String"
}
],
"changelogDate": "20180317190851",
"dto": "no",
"service": "no",
"entityTableName": "user_extra",
"jpaMetamodelFiltering": false,
"pagination": "no"
}
还有一些xml更改日志: 这是示例更改日志:
There are also some xml change logs: Here are sample change logs:
added_entity_UserExtra:
added_entity_UserExtra:
<?xml version="1.0" encoding="utf-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<property name="now" value="now()" dbms="h2"/>
<property name="now" value="now()" dbms="mysql"/>
<!--<property name="autoIncrement" value="true"/>-->
<property name="floatType" value="float4" dbms="postgresql, h2"/>
<property name="floatType" value="float" dbms="mysql, oracle, mssql"/>
<!--
Added the entity UserExtra.
-->
<changeSet id="20180317190851-1" author="jhipster">
<createTable tableName="user_extra">
<column name="user_id" type="bigint">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="phone" type="varchar(255)">
<constraints nullable="true" />
</column>
<!-- jhipster-needle-liquibase-add-column - JHipster will add columns here, do not remove-->
</createTable>
</changeSet>
<!-- jhipster-needle-liquibase-add-changeset - JHipster will add changesets here, do not remove-->
</databaseChangeLog>
added_entity_constraints_UserExtra:
added_entity_constraints_UserExtra:
<?xml version="1.0" encoding="utf-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd">
<!--
Added the constraints for entity UserExtra.
-->
<changeSet id="20180317190851-2" author="jhipster">
<addForeignKeyConstraint baseColumnNames="user_id"
baseTableName="user_extra"
constraintName="fk_user_extra_user_id"
referencedColumnNames="id"
referencedTableName="jhi_user"/>
</changeSet>
</databaseChangeLog>
请注意,JHipster为用户实体使用了名为"JHI_USER"的表,并为新实体创建了名为"USER_EXTRA"的表.我们将新实体的主键/id"字段命名为"USER_ID":
Just be aware that JHipster uses a table named "JHI_USER" for the User entity and has created a table named "USER_EXTRA" for the new entity. We are going to name the primary-key/id field of the new entity "USER_ID":
第4步:修改ManagedUserVM.java
ManagedUserVM类是在REST控制器中使用的DTO扩展UserDTO的一种.
ManagedUserVM class is sort of a DTO extending UserDTO which is used in the REST controller.
此修改的目的是添加新字段,以将其作为附加信息绑定到User.这是此类的示例代码. phone属性已添加到修改后的类中:
The purpose of this modification is adding the new field(s) we are going to bind to User as extra information. Here is a sample code of this class. The phone attribute has been added to the modified class:
package org.jhipster.web.rest.vm;
import org.jhipster.service.dto.UserDTO;
import javax.validation.constraints.Size;
/**
* View Model extending the UserDTO, which is meant to be used in the user management UI.
*/
public class ManagedUserVM extends UserDTO {
public static final int PASSWORD_MIN_LENGTH = 4;
public static final int PASSWORD_MAX_LENGTH = 100;
@Size(min = PASSWORD_MIN_LENGTH, max = PASSWORD_MAX_LENGTH)
private String password;
private String phone;
public ManagedUserVM() {
// Empty constructor needed for Jackson.
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public String toString() {
return "ManagedUserVM{" +
"} " + super.toString();
}
}
第5步:修改UserService.java
此calss中有一个名为"registerUser"的方法,负责注册新用户:
There is a method named "registerUser" in this calss which is responsible for registering a new user:
修改此服务类的目的是迫使它在添加用户时也添加UserExtra对象.这是修改后的"registeruser"方法的示例.您可以在添加的代码的顶部找到创建并保存UserExtra实体"作为注释:
The purpose of modifying this service class is to force it to also add a UserExtra object when a User is getting added. here is a sample of a modified "registeruser" method. You may find the added code with "Create and save the UserExtra entity" at top of it as comment:
public User registerUser(UserDTO userDTO, String password, String phone) {
User newUser = new User();
Authority authority = authorityRepository.findOne(AuthoritiesConstants.USER);
Set<Authority> authorities = new HashSet<>();
String encryptedPassword = passwordEncoder.encode(password);
newUser.setLogin(userDTO.getLogin());
// new user gets initially a generated password
newUser.setPassword(encryptedPassword);
newUser.setFirstName(userDTO.getFirstName());
newUser.setLastName(userDTO.getLastName());
newUser.setEmail(userDTO.getEmail());
newUser.setImageUrl(userDTO.getImageUrl());
newUser.setLangKey(userDTO.getLangKey());
// new user is not active
newUser.setActivated(false);
// new user gets registration key
newUser.setActivationKey(RandomUtil.generateActivationKey());
authorities.add(authority);
newUser.setAuthorities(authorities);
userRepository.save(newUser);
cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).evict(newUser.getLogin());
cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE).evict(newUser.getEmail());
log.debug("Created Information for User: {}", newUser);
// Create and save the UserExtra entity
UserExtra newUserExtra = new UserExtra();
newUserExtra.setUser(newUser);
newUserExtra.setPhone(phone);
userExtraRepository.save(newUserExtra);
log.debug("Created Information for UserExtra: {}", newUserExtra);
return newUser;
}
步骤6:修改AccountResource.java
此类是REST控制器,负责与帐户相关的活动:
This class is a REST controller responsible for Account related activities:
此控制器中有一个名为"registerAccount"的方法,该方法调用UserService类的"registerUser"方法:
There is a method named "registerAccount" in this controller that calls "registerUser" method of UserService class:
User user = userService.registerUser(managedUserVM, managedUserVM.getPassword());
我们需要修改此行,以便可以将新字段传递给方法:
We need to modify this line so we can pass the new field(s) to the method:
@PostMapping("/register")
@Timed
@ResponseStatus(HttpStatus.CREATED)
public void registerAccount(@Valid @RequestBody ManagedUserVM managedUserVM) {
if (!checkPasswordLength(managedUserVM.getPassword())) {
throw new InvalidPasswordException();
}
userRepository.findOneByLogin(managedUserVM.getLogin().toLowerCase()).ifPresent(u -> {throw new LoginAlreadyUsedException();});
userRepository.findOneByEmailIgnoreCase(managedUserVM.getEmail()).ifPresent(u -> {throw new EmailAlreadyUsedException();});
User user = userService.registerUser(managedUserVM, managedUserVM.getPassword(), managedUserVM.getPhone());
mailService.sendActivationEmail(user);
}
第7步:修改用户界面
最后,您需要在html文件中添加输入元素:
Finally, you need to add an input element into the html file:
<div class="form-group">
<label class="form-control-label" for="phone" data-translate="global.form.phone">Phone number</label>
<input type="tel" class="form-control" id="phone" name="phone" #phone="ngModel" placeholder="{{'global.form.phone.placeholder' | translate}}"
[(ngModel)]="registerAccount.phone">
</div>
然后,这就是您在注册页面中看到的内容:
Then, this is what you'll have in the registration page:
这是数据层:
JHI_USER
USER_EXTRA
USER_EXTRA
P.S.
最简单的方法是通过JDL添加与User具有一对一关系的UserExtra实体,并在创建新用户时添加"userExtra".
这篇关于JHipster:向用户注册其他信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!