如何在使用Java Spring的Repository Hibernate和Pageable时根据参数进行搜索?

huangapple 未分类评论45阅读模式
英文:

How to do searching with parameters using Repository Hibernate and Pageable with Java Spring?

问题

我刚刚学会如何使用Repository Java进行分页(我有一个MySQL数据库)。我基本上使用DAO与我的模型(pregunta),并将我的模型转换为DTO(preguntaDTO)。

public Page<PreguntaDTO> getAllPreguntasPorPagina(Pageable pageable){
  return preguntaRepository.findAll(pageable).map(PreguntaDTO::fromEntity);
}

我的控制器接收分页参数。

@GetMapping("/listadoPreguntasPaginadas")
public ResponseEntity<Page<PreguntaDTO>> listadoPreguntasPaginadas(
  @RequestParam(defaultValue = "0") int page,
  @RequestParam(defaultValue = "10") int size,
  @RequestParam(defaultValue = "pregunta") String order,
  @RequestParam(defaultValue = "true") boolean asc
) {
  Page<PreguntaDTO> preguntaDTOpaginada = preguntaService.listadoPreguntasPageables(PageRequest.of(page, size, Sort.by(order)));
  return new ResponseEntity<Page<PreguntaDTO>>(preguntaDTOpaginada, HttpStatus.OK);
}

但现在,我需要在我的JQuery中使用参数(文本和ID)。我会尽力更好地解释一下。我的模型是:

@Entity
@Table(name = "preguntas")
@EntityListeners(AuditingEntityListener.class)
@Getter
@Setter
public class Pregunta implements Serializable  {
  // ...(模型定义)
}

我的搜索除了要分页外,还必须返回所有满足以下条件的问题(pregunta):

  • 在字段deEnfermedadById中具有ID(deEnfermedadById: number)
  • 在字段pregunta(类型,pregunta: string)中具有文本(cadena: string)

我知道如何使用Entity Management查找这种类型的列表,但在这里我不知道如何使用分页。您可以看到我如何做到这一点。

public List<Pregunta> listadoPreguntasByIdEnfermedad(Long idEnf, String cadena) {
  // ...(查询实现)
}

正如您所见,我有些困惑。使用Entity Management,我无法进行分页,并且使用Repository Java,我不知道如何在我的分页方法中添加一些参数(id和text)。

谢谢您的帮助。:-)

此外,以下是接口的一些额外信息:

package com.uned.project.sanitaUned.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.uned.project.sanitaUned.model.Pregunta;

@Repository
public interface PreguntaRepository extends JpaRepository<Pregunta, Long> {
}

该接口扩展了:

@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
  // ...
}

而这个接口又扩展了分页:

@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
  // ...
  Page<T> findAll(Pageable pageable);
}

您尝试过:

@Repository
public interface PreguntaRepository extends JpaRepository<Pregunta, Long> {
  @Query("select * from sanihelp.preguntas where de_enfermedad_by_id = :de_enfermedad_by_id") 
  Page<Pregunta> findAllWithFields(Pageable pageable, @Param("de_enfermedad_by_id") long de_enfermedad_by_id);
}

但它没有工作,在服务器启动时出现错误。

英文:

I have just learnt how to do Pageable with Repository Java ( I have a BBDD MySQL) . I basically use DAO with my model (pregunta) and I cast my model to my DTO (preguntaDTO).



public Page&lt;PreguntaDTO&gt; getAllPreguntasPorPagina(Pageable pageable){

  return preguntaRepository.findAll(pageable).map(PreguntaDTO::fromEntity);

}	

My controller receives the parameters for the pagination.


@GetMapping(&quot;/listadoPreguntasPaginadas&quot;)

