Ha estado utilizando los datos de primavera JPA por un tiempo. Durante este período, aprendí algunas cosas y encontré algunos problemas. Los compartiré contigo aquí.
Prefacio:
Introducción a los datos de primavera:
Spring Data es un marco de código abierto para simplificar el acceso a la base de datos y admitir servicios en la nube. Su objetivo principal es hacer que el acceso a los datos sea conveniente y rápido, y admitir los servicios de datos de marco y computación en la nube de MAP-Reduce. Los datos de Spring contienen múltiples subprojects:
Commons: proporciona un marco básico compartido adecuado para su uso en cada subproyecto y admite la persistencia entre la database
JPA: simplifica la capacidad de crear niveles de acceso a datos de JPA y niveles de persistencia en todo el almacenamiento
Hadoop - MapReduce Job basado en la configuración de trabajo de Spring Hadoop y un modelo de programación de POJO
Valor clave: integra a Redis y Riak para proporcionar un embalaje simple en múltiples escenarios comunes
Documento: Integre bases de datos de documentos: CouchDB y MongoDB y proporcione mapeo de configuración básica y soporte de biblioteca
Gráfico - Neo4J integrado para proporcionar un poderoso modelo de programación basado en POJO
Graph Roo Addon - Soporte de ROO para NEO4J
Extensiones JDBC: admite Oracle Rad, colas avanzadas y tipos de datos avanzados
Mapeo: marco de mapeo de objetos proporcionado basado en grases, admitiendo diferentes bases de datos
Ejemplos: programas de muestra, documentos y bases de datos de gráficos
Orientación - Documentación avanzada
1. Introducción a los datos de primavera JPA
Spring Data JPA es un marco de aplicación JPA encapsulado por Spring basado en el marco de ORM y las especificaciones de JPA, y proporciona un conjunto completo de soluciones de capa de acceso a datos.
2. Funciones JPA de Spring Data JPA
Spring Data JPA tiene funciones muy poderosas. Aquí nos saltamos el paso de construcción del medio ambiente y echamos un vistazo a la "dulzura" de los datos de primavera JPA.
Spring Data JPA proporciona a los usuarios las siguientes interfaces:
3. Interfaz JPA de datos de Spring Data
1. Interfaz CrudRepository
Crear una clase de entidad:
@Entity @Table (name = "User") Usuario de clase pública {@ID @GeneratedValue Private Integer ID; // Cuenta cuenta de cadena privada; // nombre Nombre de cadena privada; // Contraseña contraseña de cadena privada; // correo electrónico Correo electrónico de cadena privada; } Escriba una interfaz y herede la interfaz CrudRepository:
Interfaz pública UserRepository extiende CrudRepository <User, Integer> {} Escriba una clase de prueba (para ver el efecto de manera más intuitiva, todas las clases de prueba no usan afirmaciones e imprimen declaraciones que se usan directamente):
clase pública UserRepositoryTest {@aUtowired private userRepository dao; @Test // Guardar public void testSave () {user user = new user (); user.setName ("chhliu"); user.setAccount ("10000"); user.setEmail ("[email protected]"); user.setPassword ("123456"); dao.save (usuario); } @Test // Save public void testSave1 () {list <serer> users = new ArrayList <Serer> (); Usuario user = nuevo usuario (); user.setName ("Tanjie"); user.setAccount ("10000"); user.setEmail ("[email protected]"); user.setPassword ("123456"); ussers.add (usuario); user = new User (); user.setName ("Esdong"); user.setAccount ("10000"); user.setEmail ("[email protected]"); user.setPassword ("123456"); ussers.add (usuario); user = new User (); user.setName ("Qinhongfei"); user.setAccount ("10000"); user.setEmail ("[email protected]"); user.setPassword ("123456"); ussers.add (usuario); user = new User (); user.setName ("Huizhang"); user.setAccount ("10000"); user.setEmail ("[email protected]"); user.setPassword ("123456"); ussers.add (usuario); user = new User (); user.setName ("caican"); user.setAccount ("10000"); user.setEmail ("[email protected]"); user.setPassword ("123456"); ussers.add (usuario); dao.save (usuarios); } @Test // actualizar public void topDate () {user user = dao.findone (1); user.setPassword ("123890"); // Para implementar la función de actualización de esta manera, debe agregar la anotación de cosas de @Transaction a la capa de servicio} @test // eliminar public void testDelete () {dao.delete (2); } @Test // consulta todo public void testFindall () {list <serem> users = (list <serer>) dao.findall (); System.out.println (json.tojsonstring (usuarios)); } @Test // consulta si el objeto de identificación especificado existe public void testisExist () {boolean isExist = dao.exists (8); System.out.println (isExist); } @Test // consulta public void testFinduserByids () {list <integer> listIds = new ArrayList <Integer> (); listids.add (2); listids.add (4); listids.add (7); List <serem> users = (list <serem>) dao.findall (listids); System.out.println (json.tojsonstring (usuarios)); }} Como puede ver, en este punto, solo escribí una clase de interfaz y no implementé esta clase de interfaz, por lo que podría completar la operación CRUD básica. Debido a que esta interfaz creará automáticamente métodos para agregar, eliminar, modificar y buscar objetos de dominio, para el uso directo de la capa de negocios.
La interfaz se define de la siguiente manera, y se proporcionan un total de 11 métodos, lo que básicamente puede cumplir con operaciones simples de Crud y operaciones por lotes:
@NorepositoryBean interfaz pública crudRepository <t, id extiende serializable> extiende el repositorio <t, id> {<s extiende t> s salvar (s entidad); // save <s extiende t> iterable <s> salvar (itableer <s> entidades); // save save t findone (id id); // consulta un objeto basado en id boolean exists exists (Idable Id); // Batch Save Findone (ID ID ID); // Consulta un objeto basado en Id boolean existe (Idable Id); // Batch Save Findone (ID ID ID); // Consulta un objeto basado en Id Boolean EXISTE EXISTE (IDABilI ITerable <T> findall (); // consulta todos los objetos iterables <t> findall (iterable <id> ids); // consulta todos los objetos basados en la lista de identificación Long count (); // Calcule el número total de objetos void eliminar (id id); // eliminar void eliminar (t entidad); // delete vaquero vaquero (itreable <iserable t> entidades); deleteall (); // eliminar todo} 2. Paging yStsortingRepository Interfaz
La interfaz Paging y SortingRepository hereda la interfaz CrudRepository.
Escriba interfaces y herede la interfaz Paging y SortingRepository
interfaz pública userRepositoryWithOrder extiende Paging ySortingRepository <User, Integer> {} Escribir clases de prueba:
@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (ubicaciones = {"classpath: ApplicationContext-Config.xml"}) @transactionConfiguration (defaultrollback = false) @transactional public class UserRepositorywithorderTest {@autowed userRepositorywithorder Dao; @Test public void testOrder () {sort sort = new sort (direction.desc, "id"); Concordante pagible = nuevo pagequest (0, 5, sort); Página <user> page = dao.findall (pagible); System.out.println (json.tojsonstring (página)); System.out.println (page.getSize ()); }} Mientras herede esta interfaz, Spring Data JPA ya le proporcionará las funciones de paginación y clasificación. La interfaz se define de la siguiente manera, y se proporcionan dos métodos para su uso, donde t es la clase de entidad que se operará y la identificación es el tipo de clave principal de la clase de entidad
@NorepositoryBean Public Interface Paging y SortingRepository <t, ID extiende serializable> extiende crudRepository <t, id> {ITerable <T> findall (sort sort); // Ordenar sin paginar la página <T> findall (pagible pagable); // clasificar con pagaging} 3. Interfaz JParepository
Si el negocio necesita proporcionar operaciones CRUD y también proporcionar funciones de paginación y clasificación, entonces puede heredar directamente esta interfaz. Esta interfaz hereda la interfaz Paging y SortingRepository.
La interfaz se define de la siguiente manera:
public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> { List<T> findAll();//Query all objects, do not sort List<T> findAll(Sort sort);//Query all objects, and sort <S extends T> List<S> save(Iterable<S> entities);//Batch save void flush();//Mail cache Sincroniza con la base de datos t saveandflush (entidad t); // guardar y forzar sincronizar void deleteinbatch (iterable <t> entidades); // lote delete void deleteallinbatch (); // delete} 4. Interfaz JPaspecificationExecutor
Esta interfaz proporciona soporte para consultas de criterios JPA. Tenga en cuenta que esta interfaz es muy especial y no pertenece al sistema de repositorio. Spring Data JPA no escaneará y reconocerá automáticamente, por lo que no se encontrará el bean correspondiente. Solo necesitamos heredar cualquier subterfaz que hereda el repositorio o heredar directamente la interfaz del repositorio. Spring Data JPA escaneará y reconocerá automáticamente y realizará una administración unificada.
La interfaz está escrita de la siguiente manera:
Public Interface SpecificationExecutorRepository extiende CrudRepository <User, Integer>, JPaspecificationExecutor <serer> {} Clase de servicio:
@Service public class SpecificationExeCutorRepositoryManager {@aUtowired Especificación privada EXECUTORREPOSITORY DAO; / *** Descripción: Consulta el usuario basado en el nombre*/ Public User FindUserByName (nombre de cadena final) {return dao.findone (new Specification <Serem> () {@Override public Predicate topredicate (root <serve> root, criteriaQuery <?> Query, criteriabuDilder cb) {predicarse = cb.equal (eEqual.get (name ", name, name;);}); }); } / *** Descripción: Consulte el usuario basado en el nombre y el correo electrónico* / Public User FindUserByNameAnDEMail (nombre final de cadena final, correo electrónico de cadena final) {return dao.findone (nueva especificación <serem> () {@Override public Predicate topredicate (root <serve> root, criteriaQuery <?> Query, criteriabuIrder cb) {LIST <LIST> LIST = NEWNICTATY <RA ROTOTATY> (() (((consulta CRITORIRIABUIRIRIRIRIRIRIR) {LIST <LIST> LIST <NEW ARTADATA (NEWATATADO <) (PredAted (); Predict1 = cb.equal (root.get ("nombre"), Nombre); } / *** Descripción: Consulta de combinación* / Public User FindUserByUser (User User Uservo final) {return dao.findone (nueva especificación <serem> () {@Override public Predicate topredicate (root <serer> root, criteriaQuery <?> Query, CriteriabuDirder CB) {predicción predicto = cb.equal (root.get (name ","), user. (UsEnSeN (UsEnSeN (UsEnSeN (UsEnSeN (UsEnSeN) (USED (USETGET); cb.and (predicada, cb.equal (root.get ("correo electrónico"), uservo.getpassword ()); } / *** Descripción: Consulta de rango en el método, como consultar el usuario con ID de usuario en [2,10]* / public List <Serem> FindUserByids (Lista final <integer> IDS) {return dao.findall (nueva especificación <serem> () {@Override public Predicate topredicate (root <serve> root, criteriaquery <?> query, criteriAriAbreAbreAriAriAft {return topredicate {return topredic root.in (IDS); } /** * Description: Range query gt method, such as querying all users with user id greater than 9*/ public List<User> findUserByGtId(final int id){ return dao.findAll(new Specification<User>() { @Override public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) { return cb.gt (root.get ("id"). As (integer.class), id); } /** * Description: Range query lt method, such as querying users with user id less than 10*/ public List<User> findUserByLtId(final int id){ return dao.findAll(new Specification<User>() { @Override public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) { return cb.lt (root.get ("id"). As (integer.class), id); } / *** Descripción: consulta de rango entre métodos, como consultar usuarios con IDS entre 3 y 10* / Lista pública <serem> FindUserBetweenId (final int inicio, final int end) {return dao.findall (nueva especificación <serer> () {@Override public Predicate (Root> root, criteriaquery <?> Query, CriteriAriler cb) cb.between (root.get ("id"). As (integer.class), inicio, final); } / *** Descripción: Operaciones de clasificación y paginación* / página pública <serem> FindUserAndorder (final int id) {sort sort = new sort (direction.desc, "id"); return dao.findall (nueva especificación <serem> () {@Override public Predicate topredicate (root <serem> root, criteriaQuery <?> Query, Criteriabuilder cb) {return cb.gt (root.get ("id"). As (integer.class), id);}, new Pagerequest (0, 5, sort)); } / *** Descripción: Solo operaciones de clasificación* / Lista pública <serem> FinduserAnDordersecondmethod (final int id) {return dao.findall (nueva especificación <serem> () {@Override public Predicate topredicate (root <serve> root, criteriaquery <?> Query, criteriabuid cb) { cb.gt (root.get ("id"). como (integer.class), id); }} Clase de prueba:
@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (ubicaciones = {"classpath: ApplicationContext-Config.xml"}) @transactionConfiguration (DeFaultrollback = false) @Transactional Class especification ExpecificationsExRePositoryManAgerterTest {@autowired private privado privado privado PrivateRecutorRorRorgeRerger; @Test public void testFinduserByName () {user user = ganager.finduserByName ("chhliu"); System.out.println (json.tojsonstring (usuario)); } @Test public void testFindUserByNameAndEmail () {user user = ganager.finduserByNameAndEmail ("chhliu", "chhliu @.com"); System.out.println (json.tojsonstring (usuario)); } @Test public void testFinduserByUservo () {user user = new User (); user.setName ("chhliu"); user.setEmail ("[email protected]"); Usuario u = administrador.finduserByUser (usuario); System.out.println (json.tojsonstring (u)); } @Test public void testFindUserByids () {list <serer> users = ganager.finduserByids (new ArrayList <Integer> (Arrays.aslist (1,3,5,6))); System.out.println (json.tojsonstring (usuarios)); } @Test public void testFindUserByGtid () {list <serer> users = manager.finduserByGtid (5); System.out.println (json.tojsonstring (usuarios)); } @Test public void testFindUserBylTid () {list <serer> users = ganager.finduserByltid (5); System.out.println (json.tojsonstring (usuarios)); } @Test public void testFindUserBetWeNID () {list <serer> users = ganager.finduserBetweenId (4, 9); System.out.println (json.tojsonstring (usuarios)); } @Test public void testFindUserAndorder () {Page <Ser User> Users = Manager.FindUserAndorder (1); System.out.println (json.tojsonstring (usuarios)); } @Test public void testFindUserAndordorSecondmethod () {list <serer> users = ganager.finduserAndordersecondmethod (1); System.out.println (json.tojsonstring (usuarios)); }} 5. Interfaz de repositorio
Esta interfaz es la interfaz más básica, es solo una interfaz icónica y no se definen métodos, entonces, ¿cuál es el uso de esta interfaz? Dado que Spring Data JPA proporciona esta interfaz, por supuesto, es útil. Por ejemplo, algunos métodos que no queremos proporcionar externamente. Por ejemplo, solo queremos proporcionar métodos de adición y modificación y no métodos de eliminación, entonces las interfaces anteriores no pueden hacerlo. En este momento, podemos heredar esta interfaz y copiar los métodos correspondientes en la interfaz CrudRepository a la interfaz del repositorio.
Resumen: ¿Cómo deberían los desarrolladores elegir las cinco interfaces anteriores? De hecho, la base es muy simple. Elija uno de ellos de acuerdo con las necesidades comerciales específicas. Porque no hay problema de fuerza y fuerza entre cada interfaz.
4. Spring Data JPA Consuly
1. Cree una consulta usando @Query
El uso de la anotación @Query es muy simple. Solo necesita etiquetar la anotación en el método declarado y proporcionar una declaración de consulta JP QL. A muchos desarrolladores les gusta usar parámetros con nombre en lugar de números de posición al crear JP QL, y @Query también proporciona soporte para esto. En la instrucción JP QL, los parámetros se especifican a través del formato de ": variable", y al mismo tiempo, @param se usa frente a los parámetros del método para corresponder a los parámetros nombrados en JP QL. Además, los desarrolladores también pueden realizar una operación de actualización utilizando @Query. Para hacer esto, debemos usar @modifying para identificar la operación como una consulta modificada mientras usa @Query, de modo que el marco eventualmente genere una operación actualizada, no una operación de consulta.
Escriba una interfaz de la siguiente manera:
/*** Descripción: consulta personalizada. Cuando Spring Data JPA no puede proporcionar, se requiere una interfaz personalizada. Este método se puede utilizar en este momento*/ interfaz pública userDefineBySelf extiende jParepository <user, entero> {/ *** parámetros llamados* Descripción: se recomienda usar este método, puede ignorar la ubicación de los parámetros*/ @Query ("Seleccione U del usuario U.Ne.name =: Nombre") Usuario FinduserByName (@param ("Nombre") String Name); /*** Parámetros del índice* Descripción: ¿Uso? marcador de posición*/ @Query ("Seleccione U del usuario u donde u.email =? 1") // 1 indica el primer parámetro user FindUserByEmail (correo electrónico de cadena); /*** Descripción: Las actualizaciones se pueden lograr a través de @modifying y @consulta* Nota: El valor de retorno de modificar consultas solo puede ser void o int/integer*/@modifying @Query ("actualizar user u set u.name =: name where u.id =: id") int updateUserByid (@param ("nombre") cadena name, @param ("id") int id); } Nota: la anotación de @modifying tiene una configuración clareAutomáticamente
Dice que el contexto de persistencia subyacente puede ser eliminado, que es la clase EntityManager. Sabemos que la implementación subyacente de JPA tendrá un caché secundario, es decir, después de actualizar la base de datos, si usa este objeto más adelante, verificará el objeto. Este objeto se almacena en caché en el primer nivel, pero no se sincroniza con la base de datos. En este momento, ClearAutomatáticamente = True se usará para actualizar el caché de primer nivel de Hibernate. De lo contrario, actualizará un objeto en la misma interfaz y luego consultará este objeto, entonces el objeto que encontró sigue siendo el estado anterior que no se actualizó antes.
Clase de prueba:
@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (ubicaciones = {"classpath: ApplicationContext-Config.xml"}) @transactionConfiguration (defaultrollback = false) @transactional public class UserDefineByebySelfTest {@autowered useredEbyBySelf Dao; @Test public void testFinduserByName () {user user = dao.finduserByName ("chhliu"); Afirmar.assertEquals ("chhliu", user.getName ()); System.out.println (user.getName ()); } @Test public void testFinduserByEmail () {user user = dao.finduserByEmail ("chhliu @.com"); Afirmar.assertEquals ("chhliu", user.getName ()); System.out.println (user.getName ()); } @Test public void topDateUserById () {dao.updateuserByid ("tanjie", 4); }} Desde el código de prueba, podemos ver que solo definimos la interfaz, sin ninguna clase de implementación, pero implementamos las funciones que necesitamos.
2. Cree una consulta usando @namedqueries
La consulta nombrada es una función proporcionada por JPA que separa las declaraciones de consulta del cuerpo del método para compartir múltiples métodos. Spring Data JPA también proporciona un buen soporte para consultas con nombre. Los usuarios solo necesitan definir la declaración de consulta en el archivo ORM.XML o en el código de acuerdo con la especificación JPA. Lo único que deben hacer es cumplir con las reglas de nombres de "DomainClass.MethodName ()" al nombrar la declaración.
Escribir una interfaz:
La interfaz pública FindUserByNamedQueryRepository extiende jParepository <user, integer> {user finduserWithName (@param ("nombre") nombre de cadena); } Escribir una clase:
@Entity @NamedQuery (valor = {@namedQuery (name = "user.finduserWithName", Query = "Seleccione U de User U Where U.Name =: Name")}) // Nota: Si hay múltiples métodos aquí, debe usar @NamedQuery. Si solo hay un método, puede usar @NamedQuery. El método de escritura es el siguiente: @namedQuery (name = "user.finduserWithName", Query = "Seleccione U del usuario u donde u.name =: name") clase pública FinduserBynamedQuery { / *** Nota: Esta clase de entidad debe definirse aquí, de lo contrario, se informará una excepción* / @id @GeneredValue Private Integer ID; } Nota: Las piezas marcadas en rojo en el artículo deben corresponder una por uno, de lo contrario no cumplirán con las especificaciones de JPA.
Clase de prueba:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:applicationContext-config.xml" }) @TransactionConfiguration(defaultRollback = false) @Transactional public class FindUserByNamedQueryRepositoryTest { @Autowired private FindUserByNamedQueryRepository dao; @Test public void testFinduserByName () {user user = dao.finduserWithName ("caican"); System.out.println (json.tojsonstring (usuario)); }} 3. Cree una consulta analizando el nombre del método
Como su nombre indica, es crear una consulta basada en el nombre del método. Tal vez suena increíble al principio, pero después de las pruebas, descubrí que todo es posible.
Escribir una interfaz:
Interfaz pública SimpleConditionQueryRepository extiende jParepository <User, Integer> { /*** Descripción: Según las reglas definidas por los datos de Spring, el método de consulta comienza con Find | Read | Get* cuando se trata de una consulta condicional, las propiedades de la condición están conectadas con palabras clave condicionales. 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 Lista de parámetros*/ User findByNameAndemail (nombre de cadena, correo electrónico de cadena); / ** * NOTA: Esta interfaz aquí es equivalente a enviar un SQL: Seleccione U del usuario u donde u.name =? 1 o u.password =? 2 */ list <serer> findByNameorPassword (nombre de cadena, contraseña de cadena); / ** * NOTA: Esta interfaz aquí es equivalente a enviar un SQL: Seleccione U del usuario u donde u.id entre? 1 y? 2 */ list <serer> findByidBetween (integer start, entero final); / ** * NOTA: Esta interfaz aquí es equivalente a enviar un SQL: Seleccione U del usuario u donde u.id entre? 1 y? 2 */ list <serer> findByidBetween (integer start, entero final); / ** * NOTA: Esta interfaz aquí es equivalente a enviar un SQL: Seleccione U del usuario u donde u.id <? 1 */ list <serer> findByidlessThan (End Integer); / ** * NOTA: Esta interfaz aquí es equivalente a enviar un SQL: Seleccione U del usuario u donde u.id>? 1 */ list <serer> findByIdGreaterThan (inteente inteente); / ** * NOTA: Esta interfaz aquí es equivalente a enviar un SQL: Seleccione U del usuario u donde u.name es nulo */ list <serer> findByNameIsNull (); / ** * NOTA: Esta interfaz aquí es equivalente a enviar un SQL: Seleccione U del usuario u donde u.name no es nulo */ list <serer> findByNameIsNotNull (); / ** * NOTA: Esta interfaz aquí es equivalente a enviar un SQL: Seleccione U del usuario u donde U.Name Like? 1 */ list <serer> findBynamElike (nombre de cadena); / ** * NOTA: Esta interfaz aquí es equivalente a enviar un SQL: Seleccione U del usuario u donde u.name no como? 1 */ list <serer> findBynamenotlike (nombre de cadena); / ** * NOTA: Esta interfaz aquí es equivalente a enviar un SQL: Seleccione U del usuario u donde u.password =? 1 pedido por u.id desc */ list <serer> findByPasswordOrderLeByDdesc (contraseña de cadena); / ** * NOTA: Esta interfaz aquí es equivalente a enviar un SQL: Seleccione U del usuario u donde u.name <>? 1 */ list <serer> findBynamenot (nombre de cadena); / ** * NOTA: Esta interfaz aquí es equivalente a enviar un SQL: Seleccione U del usuario u donde u.id in? 1 */ list <serer> findByidin (list <integer> ids); / ** * NOTA: Esta interfaz aquí es equivalente a enviar un SQL: Seleccione U del usuario u donde no está en? 1 */ list <serer> findByidNotin (list <integer> ids); } Clase de prueba (la parte del comentario es la instrucción SQL enviada real):
@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (ubicaciones = {"classpath: ApplicationContext-Config.xml"}) @TransactionConfiguration (DeFaulTrollback = False) @Transactional Public Class SimpleConTitionQueryRepositoryRositoryTest {@aUtoWired Private SimplEditionReReReReRepReProyReReReP /*** Seleccione User0_.id como ID0_, user0_.account como cuenta0_, user0_.email como correo electrónico0_, user0_.name as name0_, user0_.password como contraseña0_ desde usuarios de usuarios0_ donde user0_.name = y user0_.email =? límite? */ @Test public void testFinduserByNameAndEmail () {user user = dao.findbynameAndemail ("chhliu", "chhliu @.com"); System.out.println (json.tojsonstring (usuario)); } /*** Seleccione User0_.id como id1_, user0_.account como cuenta1_, user0_.email como correo electrónico1_, user0_.name as name1_, user0_.password como contraseña1_ del usuario user0_ donde user0_.name = =? o user0_.password =? */ @Test public void testFinduserByNameOrPassword () {list <serer> users = dao.findbynameOorPassword ("chhliu", "123456"); System.out.println (json.tojsonstring (usuarios)); } /*** Seleccione User0_.id como id1_, user0_.account como cuenta1_, user0_.email como correo electrónico1_, user0_.name as name1_, user0_.password como contraseña1_ del usuario user0_ donde user0_.id entre? y ? */ @Test public void testFindByidBetween () {list <serer> users = dao.findbyidbetween (5, 8); System.out.println (json.tojsonstring (usuarios)); } /*** Seleccione User0_.id como id1_, user0_.account como cuenta1_, user0_.email como correo electrónico1_, user0_.name as name1_, user0_.password como contraseña1_ del usuario user0_ donde user0_.id <? */ @Test public void testFindByIdLessthan () {list <serer> users = dao.findbyidlessthan (4); System.out.println (json.tojsonstring (usuarios)); } /*** Seleccione User0_.id como ID0_, user0_.account como cuenta0_, user0_.email como correo electrónico0_, user0_.name as name0_, user0_.password como contraseña0_ del usuario user0_ donde user0_.id>? */ @Test public void testFindByIdGreaterThan () {list <serer> users = dao.findbyidgreaterThan (6); System.out.println (json.tojsonstring (usuarios)); } / ** * Seleccione User0_.id como id0_, user0_.account como cuenta0_, user0_.email como correo electrónico0_, user0_.name as name0_, user0_.password como contraseña 0_ de user0_ donde user0_.name es null * / @Test public System.out.println (json.tojsonstring (usuarios)); } / ** * Seleccione User0_.id como id1_, user0_.account como cuenta1_, user0_.email como correo electrónico1_, user0_.name as name1_, user0_.password como contraseña1_ desde user0_ donde user0_.name no es null * / @test public void testFindbynameisnotnotnull () {list <serve> ussers no es null * / @test void testFindbynameisnotnotnulle dao.findbynameIsnotnull (); System.out.println (json.tojsonstring (usuarios)); } /*** Seleccione User0_.id como id1_, user0_.account como cuenta1_, user0_.email como correo electrónico1_, user0_.name as name1_, user0_.password como contraseña1_ del usuario user0_ donde user0_.name */ @Test public void testFindBynamElike () {list <serer> users = dao.findbynamelike ("chhliu"); System.out.println (json.tojsonstring (usuarios)); } /*** Seleccione User0_.id como id0_, user0_.account como cuenta0_, user0_.email como correo electrónico0_, user0_.name as name0_, user0_.password como contraseña0_ de user0_ donde user0_.name no le gusta? */ @Test public void testFindBynamenotlike () {list <serer> users = dao.findbynamenotlike ("chhliu"); System.out.println (json.tojsonstring (usuarios)); } /*** Seleccione User0_.id como id0_, user0_.account como cuenta0_, user0_.email como correo electrónico0_, user0_.name as name0_, user0_.password como contraseña 0_ de user0_ donde user0_.password =? pedido por user0_.id Desc */ @test public void testFindbyPasswordOrderLeLeByidDesc () {list <serem> users = dao.findbypasswordOrgeLorderByIdDesc ("123456"); System.out.println (json.tojsonstring (usuarios)); } /*** Seleccione User0_.id como id1_, user0_.account como cuenta1_, user0_.email como correo electrónico1_, user0_.name as name1_, user0_.password como contraseña1_ del usuario user0_ donde user0_.name <>? */ @Test public void testFindBynamenot () {list <serer> users = dao.findbynamenot ("chhliu"); System.out.println (json.tojsonstring (usuarios)); } /** * select user0_.id as id1_, user0_.account as account1_, user0_.email as email1_, user0_.name as name1_, user0_.password as password1_ from USER user0_ where user0_.id in ( ? , ? , ? , ? ) */ @Test public void testFindByIdIn(){ List<User> users = dao.findByIdIn(new ArrayList <integer> (arrays.aslist (3,4,6,8))); System.out.println (json.tojsonstring (usuarios)); } / ** * Seleccione User0_.id como id0_, user0_.account como cuenta0_, user0_.email como correo electrónico0_, user0_.name as name0_, user0_.password como contraseña 0_ desde user0_ donde user0_.id no en (?,?,?,?) * / @test public void testFindByidnotin () {list <serve <ser dao.findbyidnotin (new ArrayList <integer> (arrays.aslist (3, 4, 6, 8))); System.out.println (json.tojsonstring (usuarios)); }} Aquí, solo definimos una interfaz. Solo hay métodos en la interfaz, pero no hay implementación, pero se completan varias operaciones.
Después de ver esto, muchas personas probablemente preguntarán, ¿cómo lo hicieron los datos de primavera JPA? Resulta que cuando el marco analiza el nombre del método, primero interceptará el exceso de prefijos del nombre del método, como Find, FindBy, Read, Readby, Get, Getby y luego analizar la parte restante. Y si el último parámetro del método es de tipo o de tipo amable, la información relevante también se extraerá para la consulta de clasificación o paginación por reglas. Al crear una consulta, lo expresamos utilizando nombres de atributos en el nombre del método, como findByidin (). Cuando el marco analiza este método, primero elimina FindBy y luego analiza los atributos restantes.
Al consultar, generalmente es necesario consultar en función de múltiples atributos al mismo tiempo, y las condiciones de consulta también son de diferentes formatos (mayores que cierto valor, en un cierto rango, etc.). Spring Data JPA proporciona algunas palabras clave para expresar la consulta condicional, aproximadamente como sigue:
Y --- El equivalente a la palabra clave y en SQL, como FindByUsernameSandpassword (String User, Striang Pwd)
O --- equivalente o palabras clave en SQL, como FindByUserNameorAddress (String User, String AdDR)
Entre --- La palabra clave equivalente a SQL, como findBySalaryBetween (int max, int min)
LessThan --- equivalente a "<" en SQL, como FindBySalarylessThan (int max)
Greatthan --- equivalente a ">" en SQL, como FindBySalaryGreaterThan (int min)
Isnull --- equivalente a "es nulo" en SQL, como findbyusernameIsnull ()
Isnotnull --- equivalente a "no es nulo" en SQL, como FindByUsernameIsnotnull ()
Nonull --- equivalente a isnotnull
Me gusta --- equivalente a "me gusta" en SQL, como findByUsernamelike (usuario de cadena)
No me gusta --- equivalente a "no me gusta" en SQL, como findbyusernamenot como (usuario de cadena)
OrderBy ---- equivalente a "Orden por" en SQL, como FindByUsernerOrderByaryAsc (usuario de cadena)
No --- equivalente a "! =" En SQL, por ejemplo, findByUsernAnot (usuario de cadena)
En --- equivalente a "en" en SQL, como FindByUserNamein (colección <String> UserList). Los parámetros del método pueden ser de tipo de colección, o una matriz o un parámetro de longitud indefinida.
Notin --- equivalente a "no en" en SQL, como FindbyUsernamenotin (colección <string> userList). Los parámetros del método pueden ser de tipo de colección, o una matriz o un parámetro de longitud indefinida.
5. El orden de crear consultas
Al crear un objeto proxy para una interfaz, si encuentra que múltiples de las situaciones anteriores están disponibles al mismo tiempo, ¿qué estrategia debe adoptar primero? Para hacer esto, <JPA: Repositorios> proporciona la propiedad de consulta-aspecto-estrategia para especificar el orden de las búsquedas. Tiene los siguientes tres valores:
Crear --- Crear una consulta resolviendo el nombre del método. Incluso si hay una consulta con nombre de coincidencia, o la declaración de consulta especificada por el método a través de @Query, se ignorará.
Crear, si no-ya se encuentra --- Si el método especifica una declaración de consulta a través de @Query, la consulta se implementa; Si no, se encuentra si una consulta con nombre que cumple con los criterios se define, si se encuentra, se usa la consulta con nombre; Si ninguno se encuentra, la consulta se crea analizando el nombre del método. This is the default value of the query-lookup-strategy property.
use-declared-query --- 如果方法通过@Query 指定了查询语句,则使用该语句实现查询;如果没有,则查找是否定义了符合条件的命名查询,如果找到,则使用该命名查询;如果两者都没有找到,则抛出异常。
六、Spring Data JPA 对事务的支持
细心的读者也许从上面的代码中看出了一些端倪,我们在使用Spring data JPA的时候,只是定义了接口,在使用的时候,直接注入就可以了,并没有做与事物相关的任何处理,但实际上,事物已经起到效果了,这又是为什么了?
默认情况下,Spring Data JPA 实现的方法都是使用事务的。针对查询类型的方法,其等价于@Transactional(readOnly=true);增删改类型的方法,等价于@Transactional。可以看出,除了将查询的方法设为只读事务外,其他事务属性均采用默认值。
如果用户觉得有必要,可以在接口方法上使用@Transactional 显式指定事务属性,该值覆盖Spring Data JPA 提供的默认值。同时,开发者也可以在业务层方法上使用@Transactional 指定事务属性,这主要针对一个业务层方法多次调用持久层方法的情况。持久层的事务会根据设置的事务传播行为来决定是挂起业务层事务还是加入业务层的事务。
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.