Ele usa o Spring Data JPA há um tempo. Durante esse período, aprendi algumas coisas e encontrei alguns problemas. Vou compartilhá -los com você aqui.
Prefácio:
Introdução aos dados da primavera:
Os dados do Spring são uma estrutura de código aberto para simplificar o acesso ao banco de dados e suportar serviços em nuvem. Seu principal objetivo é fazer o acesso a dados convenientes e rápidos e apoiar os serviços de dados da estrutura e de computação em nuvem. Os dados da mola contêm vários subprojetos:
Commons - Fornece uma estrutura básica compartilhada adequada para uso em cada subprojeto e suporta persistência de dados entre dados cruzados
JPA - simplifica a capacidade de criar camadas de acesso a dados JPA e camadas de persistência em todo o armazenamento
Hadoop - MapReduce Job com base na configuração de emprego do Spring Hadoop e em um modelo de programação POJO
Valor -chave - integra redis e riak para fornecer embalagens simples em vários cenários comuns
Documento - Integrem bancos de dados de documentos: CouchDB e MongoDB e fornecem mapeamento básico de configuração e suporte à biblioteca
Gráfico - Neo4J integrado para fornecer um poderoso modelo de programação baseado em Pojo
Gráfico Roo Addon - ROO Suporte para neo4j
Extensões JDBC - suporta Oracle Rad, filas avançadas e tipos de dados avançados
Mapping - Framework de mapeamento de objetos fornecido com base em graals, suportando diferentes bancos de dados
Exemplos - Programas de amostra, documentos e bancos de dados de gráficos
Orientação - documentação avançada
1. Introdução ao Spring Data JPA
O Spring Data JPA é uma estrutura de aplicativo JPA encapsulada por mola com base nas especificações da estrutura ORM e JPA e fornece um conjunto completo de soluções de camada de acesso a dados.
2. Funções JPA de dados de primavera
Os dados da primavera JPA têm funções muito poderosas. Aqui, ignoramos a etapa de construção do ambiente e damos uma olhada na "doçura" do JPA de dados da primavera.
Spring Data JPA fornece aos usuários as seguintes interfaces:
3. Interface JPA de dados de mola
1. Interface Crudrepository
Crie uma classe de entidade:
@Entity @Table (name = "user") public class Usuário {@id @generatedValue ID inteiro privado; // Conta da conta de string privada; // Nome do nome da string privada; // senha de senha privada string senha; // email email de string privada; } Escreva uma interface e herde a interface Crudrepository:
interface pública UserRepository estende Crudrepository <Usuário, Integer> {} Escreva uma classe de teste (para ver o efeito de maneira mais intuitiva, todas as classes de teste não usam afirmações e imprimem declarações usadas diretamente):
classe pública userRepositoryTest {@aUTowired private userRepository dao; @Test // salvar public void testSave () {user user = new user (); user.setName ("chhliu"); user.setAccount ("10000"); user.setEmail ("[email protected]"); user.setPassword ("123456"); Dao.Save (usuário); } @Test // salve o public void testSave1 () {list <suser> users = new ArrayList <suser> (); Usuário do usuário = novo usuário (); user.setName ("Tanjie"); user.setAccount ("10000"); user.setEmail ("[email protected]"); user.setPassword ("123456"); usuários.add (usuário); usuário = novo usuário (); user.setName ("Esdong"); user.setAccount ("10000"); user.setEmail ("[email protected]"); user.setPassword ("123456"); usuários.add (usuário); usuário = novo usuário (); user.setName ("Qinhongfei"); user.setAccount ("10000"); user.setEmail ("[email protected]"); user.setPassword ("123456"); usuários.add (usuário); usuário = novo usuário (); user.setName ("huizhang"); user.setAccount ("10000"); user.setEmail ("[email protected]"); user.setPassword ("123456"); usuários.add (usuário); usuário = novo usuário (); user.setName ("Caican"); user.setAccount ("10000"); user.setEmail ("[email protected]"); user.setPassword ("123456"); usuários.add (usuário); Dao.save (usuários); } @Test // atualize public void testUpDate () {user user = dao.findone (1); user.setPassword ("123890"); // Para implementar a função de atualização dessa maneira, você precisa adicionar @Transaction Thing Anotation à camada de serviço} @test // excluir public void testDelete () {dao.delete (2); } @Test // Query todos os public void testFindall () {list <suser> users = (list <suser>) dao.findall (); System.out.println (json.tojSonstring (usuários)); } @Teste // Consulta se o objeto ID especificado existe public void testisexist () {boolean isexist = dao.exists (8); System.out.println (isExist); } @Test // Query public void testFindUserByIds () {list <Teger> listids = new ArrayList <Teger> (); listids.add (2); listids.add (4); listids.add (7); List <suser> usuários = (list <suser>) dao.findall (listids); System.out.println (json.tojSonstring (usuários)); }} Como você pode ver, neste momento, escrevi apenas uma classe de interface e não implementei essa classe de interface, para que eu pudesse concluir a operação básica do CRUD. Como essa interface criará automaticamente métodos para adicionar, excluir, modificar e pesquisar objetos de domínio, para uso direto da camada de negócios.
A interface é definida da seguinte forma e são fornecidos 11 métodos, que podem basicamente atender a operações simples de CRUD e operações em lote:
@Norepositorybean interface pública crudrepositório <t, id estende serializável> estende o repositório <t, id> {<s estende t> s salvar (s entidade); // salvar <s estende t> itererable <s> salve (itererable <s> entidades); // batch savona (idist); Iterable <t> findall (); // consulta todos os objetos iterable <t> findAll (iterable <d> ids); // consulte todos os objetos com base na lista de identificação long count (); // calcular o número total de objetos void Delete (Id Id); // Delete void (t entidade); DeLeTeall (); // Excluir tudo} 2. Interface PagingAndSortingRepository
A interface PagingAndSortingRepository herda a interface CrudReposition.
Escreva interfaces e herança de pagingAndSortingRepository Interface
interface pública userRepositorywithorder estende PagingAndSortingRepository <Usuário, Integer> {} Escreva aulas de teste:
@Runwith (springjunit4classrunner.class) @ContextConfiguration (Localizações = {"ClassPath: ApplicationContext-Config.xml"}) @TransactionConfiguration (Defaultrollback = false) @Transaction Public Class UserRepositoryWithOrderTest {AATROLLBOWIRD) @Transaction Public Class UserRepositoryWitherTest {AAUTOWIRD) @Test public void testOrdorMer () {classy Sort = new Sort (direção.desc, "id"); Pagável pagável = novo pagerequest (0, 5, classificação); Página <suser> página = dao.findall (pagável); System.out.println (json.tojSonstring (página)); System.out.println (Page.getSize ()); }} Enquanto você herdar essa interface, o Spring Data JPA já fornecerá as funções de paginação e classificação. A interface é definida da seguinte
@NorepositoryBean Public Interface PagingAndSortingRepository <t, ID estende serializável> estende Crudrepository <t, id> {iterable <t> findAll (classificar); // classificar sem página <t> findall (pagável pagável); // Classificar com Paging} 3. Interface jparepository
Se a empresa precisar fornecer operações CRUD e também fornecer funções de paginação e classificação, você poderá herdar diretamente essa interface. Essa interface herda a interface PagingAndSortingRepository.
A interface é definida da seguinte forma:
interface pública jParepository <t, id estende serializável> estende o pagingAndSortingRepository <t, id> {list <t> findAllAll (); // consulte todos os objetos, não classifique a lista <T> findAll (sort); // consulte todos os objetos e classifica <s estends trez sincroniza com o banco de dados T SaveAndflush (entidade T); // Salvar e forçar sincronizar o void DeleteInbatch (entidades Iterable <T>); // lote Delete void DeLeTeallinBatch (); // excluir tudo} 4. Interface jPaspecificationExecutor
Esta interface fornece suporte para consultas de critérios JPA. Observe que essa interface é muito especial e não pertence ao sistema de repositório. Os dados da primavera JPA não digitalizarão e reconhecem automaticamente, portanto o feijão correspondente não será encontrado. Precisamos herdar apenas qualquer sub-interface que herde o repositório ou herde diretamente a interface do repositório. O Spring Data JPA digitalizará automaticamente e reconhecerá e executará o gerenciamento unificado.
A interface está escrita da seguinte forma:
Public Interface SpecificationExecutorRepository estende Crudrepository <Usuário, Integer>, JPasPecificationExecutor <sufers> {} Classe de serviço:
@Service Public Class SpecificationExecutorRepositoryManager {@AUTOWIRED SPECIFICAÇÃO PRIVADA DEEXECONDORREPOSIÍDIO DAO; / *** Descrição: Consulta o usuário com base no nome*/ public User FindUserByName (Nome da String final) {return Dao.findone (nova especificação <suser> () {@Override public predicado topredicate (root <suser> root, CriteriaQuery <?> Consulta, CriteriaberererererererererererDer (Predicate); }); } / *** Descrição: Consulte o usuário com base no nome e email* / public user findUserByNameAndemail (nome final da string, email final da string) {return Dao.findone (new Specification <suser> () {@Override Public Prediced Cb) (Princima <ROOT> ROOT, PREDERIAQUERIA <?> Predict1 = CB.Equal (ROOT.GENS (Nome "), Nome); } / *** Descrição: consulta combinada* / public User FindUserByUser (Usuário final Uservo) {return Dao.findone (new Specification <suser> () {@Override public Prediced Topredicate (root <suser> root, CriteriaQuery <?> Consulta, CriterAbererererererererererererDer (Predicating), Predict (Predict (CriterIAQuery <?> Consulta, RetiABererererererererererererDer (Predicating), previsto (Predict (CriteriaQuery <?>, Consulta, rootiAbuerDer (Predict), previsto (previsto, previsto (limite) (limite de critério (root> root) (limite de critério "). cb.and (predicado, cb.equal (root.get ("email"), uservo.getpassword ()); } / *** Descrição: Consulta de intervalo no método, como consultar o usuário com ID do usuário em [2,10]* / list public <suser> findUserByIds (Lista final <Teger> Ids) {return Dao.findall (new specification <suser> () {@Override public Predicicate (root <suser> root, carrinha <suser> () {@Override public Topredicate (root <suser>, carrinho, ROTRIATERIAQUERIA: root.in (IDS); } / *** Descrição: Método GT GT GT, como consultar todos os usuários com ID do usuário superior a 9* / list public <suser> findUserBygtid (final int id) {return Dao.findall (nova especificação <suser> () {@Override public Prediced Topredicate (raiz> raiz, raiz, «Criteriaquery <? cb.gt (root.get ("id"). AS (Integer.class), id); } / *** Descrição: Método de consulta de gama LT, como consultar usuários com ID de usuário menor que 10* / list public <suser> findUserByLtid (final int id) {return Dao.findall (nova especificação <usery> () {@Override Public Predicate Topredicate (raiz> raiz, raiz, raiz, raiz, raiz <?> cb.lt (root.get ("id"). AS (Integer.class), id); } / *** Descrição: Consulta de intervalo entre métodos, como consultar usuários com IDs entre 3 e 10* / Lista pública <suser> findUserbetweenId (final int start, final int end) {return Dao.findall (nova especificação <) () {@Override public Predicate (root> root> root, critria cb.Between (root.get ("id"). como (inteiro.class), start, fim); } / *** Descrição: Operações de classificação e paginação* / página pública <suser> findUserrandorder (final int id) {classy sort = new Sort (direction.desc, "id"); Return Dao.findall (nova especificação <suser> () {@Override public Predicate Topredicate (root <sUsar> root, critério de consulta <?>, critério Criteriabilercing cb) {return cb.gt (root.get ("id"). como (integger.class), id);}}, newest (0 "). } / *** Descrição: apenas operações de classificação* / public list <suser> findUserAndorderSecondMethod (final int id) {return Dao.findall (nova especificação <suser> () {@Override Public predicado ToPredicate (raiz <suser> root, critério <?> Query, critriabilder CB) {<suser> root, critério <?> cb.gt (root.get ("id"). }} Classe de teste:
@Runwith (springjunit4classrunner.class) @ContextConfiguration (locations = {"ClassPath: ApplicationContext-Config.xml"}) @TransactionConfiguration (DefaulTrollback = false) @Transaction Public Specification; @Test public void testFindUserByName () {User user = gerente.findUserByName ("chhliu"); System.out.println (json.tojSonstring (usuário)); } @Test public void testFindUSERBYNAMEANDEMAIL () {Usuário Usuário = Gerenciador.FindUSERBYNAMEANDEMAIL ("CHHLIU", "CHHLIU @.COM"); System.out.println (json.tojSonstring (usuário)); } @Test public void testFindUSERBYUSVO () {Usuário do usuário = new User (); user.setName ("chhliu"); user.setEmail ("[email protected]"); Usuário u = gerente.finduserByUser (usuário); System.out.println (json.tojSonstring (u)); } @Test public void testFindUSERBYIDS () {list <suser> users = gerente.findUSERBYIDS (novo ArrayList <Teger> (Arrays.asList (1,3,5,6))); System.out.println (json.tojSonstring (usuários)); } @Test public void testFindUSERBYGTID () {LIST <usery> users = gerenciador.findUSERBYGTID (5); System.out.println (json.tojSonstring (usuários)); } @Test public void testFindUSERBYLTID () {list <suser> usuários = gerenciador.findUSERBYLTID (5); System.out.println (json.tojSonstring (usuários)); } @Test public void testFindUserBeenId () {list <suser> users = gerente.findUserBeenId (4, 9); System.out.println (json.tojSonstring (usuários)); } @Test public void testFindUserRordOrder () {página <suser> usuários = gerenciador.finduserrandorder (1); System.out.println (json.tojSonstring (usuários)); } @Test public void testFindUserAndorderSeCondMethod () {list <suser> users = gerente.findUserAndorderSeCondMethod (1); System.out.println (json.tojSonstring (usuários)); }} 5. Interface do repositório
Essa interface é a interface mais básica, é apenas uma interface icônica e nenhum método é definido, então qual é o uso dessa interface? Como o Spring Data JPA fornece essa interface, é claro que é útil. Por exemplo, alguns métodos que não queremos fornecer externamente. Por exemplo, queremos apenas fornecer métodos de adição e modificação e não métodos de exclusão, as interfaces anteriores não podem fazê -lo. Neste momento, podemos herdar essa interface e copiar os métodos correspondentes na interface Crudrepositório para a interface do repositório.
Resumo: Como os desenvolvedores devem escolher as cinco interfaces acima? De fato, a base é muito simples. Escolha um deles de acordo com as necessidades de negócios específicas. Porque não há problema de força e força entre cada interface.
4. Spring Data JPA Consulta
1. Crie uma consulta usando @Query
O uso da anotação @Query é muito simples. Você só precisa rotular a anotação no método declarado e fornecer uma declaração de consulta JP QL. Muitos desenvolvedores gostam de usar parâmetros nomeados em vez de números de posição ao criar o JP QL, e o @Query também fornece suporte para isso. Na instrução JP QL, os parâmetros são especificados através do formato de ": variável" e, ao mesmo tempo, o @param é usado na frente dos parâmetros do método para corresponder aos parâmetros nomeados no JP QL. Além disso, os desenvolvedores também podem executar uma operação de atualização usando @Query. Para fazer isso, precisamos usar o @modifying para identificar a operação como uma consulta modificada enquanto estiver usando o @Query, para que a estrutura eventualmente gerem uma operação atualizada, não uma operação de consulta.
Escreva uma interface da seguinte maneira:
/*** Descrição: Consulta personalizada. Quando o Spring Data JPA não pode fornecer, é necessária uma interface personalizada. Este método pode ser usado neste momento*/ interface pública UserDefineBySelf estende JParepository <Usuário, Integer> {/ *** Parâmetros nomeados* Descrição: Recomenda -se usar esse método, você pode ignorar o local do local do local; /*** Parâmetros de índice* Descrição: Use? espaço reservado*/ @Query ("Selecione U no usuário u onde u.Email =? 1") // 1 Indica o primeiro parâmetro do usuário findUserByEmail (string email); /*** Descrição: as atualizações podem ser alcançadas por meio de @modifying e @Query* Nota: O valor de retorno da modificação de consultas só pode ser vazio ou int/inteiro*/@modifying @Query ("Atualize o usuário u Definir u.name =: nome onde u.id =: id") int updateIrbyId (@Param ("Nome") String, String, } Nota: @modifying Anotation tem uma configuração ClearAutomaticaticamente
Diz que o contexto de persistência subjacente pode ser limpo, que é a classe EntityManager. Sabemos que a implementação subjacente do JPA terá um cache secundário, ou seja, depois de atualizar o banco de dados, se você usar esse objeto posteriormente, verificará o objeto. Este objeto é armazenado em cache no primeiro nível, mas não é sincronizado com o banco de dados. Neste momento, ClearAutomaticaticamente = true será usado para atualizar o cache do primeiro nível de Hibernate. Caso contrário, você atualizará um objeto na mesma interface e, em seguida, consultará esse objeto, o objeto que você encontrou ainda é o estado anterior que não havia sido atualizado antes.
Classe de teste:
@Runwith (springjunit4classrunner.class) @ContextConfiguration (Localizações = {"ClassPath: ApplicationContext-Config.xml"}) @TransactionConfiguration (DefaulTrollback = false) @Transaction Public class UservieFineLeLeLeeld; @Test public void testFindUserByName () {User user = dao.findUserByName ("chhliu"); Assert.asserTequals ("chhliu", user.getName ()); System.out.println (user.getName ()); } @Test public void testFindUSERBYEMAIL () {Usuário do usuário = dao.findUserByEmail ("chhliu @.com"); Assert.asserTequals ("chhliu", user.getName ()); System.out.println (user.getName ()); } @Test public void testUpDateUserById () {Dao.UpDateUserById ("Tanjie", 4); }} No código de teste, podemos ver que definimos apenas a interface, sem nenhuma classe de implementação, mas implementamos as funções de que precisamos.
2. Crie uma consulta usando @NamedQueries
O nomeado consulta é uma função fornecida pela JPA que separa as declarações de consulta do corpo do método para compartilhar vários métodos. O Spring Data JPA também fornece um bom suporte para consultas nomeadas. Os usuários precisam definir apenas a instrução de consulta no arquivo Orm.xml ou no código de acordo com a especificação JPA. A única coisa que eles precisam fazer é atender às regras de nomenclatura de "DomainClass.methodName ()" ao nomear a declaração.
Escrevendo uma interface:
interface pública findUserByNamedQuerRepository estende jparepository <usuário, número inteiro> {user findUserwithName (@param ("name") nome da string); } Escrevendo uma aula:
@Entity @NamedQuery (Value = {@NamedQuery (name = "user.findUserwithname", query = "Selecione U FROM Usuário u WHERE U.Name =: Nome")}) // Nota: Se houver vários métodos aqui, você precisará usar @NamedQuery. Se houver apenas um método, você poderá usar @NamedQuery. O método de escrita é o seguinte: @NamedQuery (name = "user.findUserwithname", query = "selecione u do usuário u where un nome =: name") public class FinduSerByNamedQuery { / *** Nota: Esta classe de entidade deve ser definida aqui, caso contrário, uma exceção será relatada* / @id @GenerAratedValue Integer Intriveger deve ser definido aqui, caso contrário, uma exceção será relatada* / @id @GenerAratedValue Integer; } Nota: As peças marcadas em vermelho no artigo precisam corresponder uma a uma, caso contrário, elas não atenderão às especificações da JPA.
Classe de teste:
@Runwith (springjunit4classrunner.class) @ContextConfiguration (locations = {"ClassPath: ApplicationContext-Config.xml"}) @TransactionConfiguration (DefaulTrollback = False) @Transaction public Class FindUnedEdEnEdEdEnDeRByEnDeSetMerPesterTrollback = false) @Test public void testFindUserByName () {Usuário User = dao.findUserwithName ("caican"); System.out.println (json.tojSonstring (usuário)); }} 3. Crie uma consulta analisando o nome do método
Como o nome sugere, é criar uma consulta com base no nome do método. Talvez pareça incrível no começo, mas após o teste, descobri que tudo é possível.
Escrevendo uma interface:
Interface pública SimpleConditionQueryRepository estende JParepository <Usuário, Integer> { /*** Descrição: De acordo com as regras definidas pelos dados da mola, o método de consulta começa com Find | Leia | Obtenha* Quando se trata de consulta condicional, as propriedades da condição são conectadas com palavras -chave condicionais. It should be noted that: the first letter of the conditional attribute must be uppercase*/ /** * Note: This interface here is equivalent to sending a SQL:select u from User u where u.name = :name and u.email = :email * Parameter name is uppercase, the initial letter of the conditional name is uppercase, and the order of parameters in the interface name must be the same as the order of the parameters in the parameter Lista*/ Usuário FindByNameAndemail (Nome da String, String email); / ** * NOTA: Esta interface aqui é equivalente ao envio de um SQL: selecione U FROM Usuário u onde u.name =? 1 ou u.password =? 2 */ list <suser> findByNameRorpassword (nome da string, senha da string); / ** * NOTA: Esta interface aqui é equivalente a enviar um SQL: selecione U FROM Usuário u Onde U.Id entre? 1 e? 2 */ list <suser> findByIdBetween (Início do número inteiro, fim inteiro); / ** * NOTA: Esta interface aqui é equivalente a enviar um SQL: selecione U FROM Usuário u Onde U.Id entre? 1 e? 2 */ list <suser> findByIdBetween (Início do número inteiro, fim inteiro); / ** * NOTA: Esta interface aqui é equivalente ao envio de um SQL: selecione U FROM Usuário u onde U.id <? 1 */ list <suser> findByIdlessThan (final inteiro); / ** * NOTA: Esta interface aqui é equivalente ao envio de um SQL: selecione U FROM Usuário u onde U.Id>? 1 */ List <USUSE> findByIdGreaterthan (Início do número inteiro); / ** * NOTA: Esta interface aqui é equivalente ao envio de um SQL: selecione U no usuário u, onde o U.Name é nulo */ list <suser> findByNameisNull (); / ** * NOTA: Esta interface aqui é equivalente ao envio de um SQL: selecione U FROM UUSER U WHERE UNHE NOME não é NULL */ LIST <usery> findByNameisNull (); / ** * NOTA: Esta interface aqui é equivalente a enviar um SQL: selecione U no usuário u where U.Nome como? / ** * NOTA: Esta interface aqui é equivalente a enviar um SQL: selecione U FROM Usuário u onde o UN não é como? 1 */ list <suser> findByNameNot Like (Nome da String); / ** * NOTA: Esta interface aqui é equivalente ao envio de um SQL: selecione U FROM Usuário u WHERE U.Password =? 1 Ordem por U.Id Desc */ List <Ususer> findByPassWordOrderByIdDesc (senha da String); / ** * NOTA: Esta interface aqui é equivalente ao envio de um SQL: Selecione U no usuário u onde o UNNE <>? 1 */ list <suser> findByNameNot (Nome da String); / ** * NOTA: Esta interface aqui é equivalente ao envio de um SQL: selecione U FROM Usuário u onde U.Id em? 1 */ list <suser> findByidin (List <Teger> IDs); / ** * NOTA: Esta interface aqui é equivalente ao envio de um SQL: selecione U FROM Usuário u onde U.Id não está em? 1 */ list <suser> findByidNotin (List <Teger> IDs); } Classe de teste (a parte do comentário é a instrução SQL enviada real):
@Runwith (springjunit4classrunner.class) @ContextConfiguration (Localizações = {"ClassPath: ApplicationContext-Config.xml"}) @TransactionConfiguration (DeFaulTrollback = False) @Transaction Public Class SimpleConditionEsterPoSerPositoryTestestestrower) /*** Selecione User0_.id como ID0_, User0_.Account AS Account0_, User0_.Email como email0_, user0_.name como name0_, user0_.password como senha0_ do usuário user0_ where user0_.name =? e user0_.email =? limite? */ @Test public void testFindUSERBYNAMEANDEMAIL () {Usuário do usuário = dao.findbynameAndemail ("chhliu", "chhliu @.com"); System.out.println (json.tojSonstring (usuário)); } /*** Selecione User0_.id como ID1_, User0_.Account AS Account1_, User0_.Email como email1_, user0_.name como nome1_, user0_.password como senha1_ do usuário user0_ where user0_.name =? ou user0_.password =? */ @Test public void testFindUSERBYNAMEPASSWORD () {LIST <suser> usuários = dao.findbyNamePassword ("chhliu", "123456"); System.out.println (json.tojSonstring (usuários)); } /*** Selecione User0_.id como id1_, user0_.AccOut As Account1_, User0_.Email como email1_, user0_.name como nome1_, user0_.password como senha1_ do usuário user0_ where user0_.id entre? e ? */ @Test public void testFindbyIdBetween () {list <usery> users = dao.findbyidbetween (5, 8); System.out.println (json.tojSonstring (usuários)); } /*** Selecione User0_.id como id1_, user0_.Account como conta1_, user0_.Email como email1_, user0_.name como nome1_, user0_.password como senha1_ do usuário user0_ where user0_.id <? */ @Test public void testFindbyIdlessthan () {list <suser> usuários = dao.findbyidlessthan (4); System.out.println (json.tojSonstring (usuários)); } /*** Selecione User0_.id como ID0_, User0_.Account AS Account0_, User0_.Email como email0_, user0_.name como name0_, user0_.password AS Password0_ do usuário user0_ where user0_.id>? */ @Test public void testFindByIdGreaterThan () {list <suser> usuários = dao.findbyidGreaterthan (6); System.out.println (json.tojSonstring (usuários)); } / ** * Selecione User0_.id como ID0_, User0_.AccOut AS Account0_, User0_.Email como email0_, user0_.name como name0_, user0_.password como senha 0_ do usuário useriSnull (User0_.name é null * / @@Test public void TestFindByNull () {NURERSUSUSTEMUSTERSNUSTIMIN (UsersnUrtIsnUrtIsnin ( @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @) System.out.println (json.tojSonstring (usuários)); } / ** * Selecione User0_.id como ID1_, User0_.Account AS Account1_, User0_.Email como email1_, user0_.name como name1_, user0_.password como senha1_ do usuário user0_ () usersnOll () não é null * / @Test Public Void testfindnameSnotnull () @) / @Test lister public void test Findbynotnotnull () (@test lister) Dao.findbyNameisNotNull (); System.out.println (json.tojSonstring (usuários)); } /*** Selecione User0_.id como id1_, user0_.Account como conta1_, user0_.Email como email1_, user0_.name como nome1_, user0_password como senha1_ do usuário user0_ where user0_.name goste? */ @Test public void testFindByNeRike () {list <usery> usuários = dao.findbyNamelike ("chhliu"); System.out.println (json.tojSonstring (usuários)); } /*** Selecione User0_.id como ID0_, User0_.Account AS Account0_, User0_.Email como email0_, user0_.name como name0_, user0_.password como senha0_ do usuário user0_ onde user0_.name não gosta? */ @Test public void testFindByNameNotLike () {list <suser> usuários = dao.findbynamenotlike ("chhliu"); System.out.println (json.tojSonstring (usuários)); } /*** Selecione User0_.id como ID0_, User0_.Account AS Account0_, User0_.Email como email0_, user0_.name como name0_, user0_.password AS Password0_ do usuário user0_ where user0_.password =? encomendar por user0_.id desc */ @test public void testFindBypSswordOrderByIdDesc () {list <suser> usuários = dao.findbypasswordOrderByIdDesc ("123456"); System.out.println (json.tojSonstring (usuários)); } /*** Selecione User0_.id como id1_, user0_.AccOut As Account1_, User0_.Email como email1_, user0_.name como nome1_, user0_.password como senha1_ do usuário user0_ where user0_.name <>? */ @Test public void testFindByNameNot () {list <usery> users = dao.findbynamenot ("chhliu"); System.out.println (json.tojSonstring (usuários)); } / ** * Selecione User0_.id como ID1_, User0_.AccOut como conta1_, user0_.Email como email1_, user0_.name como name1_, user0_.password como senha1_ do usuário user0_ where user0_.id em (?,?,? Lister? ArrayList <Teger> (Arrays.asList (3,4,6,8))); System.out.println (json.tojSonstring (usuários)); } / ** * Selecione User0_.id como ID0_, User0_.AccOut AS Account0_, User0_.Email como email0_, user0_.name como name0_, user0_.password como senha 0_ do usuário user0_ where user0_.id não em (?,?,?) * / @Test Public Void Testfindnyntnotyr0_.id não Dao.findbyidnotin (novo ArrayList <Teger> (Arrays.asList (3, 4, 6, 8))); System.out.println (json.tojSonstring (usuários)); }} Aqui, definimos apenas uma interface. Existem apenas métodos na interface, mas não há implementação, mas várias operações são concluídas.
Depois de ver isso, muitas pessoas provavelmente perguntarão: como o Spring Data JPA fez isso? Acontece que, quando a estrutura analisar o nome do método, ele interceptará primeiro os prefixos excedentes do nome do método, como encontrar, encontrar, ler, ler, obter, getby e analisar a parte restante. E se o último parâmetro do método for de tipo ou tipo de pagamento, as informações relevantes também serão extraídas para consulta de classificação ou paginação por regras. Ao criar uma consulta, expressamos -a usando nomes de atributos no nome do método, como findbyidin (). Quando a estrutura analisa esse método, primeiro elimina o encontro e depois analisa os atributos restantes.
Ao consultar, geralmente é necessário consultar com base em vários atributos ao mesmo tempo, e as condições de consulta também são de diferentes formatos (maiores que um determinado valor, em um determinado intervalo, etc.). Spring Data JPA fornece algumas palavras -chave para expressar consulta condicional, aproximadamente a seguinte:
E --- o equivalente à palavra-chave e no SQL, como o FindByUsernameandPassword (usuário da String, Striang PWD)
Ou --- equivalente a palavras-chave no SQL, como o FindByUserNameorAddress (Usuário da String, String addr)
Entre --- a palavra-chave entre o SQL, como o FindBySalaryBetween (int max, int min)
LessThan --- equivalente a "<" em sql, como findbysalarylessthan (int max)
Greaterthan ---
IsNull --- equivalente a "é nulo" em SQL, como FindbyuserNameisNull ()
IsNotNull --- equivalente a "não é nulo" no SQL, como FindByuserNameisNotNull ()
NotNull --- equivalente a IsNotNull
Como --- equivalente a "como" no SQL, como o FindByusernamelike (usuário de string)
NÃO LIGADO --- equivalente a "não gosto" no SQL, como o FindByusernameNot Like (Usuário de String)
Ordemby ---- equivalente a "Ordem por" no SQL, como FindByUserNameOrderBySalaryAc (Usuário de String)
Não --- equivalente a "!
In --- equivalente a "in" no SQL, como o FindByuserNamein (coleção <string> userList). Os parâmetros do método podem ser do tipo de coleção, ou uma matriz ou um parâmetro de comprimento indefinido.
Notin --- equivalente a "não em" no SQL, como o FindByusernameNotin (coleção <string> userList). Os parâmetros do método podem ser do tipo de coleção, ou uma matriz ou um parâmetro de comprimento indefinido.
5. A ordem de criar consultas
Ao criar um objeto proxy para uma interface, se descobrir que vários das situações acima estão disponíveis ao mesmo tempo, qual estratégia deve adotar primeiro? Para fazer isso, <jpa: repositórios> fornece a propriedade de consulta-look-up-strategy para especificar a ordem das pesquisas. Tem os três valores a seguir:
Crie --- Crie uma consulta resolvendo o nome do método. Mesmo se houver uma consulta nomeada correspondente ou a declaração de consulta especificada pelo método através do @Query, ela será ignorada.
Create-if-não-achado --- Se o método especificar uma declaração de consulta através do @Query, a consulta será implementada; Caso contrário, é descoberto se uma consulta nomeada que atende aos critérios é definida, se encontrada, a consulta nomeada é usada; Se nenhum deles for encontrado, a consulta é criada analisando o nome do método. This is the default value of the query-lookup-strategy property.
use-declared-query --- 如果方法通过@Query 指定了查询语句,则使用该语句实现查询;如果没有,则查找是否定义了符合条件的命名查询,如果找到,则使用该命名查询;如果两者都没有找到,则抛出异常。
六、Spring Data JPA 对事务的支持
Careful readers may see some clues from the above code. When we use Spring data JPA, we just define the interface. When using it, we can just inject it directly, and we do not do any processing related to things. But in fact, things have already achieved results. Por que isso?
默认情况下,Spring Data JPA 实现的方法都是使用事务的。针对查询类型的方法,其等价于@Transactional(readOnly=true);增删改类型的方法,等价于@Transactional。可以看出,除了将查询的方法设为只读事务外,其他事务属性均采用默认值。
如果用户觉得有必要,可以在接口方法上使用@Transactional 显式指定事务属性,该值覆盖Spring Data JPA 提供的默认值。同时,开发者也可以在业务层方法上使用@Transactional 指定事务属性,这主要针对一个业务层方法多次调用持久层方法的情况。持久层的事务会根据设置的事务传播行为来决定是挂起业务层事务还是加入业务层的事务。
The above is all the content of this article. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.