JHipster 4.14.1:向用户注册其他信息

Ali*_*eza 4 jhipster

首先,我要感谢" Paul Etienne "提出的有用的问题和答案!下面的答案稍微详细一点,并考虑到最后一个版本的JHipster(3/17/2018).

问题很明确:如何在JHipster项目中向User实体添加新数据字段.

Ali*_*eza 10

正如官方JHipster网站中所提到的,向默认JHipster用户添加新字段/关系的最佳方式是创建一个新实体,并将其与一对一关系链接到用户.您可以在新实体中处理更多关系.我们称之为新的Entity UserExtra. User和UserExtra之间的组合

上面的UML图显示了User和UserExtra之间的组合,这意味着User具有强烈依赖于User的UserExtra,并且在没有User的情况下不能存在.换句话说,应该有一个用户,所以我们可以分配一个电话号码.

第1步:创建一个新实体

我建议使用终端创建新实体:jhipster entity userExtra

要么

JDL:

在此输入图像描述

第2步:修改新实体

您可以在域文件夹下找到新的实体类: 在此输入图像描述

我们可以将UserExtra的id映射到User的id,这样我们就可以使用UserExtra的id作为外键.如果是这样,那么我们就不应该在UserExtra中对id使用@GeneratedValue注释了.这是一个示例UserExtra类.以下是修改后的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() + "'" +
            "}";
    }
}
Run Code Online (Sandbox Code Playgroud)

第3步:修改新实体的配置

[如果您在第一步中使用了JDL,则可以跳过此步骤]

有一个json文件保存实体的配置: 在此输入图像描述 我们需要修改配置.这是一个修改过的配置json文件的示例:

{
    "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"
}
Run Code Online (Sandbox Code Playgroud)

还有一些xml更改日志: 在此输入图像描述 以下是样本更改日志:

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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

请注意,JHipster为User实体使用名为"JHI_USER"的表,并为新实体创建了一个名为"USER_EXTRA"的表.我们将命名新实体"USER_ID"的primary-key/id字段:

在此输入图像描述

第4步:修改ManagedUserVM.java

ManagedUserVM类是一种扩展UserDTO的DTO,它在REST控制器中使用. 在此输入图像描述

此修改的目的是添加我们将要绑定到User的新字段作为额外信息.以下是此类的示例代码.phone属性已添加到修改后的类中:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

第5步:修改UserService.java

在这个calss中有一个名为"registerUser"的方法,它负责注册一个新用户:

在此输入图像描述

修改此服务类的目的是强制它在添加用户时添加UserExtra对象.这是修改后的"registeruser"方法的示例.您可以在其顶部找到添加的代码"创建并保存UserExtra实体"作为注释:

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;
    }
Run Code Online (Sandbox Code Playgroud)

第6步:修改AccountResource.java

此类是一个REST控制器,负责与帐户相关的活动: 在此输入图像描述

在这个控制器中有一个名为"registerAccount"的方法,它调用UserService类的"registerUser"方法:

User user = userService.registerUser(managedUserVM, managedUserVM.getPassword());
Run Code Online (Sandbox Code Playgroud)

我们需要修改这一行,以便我们可以将新字段传递给方法:

    @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);
    }
Run Code Online (Sandbox Code Playgroud)

第7步:修改用户界面

最后,您需要在html文件中添加一个输入元素:

在此输入图像描述

<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>
Run Code Online (Sandbox Code Playgroud)

然后,这是您在注册页面中拥有的内容:

在此输入图像描述

这是数据层:

JHI_USER

在此输入图像描述

USER_EXTRA

在此输入图像描述

PS

最简单的方法是通过JDL添加一个与User一对一关系的UserExtra实体,并在创建新用户时添加"userExtra".