public ResponseEntity&lt;Page&lt;PreguntaDTO&gt;&gt; listadoPreguntasPaginadas(

  @RequestParam(defaultValue = &quot;0&quot;) int page,

  @RequestParam(defaultValue = &quot;10&quot;) int size,

  @RequestParam(defaultValue = &quot;pregunta&quot;) String order,

  @RequestParam(defaultValue = &quot;true&quot;) boolean asc

  ) {

  Page&lt;PreguntaDTO&gt; preguntaDTOpaginada= preguntaService.listadoPreguntasPageables(PageRequest.of(page, size, Sort.by(order)));

  return new ResponseEntity&lt;Page&lt;PreguntaDTO&gt;&gt;(preguntaDTOpaginada, HttpStatus.OK);

}

But now, I need To use parameters in my JQUERY ( text and id) . I´ll try to explain it better.
My model is:


@Entity

@Table (name=&quot;preguntas&quot;)

@EntityListeners(AuditingEntityListener.class) // sin esto no genera fecha automatica

@Getter

@Setter

public class Pregunta implements Serializable  {

  private static final long serialVersionUID = 5191280932150590610L;

	

  @Id // definimos clave primaria

  @GeneratedValue(strategy=GenerationType.AUTO)  // que se genere de forma automatica y crezca

  private Long id;

	

  @Temporal(TemporalType.TIMESTAMP)

  @LastModifiedDate    

  private  Date createAt;	

	

  @NotBlank // que no este campo en blanco, validar documento

  @NotNull(message = &quot;Nombre no puede ser nulo&quot;)

  private String pregunta;

  private Boolean activa=true;

  private Long deEnfermedadById;//ID de Enfermedad 

  private Long createdById;//ID de usuario 

  private Boolean denunciado=false;	

  private String aux=&quot;Campo auxiliar sin usar&quot;;

}

My search, in addition to be pageable, must return all my questions ( pregunta )that have:

  • in field deEnfermedadById with an id (deEnfermedadById :number) and,
  • of text ( cadena: string) in field pregunta ( type, pregunta :string)

