2017-10-19 28 views
0

J'ai une base de données oracle que je ne peux pas changer. Dans cette base de données, j'ai une table utilisateur avec des champs d'autorité.éviter de nombreuses instructions if, amélioration du code

CREATE TABLE USER (
    ID NUMBER(38,0), 
    LOGIN VARCHAR2(6 BYTE) NOT NULL ENABLE, 
    PASSWORD VARCHAR2(200 BYTE) NOT NULL ENABLE, 

    BOOK_READ NUMBER(1,0), 
    BOOK_UPD NUMBER(1,0), 
    R_READ NUMBER(1,0), 
    R_UPD NUMBER(1,0), 
    ... 
    ... 
) 

Par exemple:

book_read = 1; - means that user has authority 
book_upd = 0; - means that user he does not 
report_read = 1; 

En ce moment, je vérifie comme ceci:

List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); 
if (user.getBook_read() == 1) { 
    authorities.add(new SimpleGrantedAuthority("ROLE_BOOK_READ")); 
} 
if (user.getBook_upd() == 1) { 
    authorities.add(new SimpleGrantedAuthority("ROLE_BOOK_UPD")); 
} 
if (user.getReport_read() == 1) { 
    authorities.add(new SimpleGrantedAuthority("ROLE_REPORT_READ")); 
} 

J'ai beaucoup d'autorités (environ 20, ils ont tous une colonne séparée dans la table). Est-ce que quelqu'un suggère comment je peux améliorer le code?

+4

Je pense que cela appartient à la révision de code, mais assurez-vous de vérifier la [liste de contrôle de migration] (https://codereview.meta.stackexchange.com/a/1689/150216) –

+0

try switch statement – imk

+0

Que fait * "I avoir beaucoup d'Autorités "* signifie? Combien? Comment sont-ils stockés? Sont-ils tous des colonnes individuelles dans une table 'USER'? Si vous voulez de l'aide pour améliorer le code, vous devez au moins nous donner des informations plus pertinentes. – Andreas

Répondre

1

Il semble que ce moment vous avez 20 autorité colonnes dans la base de données, et un objet modèle User avec 20 champs, 20 getters et 20 setter, et vous avez besoin de 20 if déclarations pour construire le List<GrantedAuthority>.

Pour simplifier cela, je suggérerais de commencer par l'objet Model et le DAO.

Pour améliorer la flexibilité, créez un enum avec les 20 autorités et nommez explicitement le nom de la colonne de la base de données et le nom du rôle, par ex.

public enum User_Authority { 
    BOOK_READ("BOOK_READ", "ROLE_BOOK_READ"), 
    BOOK_UPD ("BOOK_UPD" , "ROLE_BOOK_UPD"), 
    // more enums 

    // fields here 

    private User_Authority(String columnName, String roleName) { 
     // assign to fields here 
    } 

    // getters here 
} 

Votre objet User modèle peut alors utiliser un EnumSet<User_Authority> pour stocker les autorités sont accordées à l'utilisateur.

Votre Spring JDBC modèle peut alors utiliser un RowMapper avec la logique comme ceci:

public final class UserRowMapper implements RowMapper<User> { 
    @Override 
    public User mapRow(ResultSet rs, int rowNum) { 
     User user = new User(); 
     // get other columns here 
     EnumSet<User_Authority> granted = EnumSet.noneOf(User_Authority.class); 
     for (User_Authority auth : User_Authority.values()) 
      if (rs.getInt(auth.getColumnName()) == 1) 
       granted.add(auth); 
     user.setAuthorities(granted); 
     return user; 
    } 
} 

Le code pour construire le List<GrantedAuthority> authorities est maintenant aussi simple que cela:

List<GrantedAuthority> authorities = new ArrayList<>(); 
for (User_Authority auth : user.getAuthorities()) 
    authorities.add(new SimpleGrantedAuthority(auth.getRoleName())); 

Comme vous pouvez le voir, vous avez maintenant seulement un endroit avec 20 "répétitions": Les valeurs enum.

Si vous devez ajouter plus tard, vous bien sûr ajouter une nouvelle colonne à la table d'utilisateur, puis il vous suffit d'ajouter deux articles au code:

  • Ajouter une colonne à SELECT clause de l'instruction SQL donnée au printemps modèle JDBC. Ajouter une nouvelle valeur enum.

C'est une simplification/amélioration du code, n'est-ce pas?

0

Que diriez-vous de créer une liste de classe de stockage de la relation entre la méthode et SimpleGrantedAuthority

public class RoleChecker 
{ 
    Function<User, Integer> roleCheckFunction; 
    SimpleGrantedAuthority theAuthority; 

    public RoleChecker(Function<User, Integer> roleCheckFunction, SimpleGrantedAuthority theAuthority) 
    {} 
} 

et exécuter la boucle en utilisant le contrôle.

List<RoleChecker> roles = new ArrayList<>(); 
roles.add(new RoleChecker(User::getBook_read, new SimpleGrantedAuthority("ROLE_BOOK_READ"))); 
roles.add(new RoleChecker(User::getBook_upd, new SimpleGrantedAuthority("ROLE_BOOK_UPD"))); 
// .... 
for (RoleChecker check : roles) 
{ 
    if (check.roleCheckFunction.apply(user) == 1) 
     authorities.add(check.theAuthority); 
}