- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如何使用 @RepositoryRestResource 通过 Spring DATA REST 提供 Java 模型的 RDF/XML 和 JSON-LD 表示形式?
我正在阅读有关内容协商的内容,但只找到了带有 @Controller 注释的示例,并且在使用 @RepositoryRestResource 时我需要解释
这是我的代码。
我的实体类
package ec.edu.utpl.gestiondatos.tesis.entities;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
/**
*
* @author Efren
*/
@Entity
@Table(name = "TDI_DOCENTE")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "TdiDocente.findAll", query = "SELECT t FROM TdiDocente t")})
public class TdiDocente implements Serializable {
private static final long serialVersionUID = -8846422129143878578L;
// @Max(value=?) @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
@Id
@Basic(optional = false)
@NotNull
@Column(name = "DO_ID")
private BigDecimal doId;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 13)
@Column(name = "DO_IDENTIFICACION")
private String doIdentificacion;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 100)
@Column(name = "DO_APELLIDO_PATERNO")
private String doApellidoPaterno;
@Size(max = 100)
@Column(name = "DO_APELLIDO_MATERNO")
private String doApellidoMaterno;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 100)
@Column(name = "DO_PRIMER_NOMBRE")
private String doPrimerNombre;
@Size(max = 100)
@Column(name = "DO_SEGUNDO_NOMBRE")
private String doSegundoNombre;
@Column(name = "DO_FECHA_NACIMIENTO")
@Temporal(TemporalType.TIMESTAMP)
private Date doFechaNacimiento;
@Column(name = "DO_EQU_ID_NSGA")
private BigInteger doEquIdNsga;
@Column(name = "DO_EQU_ID_SGA")
private BigInteger doEquIdSga;
@Column(name = "DO_EQU_ID_SICA")
private BigInteger doEquIdSica;
@Column(name = "DO_EQU_ID_EVA")
private BigInteger doEquIdEva;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 2)
@Column(name = "DO_GENERO")
private String doGenero;
@Basic(optional = false)
@NotNull
@Column(name = "DO_FECHA_CREACION")
@Temporal(TemporalType.TIMESTAMP)
private Date doFechaCreacion;
@Column(name = "DO_FECHA_ACTUALIZACION")
@Temporal(TemporalType.TIMESTAMP)
private Date doFechaActualizacion;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 1)
@Column(name = "DO_ACTIVO")
private String doActivo;
@Size(max = 120)
@Column(name = "DO_CORREO_PRI")
private String doCorreoPri;
@Size(max = 120)
@Column(name = "DO_CORREO_SEC")
private String doCorreoSec;
@Size(max = 30)
@Column(name = "DO_TELEFONO_DOM")
private String doTelefonoDom;
@Size(max = 30)
@Column(name = "DO_CELULAR_PRI")
private String doCelularPri;
@Size(max = 30)
@Column(name = "DO_CELULAR_SEC")
private String doCelularSec;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 1)
@Column(name = "DO_PROMETEO")
private String doPrometeo;
@Column(name = "DO_EQU_ID_CITTES")
private BigInteger doEquIdCittes;
@Column(name = "DO_EQU_ID_NSGA2")
private BigInteger doEquIdNsga2;
@Size(max = 15)
@Column(name = "DO_IDENTIFICACION_RRHH")
private String doIdentificacionRrhh;
@Size(max = 1)
@Column(name = "DO_VALIDADO_RRHH")
private String doValidadoRrhh;
@Size(max = 20)
@Column(name = "DO_EXTENSION")
private String doExtension;
@Column(name = "DO_TECNICO_DOCENTE")
private Character doTecnicoDocente;
@Column(name = "DO_FECHA_INGRESO")
@Temporal(TemporalType.TIMESTAMP)
private Date doFechaIngreso;
@Column(name = "DO_FECHA_SALIDA")
@Temporal(TemporalType.TIMESTAMP)
private Date doFechaSalida;
@Size(max = 50)
@Column(name = "USUARIO_APEX_CREA")
private String usuarioApexCrea;
@Size(max = 50)
@Column(name = "USUARIO_APEX_ACTUALIZA")
private String usuarioApexActualiza;
@Size(max = 80)
@Column(name = "DO_CORREO_PERSONAL")
private String doCorreoPersonal;
@Size(max = 1)
@Column(name = "DO_ES_ADMINISTRATIVO")
private String doEsAdministrativo;
@Column(name = "DO_ID_TIPO_SANGRE")
private BigInteger doIdTipoSangre;
@Column(name = "DO_EQU_ID_RR_HH")
private BigInteger doEquIdRrHh;
@Size(max = 25)
@Column(name = "DO_IDENTIFICACION_NOMINA")
private String doIdentificacionNomina;
@Size(max = 1)
@Column(name = "DO_REPETIDO_NSGA")
private String doRepetidoNsga;
@Size(max = 100)
@Column(name = "DO_OBSERVACIONES_REPETIDO")
private String doObservacionesRepetido;
@Column(name = "DO_EQUI_ID_NOMINA")
private BigInteger doEquiIdNomina;
@Column(name = "DO_EQUI_ID_REGISTRO")
private BigInteger doEquiIdRegistro;
@Column(name = "DO_CANTON_NACIMIENTO")
private BigInteger doCantonNacimiento;
@Column(name = "DO_PROVINCIA_NACIMIENTO")
private BigInteger doProvinciaNacimiento;
@Column(name = "DO_TIPO_DISCAPACIDAD")
private BigInteger doTipoDiscapacidad;
@Column(name = "DO_PORCENTAJE_DISCAPACIDAD")
private BigInteger doPorcentajeDiscapacidad;
@Size(max = 25)
@Column(name = "DO_NUMERO_CARNET_CONADIS")
private String doNumeroCarnetConadis;
@Size(max = 250)
@Column(name = "DO_OBSERVACION")
private String doObservacion;
@Size(max = 15)
@Column(name = "DO_IDENTIFICACION_NSGA")
private String doIdentificacionNsga;
@Lob
@Column(name = "DO_FOTO")
private Serializable doFoto;
@Size(max = 255)
@Column(name = "DO_FOTO_MIMETYPE")
private String doFotoMimetype;
@Size(max = 255)
@Column(name = "DO_FOTO_FILENAME")
private String doFotoFilename;
@Column(name = "DO_FOTO_LAST_UPDATE")
@Temporal(TemporalType.TIMESTAMP)
private Date doFotoLastUpdate;
@Column(name = "DO_EQU_ID_NSGA3")
private BigInteger doEquIdNsga3;
@Column(name = "DO_FECHA_INICIO_ADENDA")
@Temporal(TemporalType.TIMESTAMP)
private Date doFechaInicioAdenda;
@Column(name = "DO_FECHA_FIN_ADENDA")
@Temporal(TemporalType.TIMESTAMP)
private Date doFechaFinAdenda;
@Column(name = "DO_FECHA_VALIDACION_RRHH")
@Temporal(TemporalType.TIMESTAMP)
private Date doFechaValidacionRrhh;
public TdiDocente() {
}
public TdiDocente(BigDecimal doId) {
this.doId = doId;
}
public TdiDocente(BigDecimal doId, String doIdentificacion, String doApellidoPaterno, String doPrimerNombre, String doGenero, Date doFechaCreacion, String doActivo, String doPrometeo) {
this.doId = doId;
this.doIdentificacion = doIdentificacion;
this.doApellidoPaterno = doApellidoPaterno;
this.doPrimerNombre = doPrimerNombre;
this.doGenero = doGenero;
this.doFechaCreacion = doFechaCreacion;
this.doActivo = doActivo;
this.doPrometeo = doPrometeo;
}
public BigDecimal getDoId() {
return doId;
}
public void setDoId(BigDecimal doId) {
this.doId = doId;
}
public String getDoIdentificacion() {
return doIdentificacion;
}
public void setDoIdentificacion(String doIdentificacion) {
this.doIdentificacion = doIdentificacion;
}
public String getDoApellidoPaterno() {
return doApellidoPaterno;
}
public void setDoApellidoPaterno(String doApellidoPaterno) {
this.doApellidoPaterno = doApellidoPaterno;
}
public String getDoApellidoMaterno() {
return doApellidoMaterno;
}
public void setDoApellidoMaterno(String doApellidoMaterno) {
this.doApellidoMaterno = doApellidoMaterno;
}
public String getDoPrimerNombre() {
return doPrimerNombre;
}
public void setDoPrimerNombre(String doPrimerNombre) {
this.doPrimerNombre = doPrimerNombre;
}
public String getDoSegundoNombre() {
return doSegundoNombre;
}
public void setDoSegundoNombre(String doSegundoNombre) {
this.doSegundoNombre = doSegundoNombre;
}
public Date getDoFechaNacimiento() {
return doFechaNacimiento;
}
public void setDoFechaNacimiento(Date doFechaNacimiento) {
this.doFechaNacimiento = doFechaNacimiento;
}
public BigInteger getDoEquIdNsga() {
return doEquIdNsga;
}
public void setDoEquIdNsga(BigInteger doEquIdNsga) {
this.doEquIdNsga = doEquIdNsga;
}
public BigInteger getDoEquIdSga() {
return doEquIdSga;
}
public void setDoEquIdSga(BigInteger doEquIdSga) {
this.doEquIdSga = doEquIdSga;
}
public BigInteger getDoEquIdSica() {
return doEquIdSica;
}
public void setDoEquIdSica(BigInteger doEquIdSica) {
this.doEquIdSica = doEquIdSica;
}
public BigInteger getDoEquIdEva() {
return doEquIdEva;
}
public void setDoEquIdEva(BigInteger doEquIdEva) {
this.doEquIdEva = doEquIdEva;
}
public String getDoGenero() {
return doGenero;
}
public void setDoGenero(String doGenero) {
this.doGenero = doGenero;
}
public Date getDoFechaCreacion() {
return doFechaCreacion;
}
public void setDoFechaCreacion(Date doFechaCreacion) {
this.doFechaCreacion = doFechaCreacion;
}
public Date getDoFechaActualizacion() {
return doFechaActualizacion;
}
public void setDoFechaActualizacion(Date doFechaActualizacion) {
this.doFechaActualizacion = doFechaActualizacion;
}
public String getDoActivo() {
return doActivo;
}
public void setDoActivo(String doActivo) {
this.doActivo = doActivo;
}
public String getDoCorreoPri() {
return doCorreoPri;
}
public void setDoCorreoPri(String doCorreoPri) {
this.doCorreoPri = doCorreoPri;
}
public String getDoCorreoSec() {
return doCorreoSec;
}
public void setDoCorreoSec(String doCorreoSec) {
this.doCorreoSec = doCorreoSec;
}
public String getDoTelefonoDom() {
return doTelefonoDom;
}
public void setDoTelefonoDom(String doTelefonoDom) {
this.doTelefonoDom = doTelefonoDom;
}
public String getDoCelularPri() {
return doCelularPri;
}
public void setDoCelularPri(String doCelularPri) {
this.doCelularPri = doCelularPri;
}
public String getDoCelularSec() {
return doCelularSec;
}
public void setDoCelularSec(String doCelularSec) {
this.doCelularSec = doCelularSec;
}
public String getDoPrometeo() {
return doPrometeo;
}
public void setDoPrometeo(String doPrometeo) {
this.doPrometeo = doPrometeo;
}
public BigInteger getDoEquIdCittes() {
return doEquIdCittes;
}
public void setDoEquIdCittes(BigInteger doEquIdCittes) {
this.doEquIdCittes = doEquIdCittes;
}
public BigInteger getDoEquIdNsga2() {
return doEquIdNsga2;
}
public void setDoEquIdNsga2(BigInteger doEquIdNsga2) {
this.doEquIdNsga2 = doEquIdNsga2;
}
public String getDoIdentificacionRrhh() {
return doIdentificacionRrhh;
}
public void setDoIdentificacionRrhh(String doIdentificacionRrhh) {
this.doIdentificacionRrhh = doIdentificacionRrhh;
}
public String getDoValidadoRrhh() {
return doValidadoRrhh;
}
public void setDoValidadoRrhh(String doValidadoRrhh) {
this.doValidadoRrhh = doValidadoRrhh;
}
public String getDoExtension() {
return doExtension;
}
public void setDoExtension(String doExtension) {
this.doExtension = doExtension;
}
public Character getDoTecnicoDocente() {
return doTecnicoDocente;
}
public void setDoTecnicoDocente(Character doTecnicoDocente) {
this.doTecnicoDocente = doTecnicoDocente;
}
public Date getDoFechaIngreso() {
return doFechaIngreso;
}
public void setDoFechaIngreso(Date doFechaIngreso) {
this.doFechaIngreso = doFechaIngreso;
}
public Date getDoFechaSalida() {
return doFechaSalida;
}
public void setDoFechaSalida(Date doFechaSalida) {
this.doFechaSalida = doFechaSalida;
}
public String getUsuarioApexCrea() {
return usuarioApexCrea;
}
public void setUsuarioApexCrea(String usuarioApexCrea) {
this.usuarioApexCrea = usuarioApexCrea;
}
public String getUsuarioApexActualiza() {
return usuarioApexActualiza;
}
public void setUsuarioApexActualiza(String usuarioApexActualiza) {
this.usuarioApexActualiza = usuarioApexActualiza;
}
public String getDoCorreoPersonal() {
return doCorreoPersonal;
}
public void setDoCorreoPersonal(String doCorreoPersonal) {
this.doCorreoPersonal = doCorreoPersonal;
}
public String getDoEsAdministrativo() {
return doEsAdministrativo;
}
public void setDoEsAdministrativo(String doEsAdministrativo) {
this.doEsAdministrativo = doEsAdministrativo;
}
public BigInteger getDoIdTipoSangre() {
return doIdTipoSangre;
}
public void setDoIdTipoSangre(BigInteger doIdTipoSangre) {
this.doIdTipoSangre = doIdTipoSangre;
}
public BigInteger getDoEquIdRrHh() {
return doEquIdRrHh;
}
public void setDoEquIdRrHh(BigInteger doEquIdRrHh) {
this.doEquIdRrHh = doEquIdRrHh;
}
public String getDoIdentificacionNomina() {
return doIdentificacionNomina;
}
public void setDoIdentificacionNomina(String doIdentificacionNomina) {
this.doIdentificacionNomina = doIdentificacionNomina;
}
public String getDoRepetidoNsga() {
return doRepetidoNsga;
}
public void setDoRepetidoNsga(String doRepetidoNsga) {
this.doRepetidoNsga = doRepetidoNsga;
}
public String getDoObservacionesRepetido() {
return doObservacionesRepetido;
}
public void setDoObservacionesRepetido(String doObservacionesRepetido) {
this.doObservacionesRepetido = doObservacionesRepetido;
}
public BigInteger getDoEquiIdNomina() {
return doEquiIdNomina;
}
public void setDoEquiIdNomina(BigInteger doEquiIdNomina) {
this.doEquiIdNomina = doEquiIdNomina;
}
public BigInteger getDoEquiIdRegistro() {
return doEquiIdRegistro;
}
public void setDoEquiIdRegistro(BigInteger doEquiIdRegistro) {
this.doEquiIdRegistro = doEquiIdRegistro;
}
public BigInteger getDoCantonNacimiento() {
return doCantonNacimiento;
}
public void setDoCantonNacimiento(BigInteger doCantonNacimiento) {
this.doCantonNacimiento = doCantonNacimiento;
}
public BigInteger getDoProvinciaNacimiento() {
return doProvinciaNacimiento;
}
public void setDoProvinciaNacimiento(BigInteger doProvinciaNacimiento) {
this.doProvinciaNacimiento = doProvinciaNacimiento;
}
public BigInteger getDoTipoDiscapacidad() {
return doTipoDiscapacidad;
}
public void setDoTipoDiscapacidad(BigInteger doTipoDiscapacidad) {
this.doTipoDiscapacidad = doTipoDiscapacidad;
}
public BigInteger getDoPorcentajeDiscapacidad() {
return doPorcentajeDiscapacidad;
}
public void setDoPorcentajeDiscapacidad(BigInteger doPorcentajeDiscapacidad) {
this.doPorcentajeDiscapacidad = doPorcentajeDiscapacidad;
}
public String getDoNumeroCarnetConadis() {
return doNumeroCarnetConadis;
}
public void setDoNumeroCarnetConadis(String doNumeroCarnetConadis) {
this.doNumeroCarnetConadis = doNumeroCarnetConadis;
}
public String getDoObservacion() {
return doObservacion;
}
public void setDoObservacion(String doObservacion) {
this.doObservacion = doObservacion;
}
public String getDoIdentificacionNsga() {
return doIdentificacionNsga;
}
public void setDoIdentificacionNsga(String doIdentificacionNsga) {
this.doIdentificacionNsga = doIdentificacionNsga;
}
public Serializable getDoFoto() {
return doFoto;
}
public void setDoFoto(Serializable doFoto) {
this.doFoto = doFoto;
}
public String getDoFotoMimetype() {
return doFotoMimetype;
}
public void setDoFotoMimetype(String doFotoMimetype) {
this.doFotoMimetype = doFotoMimetype;
}
public String getDoFotoFilename() {
return doFotoFilename;
}
public void setDoFotoFilename(String doFotoFilename) {
this.doFotoFilename = doFotoFilename;
}
public Date getDoFotoLastUpdate() {
return doFotoLastUpdate;
}
public void setDoFotoLastUpdate(Date doFotoLastUpdate) {
this.doFotoLastUpdate = doFotoLastUpdate;
}
public BigInteger getDoEquIdNsga3() {
return doEquIdNsga3;
}
public void setDoEquIdNsga3(BigInteger doEquIdNsga3) {
this.doEquIdNsga3 = doEquIdNsga3;
}
public Date getDoFechaInicioAdenda() {
return doFechaInicioAdenda;
}
public void setDoFechaInicioAdenda(Date doFechaInicioAdenda) {
this.doFechaInicioAdenda = doFechaInicioAdenda;
}
public Date getDoFechaFinAdenda() {
return doFechaFinAdenda;
}
public void setDoFechaFinAdenda(Date doFechaFinAdenda) {
this.doFechaFinAdenda = doFechaFinAdenda;
}
public Date getDoFechaValidacionRrhh() {
return doFechaValidacionRrhh;
}
public void setDoFechaValidacionRrhh(Date doFechaValidacionRrhh) {
this.doFechaValidacionRrhh = doFechaValidacionRrhh;
}
@Override
public int hashCode() {
int hash = 0;
hash += (doId != null ? doId.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 TdiDocente)) {
return false;
}
TdiDocente other = (TdiDocente) object;
if ((this.doId == null && other.doId != null) || (this.doId != null && !this.doId.equals(other.doId))) {
return false;
}
return true;
}
@Override
public String toString() {
return "ec.edu.utpl.gestiondatos.tesis.entities.TdiDocente[ doId=" + doId + " ]";
}
}
这是我的存储库
package ec.edu.utpl.gestiondatos.tesis.repositories;
import java.util.List;
import ec.edu.utpl.gestiondatos.tesis.entities.TdiDocente;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
@RepositoryRestResource
public interface TdiDocenteRepository extends CrudRepository<TdiDocente, Long> {
List<TdiDocente> findBydoIdentificacion(@Param("doIdentificacion") String doIdentificacion);
}
最佳答案
您可以使用Pinto将持久化的 beans 转换为 RDF,然后您可以使用 Sesame 的 RIO 框架将其编写为您想要的任何 RDF 序列化,包括 JSON-LD。
免责声明:我是 Pinto 的作者
关于java - 使用 Spring Data Rest 提供 Java 模型的 RDF/XML 和 JSON-LD 表示形式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39156543/
只是想知道这些结构之间有什么区别(text、data、rodata、bss 等)在链接描述文件中: .data : { *(.data) } .data : { *(.data*) }
Data 定义为其核心功能之一 gfoldl : gfoldl :: (Data a) => (forall d b. Data d => c (d -> b) -> d -> c b)
以下之间有什么区别:data-sly-use、data-sly-resource、data-sly-include 和 数据-sly-模板?我正在阅读 Sightly AEM 上的文档,我非常困惑。
我有一个 Spring Boot、Spring Data JPA (hibernate) Web 应用程序,并且想引入文本搜索功能。 我理解以下内容 hibernate search 或 spring
我不知道我的代码有什么问题。我读了其他有同样问题的人的一些问题,但没有找到答案。当我尝试编译时出现以下错误: ||In function 'main':| |35|error: expected ex
我不太确定为什么会收到此错误或其含义。我的数据框称为“数据”。 library(dplyr) data %>% filter(Info==1, Male==1) %>% lm(CFL_
我一直在 GitHub 等更现代的网站上看到这些属性,它们似乎总是与自定义的弹出窗口一致,如 title 属性。 Option 1 Option 2 Option 3 Option 4 我在 HTML
如何用 iCloud Core Data 替换我现有的 Core Data?这是我的持久商店协调员: lazy var persistentStoreCoordinator: NSPersistent
我一直在 GitHub 等更现代的网站上看到这些属性,它们似乎总是与自定义的弹出窗口一致,如 title 属性。 Option 1 Option 2 Option 3 Option 4 我在 HTML
我正在通过 this project 在 Android 上摆弄 node.js ,我需要一种方法将 js 文件部署到私有(private)目录(以隐藏源代码,防止用户篡改),该目录也物理存在于文件系
大家好我有点沮丧,所以我希望得到一些帮助。我的项目在 SwiftUI 中。我想使用图像选择器将图像保存到 Core Data。我实现了让 ImagePicker 工作,但我正在努力转换 Image -
我有以下数据和代码: mydf grp categ condition value 1 A X P 2 2 B X P 5
我一直在努力解决这个问题,但我根本找不到任何解决问题的方法。希望这里有人可以提供帮助。 我正在尝试为具有以下结构的某些数据创建个人选择矩阵: # A tibble: 2,152 x 32 a
我了解 Data.Map.Lazy 和 Data.Map.Strict 是不同的。但是,当您导入 Data.Map 时,您究竟导入了什么:严格的、惰性的还是两者的组合? 最佳答案 懒人。看着docs
我正在开发一个 C 程序,用于从 BerkeleyDB DBTree 数据库中提取数据值与特定模式匹配的记录。我创建数据库,打开它,将键的 DBT 和数据的另一个 DBT 清零,将 DBT 标志设置为
所以我有以下成员(member)历史表 User_ID | Start date | End Date | Type(0-7) | ---------------------------
随着最近推出的包dataframe ,我认为是时候正确地对各种数据结构进行基准测试,并突出每种数据结构的优势。我不是每个人的不同优势的专家,所以我的问题是,我们应该如何对它们进行基准测试。 我尝试过的
我有来自 API 的数据,但无法将数组中的数据设置为 vue.js 中的 this.data这是来自 API 的数据(JSON) 你能告诉我这个语法吗 {"id":1613, "name_org":"
在 Vue.js到目前为止,我已经找到了两种定义数据的方法:data: {} 和 data() { return; }. data: { defaultLayout: 'default' }
我正在研究Spring Data Rest Services,并在自定义拦截器中遇到一些问题。之前我使用spring-data-rest-webmvc 2.2.0并以以下方式添加了拦截器。 publi
我是一名优秀的程序员,十分优秀!