I know how to look for that kind of list with Entity Management, BUT here I don`t know tu use pageable.

above you can see how I did it.


public List&lt;Pregunta&gt; listadoPreguntasByIdEnfermedad(Long idEnf, String cadena) {

  List&lt;Pregunta&gt; lista = new ArrayList&lt;&gt;();

  String sql = &quot;select * from sanihelp.preguntas where &quot;

							+ &quot;de_enfermedad_by_id = ?&quot;;

  if (cadena != null) {

	sql = sql.concat(&quot; and pregunta like ? &quot;);

  };

  try {

	Query query = em.createNativeQuery(sql);

	int indice=1;

	query.setParameter(indice , idEnf);

	if (cadena != null) {

	  query.setParameter(++indice, &quot;%&quot; + cadena + &quot;%&quot;);

	}

	for (Object o : query.getResultList()) {

	  Object[] objeto = (Object[]) o;

	  Pregunta modelo = new Pregunta();	

	  modelo.setId(((BigInteger) objeto[0]).longValue());											    modelo.setActiva(Boolean.getBoolean(String.valueOf(objeto[1])));

	  modelo.setAux(String.valueOf(objeto[2]));

	  modelo.setCreateAt((java.util.Date)objeto[3]);

	  modelo.setCreatedById(((BigInteger) objeto[4]).longValue());

	  modelo.setDeEnfermedadById(((BigInteger) objeto[5]).longValue());						modelo.setDenunciado(Boolean.getBoolean(String.valueOf(objeto[6])));	

	  modelo.setPregunta(String.valueOf(objeto[7]));		

	  lista.add(modelo);

	}

  } catch (Exception e) {

	System.out.println(&quot;excepcion lanzada&quot; + e);

  }

  return lista;

}

How you can see, I am a bit Stuck. With Entity Management I cannot do pagination and with Repository Java I don´t know how to add to my pageable method some parameters ( id and text )

Thank you for your help.

如何在使用Java Spring的Repository Hibernate和Pageable时根据参数进行搜索?

Above some extra information of the interface .


package com.uned.project.sanitaUned.repository;



import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.stereotype.Repository;



import com.uned.project.sanitaUned.model.Pregunta;



@Repository

public interface PreguntaRepository extends JpaRepository&lt;Pregunta, Long&gt; {



}

that extends of :


 */

@NoRepositoryBean

public interface JpaRepository&lt;T, ID&gt; extends PagingAndSortingRepository&lt;T, ID&gt;, QueryByExampleExecutor&lt;T&gt; {



and that extends of pageable


@NoRepositoryBean

public interface PagingAndSortingRepository&lt;T, ID&gt; extends CrudRepository&lt;T, ID&gt; {



	/**

	 * Returns all entities sorted by the given options.

	 *

	 * @param sort

	 * @return all entities sorted by the given options

	 */

	Iterable&lt;T&gt; findAll(Sort sort);



	/**

	 * Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object.

	 *

	 * @param pageable

	 * @return a page of entities

	 */

	Page&lt;T&gt; findAll(Pageable pageable);

}

I tried to do :




@Repository

public interface PreguntaRepository extends JpaRepository&lt;Pregunta, Long&gt; {

	

/*  */ 

	

	 @Query (&quot;select * from sanihelp.preguntas where de_enfermedad_by_id = :de_enfermedad_by_id&quot;) 

	 Page &lt;Pregunta&gt; findAllWithFields(Pageable pageable , @Param (&quot;de_enfermedad_by_id&quot;)  long de_enfermedad_by_id );

	

}

But it didn't work, it failed in the server when I started with the next error.




Error starting ApplicationContext. To display the conditions report re-run your application with &#39;debug&#39; enabled.

2020-04-07 18:16:44.091 ERROR 8424 --- [  restartedMain] o.s.boot.SpringApplication               : Application run failed



org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name &#39;preguntaController&#39;: Unsatisfied dependency expressed through field &#39;preguntaService&#39;; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name &#39;preguntaService&#39;: Unsatisfied dependency expressed through field &#39;preguntaDAO&#39;; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name &#39;preguntaDAO&#39;: Unsatisfied dependency expressed through field &#39;preguntaRepository&#39;; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name &#39;preguntaRepository&#39;: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract org.springframework.data.domain.Page com.uned.project.sanitaUned.repository.PreguntaRepository.findAllWithFields(org.springframework.data.domain.Pageable,long)!

	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]

	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]

	

答案1

得分: 0

朋友Agustín Lidon Martinez给我答案。谢谢。

@Repository
public interface PreguntaRepository extends JpaRepository<Pregunta, Long> {

	@Query("SELECT p FROM Pregunta p WHERE p.deEnfermedadById = :de_enfermedad_by_id")
	Page<Pregunta> findAllWithFieldsContaining(Pageable pageable, @Param("de_enfermedad_by_id") Long de_enfermedad_by_id);
}

我之前不知道在使用HQL时与SQL不同。你必须使用模型Pregunta,而不是表sanihelp.preguntas的名称,这是我一直在做的。谢谢。

工作正常:

1)我的控制器。

@GetMapping("/listadoPreguntasPaginadasConIdEnfermedad")
public ResponseEntity<Page<PreguntaDTO>> listadoPreguntasPaginadasConIdEnfermedad(
        @RequestParam(defaultValue = "0") int page,
        @RequestParam(defaultValue = "10") int size,
        @RequestParam(defaultValue = "pregunta") String order,
        @RequestParam(defaultValue = "true") boolean asc,
        @RequestParam(defaultValue = "") Long idEnfermedad
) {
    Page<PreguntaDTO> preguntaDTOpaginada = preguntaService.listadoPreguntasPaginadasConIdEnfermedad(
            PageRequest.of(page, size, Sort.by(order)), idEnfermedad);
    return new ResponseEntity<Page<PreguntaDTO>>(preguntaDTOpaginada, HttpStatus.OK);
}

我的服务:

@Override
public Page<PreguntaDTO> listadoPreguntasPaginadasConIdEnfermedad(Pageable pageable, Long idEnfe) {
    return preguntaDAO.getAllPreguntasPorPaginaYCampos(pageable, idEnfe);
}

我的DAO:

/* 获取带有分页和字段映射的所有问题列表 */
public Page<PreguntaDTO> getAllPreguntasPorPaginaYCampos(Pageable pageable, Long enfermedad){
    return preguntaRepository.findAllWithFieldsContaining(pageable, enfermedad).map(PreguntaDTO::fromEntity);
}

你的问题中还有更多需要的类。再次感谢。

我在我的PreguntaRepository中使用了这个:

@Query("SELECT p FROM Pregunta p WHERE p.deEnfermedadById = :de_enfermedad_by_id and p.pregunta LIKE %:texto%")
Page<Pregunta> findAllWithFieldsContaining(Pageable pageable, Long de_enfermedad_by_id, String texto);

没有使用@Param("de_enfermedad_by_id")@Param("texto"),同样可以工作。

英文:

my friend Agustín Lidon Martinez give me the answer. Thank you.


@Repository
public interface PreguntaRepository extends JpaRepository&lt;Pregunta, Long&gt; {
	
	 @Query (&quot;SELECT p FROM Pregunta p WHERE p.deEnfermedadById = :de_enfermedad_by_id&quot;) 
	 Page &lt;Pregunta&gt; findAllWithFieldsContaining ( Pageable pageable, @Param (&quot;de_enfermedad_by_id&quot;)   Long   de_enfermedad_by_id  );  
}

I didn`t know that when you use HQL is not the same as SQL . You must use the model Pregunta and not the name of the table sanihelp.preguntas how I was doing all the time . Thank you.

