我有這個編輯表單:彈簧形式:選擇多個選定的值?
我想的是,用戶的角色都被選擇。如果這是一對多的關係,我知道我可以這樣做:
<form:label path="roles">Roles:</form:label>
<form:select multiple="true" path="roles">
<c:forEach items="${roles}" var="rol">
<c:choose>
<c:when
test="${usuarioEdit.rol.id ==rol.id}">
<option value="${rol.id}" selected="selected">${rol.nombre}</option>
</c:when>
<c:otherwise>
<option value="${rol.id}">${rol.nombre}</option>
</c:otherwise>
</c:choose>
</c:forEach>
</form:select>
<form:errors cssStyle="color:red" path="roles"></form:errors>
但是這是一個多對多的關係。如何在編輯表單中選擇選項?有一種簡單的形式嗎?
此代碼的工作,但我不知道春天提供任何設施:
<form:select multiple="true" path="roles">
<c:forEach items="${roles}" var="rol">
<c:set var="isSelected" value="false" />
<c:forEach items="${rolesUsu}" var="rolUsu">
<c:if test="${rolUsu.getRol().getId()==rol.id}">
<c:set var="isSelected" value="true" />
</c:if>
</c:forEach>
<c:choose>
<c:when test="${isSelected}">
<option value="${rol.id}" selected="selected">${rol.nombre}</option>
</c:when>
<c:otherwise>
<option value="${rol.id}">${rol.nombre}</option>
</c:otherwise>
</c:choose>
</c:forEach>
</form:select>
編輯:
在我的控制,我有:
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Set.class, "roles",
new RolCollectionEditor(Set.class, rolDao));
}
RolCollectionEditor:
public class RolCollectionEditor extends CustomCollectionEditor {
private final RolDAO rolDao;
public RolCollectionEditor(Class<?> collectionType, RolDAO rolDao) {
super(collectionType);
this.rolDao = rolDao;
}
@Override
protected Object convertElement(Object element) {
String rolId = (String) element;
Rol rol = rolDao.findById(rolId);
Usuario_Rol usuRol = new Usuario_Rol();
//Agregamos un usuario vacio temporal
//y lo sobreescribimos en el controlador
Usuario usuario = new Usuario();
usuRol.setUsuario(usuario);
usuRol.setRol(rol);
usuRol.setFechaCreacion(new Date());
usuRol.setFechaModificacion(new Date());
usuRol.setStatus("activo");
return usuRol;
}
}
這裏Usuario_Rol是多對多關係的中間表,除了userId和rolId之外,還有其他屬性。
EDIT2:
ROL類:
@Entity
@Table(name = "rol", uniqueConstraints = { @UniqueConstraint(columnNames = "nombre") })
public class Rol implements Serializable{
@Id
@Column(name = "_id")
private String id;
@Column(name = "nombre")
@NotNull
private String nombre;
@Column(name = "descripcion")
private String descripcion;
@Column(name = "status")
private String status;
@Column(name = "fechaCreacion")
private Date fechaCreacion;
@Column(name = "fechaModificacion")
private Date fechaModificacion;
@Column(name = "fechaSincronizacion")
private Date fechaSincronizacion;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "usuarioRol_pk.rol", orphanRemoval = true, cascade=CascadeType.ALL)
private Set<Usuario_Rol> usuarios = new HashSet<Usuario_Rol>(0);
//getters and setters
@Override
final public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((nombre == null) ? 0 : nombre.hashCode());
return result;
}
@Override
final public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Rol))
return false;
Rol other = (Rol) obj;
if (nombre == null) {
if (other.nombre != null)
return false;
} else if (!nombre.equals(other.nombre))
return false;
return true;
}
類Usuario:
@Entity @Table(名稱= 「usuario」,uniqueConstraints = { @UniqueConstraint(COLUMNNAMES = 「login」), @UniqueConstraint(columnNames =「correo」)}) public class Usuario implements Serializable {
@Id
@Column(name = "_id")
private String id;
@Column(name = "nombre")
@NotEmpty
private String nombre;
@Column(name = "apellido")
@NotEmpty
private String apellido;
@Column(name = "login")
@Size(min = 4)
@NotEmpty
private String login;
@Column(name = "password")
@NotEmpty
@Size(min = 4)
private String password;
@Column(name = "salt")
private String salt;
@Column(name = "correo")
@NotEmpty
@Email
private String correo;
@Column(name = "token")
private String token;
@Column(name = "status")
private String status;
@Column(name = "fechaUltimoLogin")
private Date fechaUltimoLogin;
@Column(name = "fechaCreacion")
private Date fechaCreacion;
@Column(name = "fechaModificacion")
private Date fechaModificacion;
@Column(name = "fechaSincronizacion")
private Date fechaSincronizacion;
@NotEmpty
@OneToMany(fetch = FetchType.EAGER, mappedBy = "usuarioRol_pk.usuario", orphanRemoval = true, cascade = CascadeType.ALL)
private Set<Usuario_Rol> roles = new HashSet<Usuario_Rol>(0);
//constructor, getters and setters.
@Override
final public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((login == null) ? 0 : login.hashCode());
return result;
}
@Override
final public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Usuario))
return false;
Usuario other = (Usuario) obj;
if (login == null) {
if (other.login != null)
return false;
} else if (!login.equals(other.login))
return false;
return true;
}
中級班:
@Entity
@Table(name = "usuario_rol")
@AssociationOverrides({
@AssociationOverride(name = "usuarioRol_pk.usuario", joinColumns = @JoinColumn(name = "idUsuario")),
@AssociationOverride(name = "usuarioRol_pk.rol", joinColumns = @JoinColumn(name = "idRol"))
})
public class Usuario_Rol implements Serializable{
@EmbeddedId
private Usuario_RolId usuarioRol_pk = new Usuario_RolId();
@Temporal(TemporalType.DATE)
@Column(name = "fechaCreacion")
private Date fechaCreacion;
@Temporal(TemporalType.DATE)
@Column(name = "fechaModificacion")
private Date fechaModificacion;
@Temporal(TemporalType.DATE)
@Column(name = "fechaSincronizacion")
private Date fechaSincronizacion;
@Column(name = "status")
private String status;
//gettters, setters
@Override
final public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((usuarioRol_pk == null) ? 0 : usuarioRol_pk.hashCode());
return result;
}
@Override
final public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Usuario_Rol))
return false;
Usuario_Rol other = (Usuario_Rol) obj;
if (usuarioRol_pk == null) {
if (other.usuarioRol_pk != null)
return false;
} else if (!usuarioRol_pk.equals(other.usuarioRol_pk))
return false;
return true;
}
Usuario_RolId:
@Embeddable
public class Usuario_RolId implements Serializable{
@ManyToOne
private Usuario usuario;
@ManyToOne
private Rol rol;
public Usuario getUsuario() {
return usuario;
}
public void setUsuario(Usuario usuario) {
this.usuario = usuario;
}
public Rol getRol() {
return rol;
}
public void setRol(Rol rol) {
this.rol = rol;
}
@Override
final public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((rol == null) ? 0 : rol.hashCode());
result = prime * result + ((usuario == null) ? 0 : usuario.hashCode());
return result;
}
@Override
final public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Usuario_RolId))
return false;
Usuario_RolId other = (Usuario_RolId) obj;
if (rol == null) {
if (other.rol != null)
return false;
} else if (!rol.equals(other.rol))
return false;
if (usuario == null) {
if (other.usuario != null)
return false;
} else if (!usuario.equals(other.usuario))
return false;
return true;
}
這最後一堂課是用於模擬一個多對多關係的伎倆。我遵循本教程:http://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/
我不明白如何在選擇輸入中有多對多的關係...在時間t,選定的元素將始終屬於一個實體(用戶)。或者,也許我誤解你的問題 –
是的,這是一個多對多的關係,但我只使用一個方向一個用戶 - >很多角色,但在我的數據庫中,我有一個idUser和idRol的表。我用一個解決方案編輯了這個問題,但仍然想知道春天是否提供了任何設施來實現我想要的。 – kiduxa
好了,現在我明白了。我不認爲這個春天有特定的東西來實現這個......但是你應該在控制器端做這種行爲,然後返回屬於用戶列表的角色ID數組。然後使用該數組來檢查是否應該選擇選項。它使視圖更清晰,我通常嘗試避免許多嵌入式JSTL標籤,它很難理解 –