Working ok:

  1. my controller.

	@GetMapping(&quot;/listadoPreguntasPaginadasConIdEnfermedad&quot;)
	public ResponseEntity&lt;Page&lt;PreguntaDTO&gt;&gt; listadoPreguntasPaginadasConIdEnfermedad(
			@RequestParam(defaultValue = &quot;0&quot;) int page,
            @RequestParam(defaultValue = &quot;10&quot;) int size,
            @RequestParam(defaultValue = &quot;pregunta&quot;) String order,
            @RequestParam(defaultValue = &quot;true&quot;) boolean asc,
            @RequestParam(defaultValue = &quot;&quot;) Long idEnfermedad
			) {
		    Page&lt;PreguntaDTO&gt; preguntaDTOpaginada= preguntaService.listadoPreguntasPaginadasConIdEnfermedad(
		    	                                   PageRequest.of(page, size, Sort.by(order)), idEnfermedad);
			
		    return new ResponseEntity&lt;Page&lt;PreguntaDTO&gt;&gt;(preguntaDTOpaginada, HttpStatus.OK);
	}

my service :

	@Override
	public Page&lt;PreguntaDTO&gt; listadoPreguntasPaginadasConIdEnfermedad (Pageable pageable, Long idEnfe) {
		return preguntaDAO.getAllPreguntasPorPaginaYCampos(pageable, idEnfe);
	}

mi DAO:

	/* obtener lista de todas las preguntas tabla PAGEABLE con mapeo incluido de page  y campos 		*/
				public Page&lt;PreguntaDTO&gt; getAllPreguntasPorPaginaYCampos (Pageable pageable, Long enfermedad){
					return preguntaRepository.findAllWithFieldsContaining(pageable, enfermedad).map(PreguntaDTO::fromEntity);
				}	

you have in my question more classes you need. Thanks again

I have used in my PreguntaRepository this:

@Query (&quot;SELECT p FROM Pregunta p WHERE p.deEnfermedadById = :de_enfermedad_by_id and p.pregunta LIKE %:texto%&quot;) 
	 Page &lt;Pregunta&gt; findAllWithFieldsContaining ( Pageable pageable,  Long   de_enfermedad_by_id,  String texto  );  
}

without
@Param (&quot;de_enfermedad_by_id&quot;) @Param (&quot;texto&quot;) and works as well.

huangapple
  • 本文由 发表于 2020年4月5日 23:17:24
  • 转载请务必保留本文链接:https://java.coder-hub.com/61044831.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定