1 Spring Data概述
- Spring Data:Spring的一个子项目。用于简化数据库的访问,支持NOSQL和关系数据库。其主要目标就是使得数据库的访问变得方便和快捷。
- Spring Data项目所支持NOSQL存储:
- MongoDB
- Neo4j
- Redis
- Hbase
- SpringData项目所支持的关系数据库存储技术:
- JDBC
- JPA
2 JPA Spring Data
- JPA Spring Data:致力于减少数据访问层的开发量。开发者唯一要做的,就只是声明持久层的接口,其他的交给Spring Data JPA来帮你完成!
- 框架是怎么来帮我们来完成业务逻辑的啊?比如,当有一个findByUserById()这样一个方法的声明,大致就可以判断出这是一个根据给定条件的ID查询出满足条件的User对象。Spring Data JPA做的便是规范方法的名字,根据符合规范的名字来确定方法需要实现什么样的逻辑。
3 Spring Data的HelloWorld
- ①加入mysql、Spring和JPA的jar包,当然还需要导入spring data的jar包。
- ②在applicationContext.xml中配置springdata
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <context:component-scan base-package="com.xuweiwei"></context:component-scan> <context:property-placeholder location="classpath*:db.properties"></context:property-placeholder> <!-- 配置c3p0数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="${jdbc.user}"></property> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!-- 配置EntityManager --> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"></property> <!-- 配置JPA的产品提供商 --> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean> </property> <property name="packagesToScan" value="com.xuweiwei.springdata.entity"></property> <property name="jpaProperties"> <props> <!-- 开启驼峰命名:此属性很好,不过注意的是这个是Hibernate4.x支持的,Hibernate5.x需要修改 比如:LastName是java类中的属性,对应数据库中的表的列是last_name --> <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> </props> </property> </bean> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="dataSource" ref="dataSource"></property> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <!-- 开启注解式的事务 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- 配置Spring Data --> <!-- 加入jpa的命名空间 其中base-package:用来扫描Repository Bean所在的package --> <jpa:repositories base-package="com.xuweiwei.springdata.repository" entity-manager-factory-ref="entityManagerFactory"/> </beans>
- 顺便引入db.properties
jdbc.user=root jdbc.password=root jdbc.driverClass=com.mysql.jdbc.Driver jdbc.jdbcUrl=jdbc:mysql:///jpa
- ③声明持久层的接口,该接口继承Repository。Repository是一个标记型的接口,不包含任何的方法
package com.xuweiwei.springdata.repository; import com.xuweiwei.springdata.entity.Person; import org.springframework.data.repository.Repository; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public interface PersonRepository extends Repository<Person, Integer> { Person getByLastName(String lastName); }
- ④在接口中声明需要的方法,当然,你可能需要新建实体类
package com.xuweiwei.springdata.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ @Entity @Table public class Person { private String lastName; private Integer id; private String email; public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } @Id @GeneratedValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "Person{" + "lastName='" + lastName + '\'' + ", id=" + id + ", email='" + email + '\'' + '}'; } }
- 测试
package com.xuweiwei.springdata.test; import com.xuweiwei.springdata.entity.Person; import com.xuweiwei.springdata.repository.PersonRepository; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import javax.sql.DataSource; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public class SpringDataTest { private static ApplicationContext context = null; static{ context = new ClassPathXmlApplicationContext("applicationContext.xml"); } @Test public void testDataSource(){ DataSource dataSource = (DataSource) context.getBean("dataSource"); System.out.println(dataSource); } @Test public void testCreateTable(){ } @Test public void testHelloWorldSpringData(){ PersonRepository personRepository = context.getBean(PersonRepository.class); Person person = personRepository.getByLastName("xuweiwei"); System.out.println(person); } }
4 Repository接口
- ①Repository接口是一个空接口,就是一个标记接口。
- ②如果我们定义的接口继承了Repository接口,则该接口会被IOC容器识别为一个Repository Bean,纳入到IOC容器中,进而可以在该接口中定义满足一定规范的方法。
- ③实际上,也可以通过注解@RepositoryDefinition来替代继承Repository接口
package com.xuweiwei.springdata.repository; import com.xuweiwei.springdata.entity.Person; import org.springframework.data.repository.RepositoryDefinition; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ @RepositoryDefinition(domainClass = Person.class,idClass = Integer.class) public interface PersonRepository { Person getByLastName(String lastName); }
- 总结Repository接口的使用方法:
- ①开发者需要继承Repository接口
- ②开发者不需要继承Repository接口,但是需要在持久层接口上使用@RepositoryDefinition注解,并为其指定domainClass和idClass属性。
- 基础的Repository提供了最基本的数据访问功能,其几个子接口则扩展了一些功能。它们的继承关系如下:
- Repository:仅仅是一个标识,表明任何继承它的均为仓库接口类。
- CRUDRepository:继承Repository,实现了一组CRUD相关的方法。
- PaginAndSortingRepository:继承CRUDRepository,实现了一组分页排序相关的方法。
- JpaRepository:继承PagingAndSortingRepository,实现一组JPA相关的方法。
- 自定义的XxxxRepository需要继承JPARepository,这样的XxxxRepository接口就具备了通用的数据访问控制层的能力。
- JpaSpecificationExecutor:不属于Repository体系,实现一组JPA Criteria查询相关的方法。
5 SpringData中定义方法的规范
- ①不是随便定义的,需要按照一定的规范。
- ②查询方法需要以read|find|get开头
- ③涉及条件查询的时候,条件的属性用条件关键字连接
- ④注意,条件属性需要大写
- ⑤支持属性的级联查询,如果当前类有符合条件的属性,则优先使用,而不是级联属性,如果需要使用级联属性,则属性之间使用_连接。
5.1 准备工作
-
导入jar包,或用maven或gradle构建项目。
- 新建db.properties
jdbc.user=root
jdbc.password=root
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///jpa
- 新建appliationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <context:component-scan base-package="com.xuweiwei"></context:component-scan> <context:property-placeholder location="classpath*:db.properties"></context:property-placeholder> <!-- 配置c3p0数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="${jdbc.user}"></property> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!-- 配置EntityManager --> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"></property> <!-- 配置JPA的产品提供商 --> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean> </property> <property name="packagesToScan" value="com.xuweiwei.springdata.entity"></property> <property name="jpaProperties"> <props> <!-- 开启驼峰命名:此属性很好,不过注意的是这个是Hibernate4.x支持的,Hibernate5.x需要修改 比如:LastName是java类中的属性,对应数据库中的表的列是last_name --> <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> </props> </property> </bean> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="dataSource" ref="dataSource"></property> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <!-- 开启注解式的事务 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- 配置Spring Data --> <!-- 加入jpa的命名空间 其中base-package:用来扫描Repository Bean所在的package --> <jpa:repositories base-package="com.xuweiwei.springdata.repository" entity-manager-factory-ref="entityManagerFactory"/> </beans>
- 新建Person.java实体类
package com.xuweiwei.springdata.entity; import javax.persistence.*; import java.util.Date; /** * @author 许威威 * @description: * <dl> * <dt> * 注意 * </dt> * <dd> * 此处我之所以不使用@Column来自定义数据库列的名称,是因为我使用的是Hibernate的驼峰规则,在applicationContext.xml中查看到 * </dd> * </dl> * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ @Entity @Table(name="person") public class Person { private Integer id; private String lastName; private String email; private Integer age; private Date birthday; private Date createTime; @Id @GeneratedValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Temporal(TemporalType.DATE) public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Temporal(TemporalType.TIMESTAMP) public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } }
- 新建测试类,使用Hibernate底层的ddl功能,来生成表
package com.xuweiwei.springdata.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public class SpringDataTest { private static ApplicationContext context = null; static { context = new ClassPathXmlApplicationContext("applicationContext.xml"); } @Test public void testCreateTable(){ } }
- 增加一些数据
insert into `person`(`id`,`age`,`birthday`,`create_time`,`email`,`last_name`) values (1,8,'2018-05-02','2018-05-11 19:30:23','[email protected]','sd'), (2,34,'2018-04-01','2018-05-11 19:30:26','[email protected]','dafd'), (3,32,'2018-04-03','2018-05-03 19:30:28','[email protected]','fdaf'), (4,56,'2018-04-05','2018-05-03 19:30:30','[email protected]','fda'), (5,34,'2018-04-07','2018-05-11 19:30:33','[email protected]','fda'), (6,23,'2018-01-10','2018-05-11 19:30:34','[email protected]','fda'), (7,73,'2017-04-10','2018-05-11 19:30:37','[email protected]','fda'), (8,8,'2018-02-06','2018-05-11 19:30:39','[email protected]','fa'), (9,9,'2018-04-20','2018-05-11 19:30:41','[email protected]','fa'), (10,33,'2017-02-15','2018-05-11 19:30:43','[email protected]','f'), (11,22,'2017-07-25','2018-05-11 19:30:44','[email protected]','fda'), (12,12,'2016-06-22','2018-05-11 19:30:46','[email protected]','da'), (13,27,'2010-06-16','2018-05-11 19:30:49','[email protected]','fda'), (14,56,'2000-06-06','2018-05-11 19:30:51','[email protected]','fda'), (15,79,'2009-06-09','2018-05-11 19:30:52','[email protected]','dfa');
5.2 支持的关键字
- 直接在接口中定义查询方法,如果是符合规范的,可以不用写实现,目前支持的关键字的写法如下所示:
- 示例:And,就相当于where x.last_name = ? and x.age = ?
package com.xuweiwei.springdata.repository; import com.xuweiwei.springdata.entity.Person; import org.springframework.data.repository.Repository; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public interface PersonRepository extends Repository<Person,Integer> { /** * And关键字 * @param lastName * @param age * @return */ List<Person> getByLastNameAndAge(String lastName,Integer age); }
package com.xuweiwei.springdata.test; import com.xuweiwei.springdata.entity.Person; import com.xuweiwei.springdata.repository.PersonRepository; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public class SpringDataTest { private static ApplicationContext context = null; private static PersonRepository personRepository = null; static { context = new ClassPathXmlApplicationContext("applicationContext.xml"); personRepository = context.getBean(PersonRepository.class); } @Test public void testCreateTable(){ } @Test public void testAnd(){ List<Person> persons = personRepository.getByLastNameAndAge("sd", 8); for (Person person : persons) { System.out.println(person); } } }
- 示例:Or,就相当于where x.last_name =? or x.age = ?
package com.xuweiwei.springdata.repository; import com.xuweiwei.springdata.entity.Person; import org.springframework.data.repository.Repository; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public interface PersonRepository extends Repository<Person,Integer> { /** * 关键字 Or * @param lastName * @param email * @return */ List<Person> getByLastNameOrEmail(String lastName,String email); }
package com.xuweiwei.springdata.test; import com.xuweiwei.springdata.entity.Person; import com.xuweiwei.springdata.repository.PersonRepository; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public class SpringDataTest { private static ApplicationContext context = null; private static PersonRepository personRepository = null; static { context = new ClassPathXmlApplicationContext("applicationContext.xml"); personRepository = context.getBean(PersonRepository.class); } @Test public void testCreateTable(){ } @Test public void testOr(){ List<Person> persons = personRepository.getByLastNameOrEmail("fa", "[email protected]"); for (Person person : persons) { System.out.println(person); } } }
- 示例:Between,相当于where x.birthday between ? and ?
package com.xuweiwei.springdata.repository; import com.xuweiwei.springdata.entity.Person; import org.springframework.data.repository.Repository; import java.util.Date; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public interface PersonRepository extends Repository<Person,Integer> { /** * 关键字:between * @param startTime * @param endTime * @return */ List<Person> getByBirthdayBetween(Date startTime,Date endTime); }
package com.xuweiwei.springdata.test; import com.xuweiwei.springdata.entity.Person; import com.xuweiwei.springdata.repository.PersonRepository; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public class SpringDataTest { private static ApplicationContext context = null; private static PersonRepository personRepository = null; static { context = new ClassPathXmlApplicationContext("applicationContext.xml"); personRepository = context.getBean(PersonRepository.class); } @Test public void testCreateTable(){ } @Test public void testBetween() throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Date startTime = sdf.parse("2011-11-11"); List<Person> persons = personRepository.getByBirthdayBetween(startTime, new Date()); for (Person person : persons) { System.out.println(person); } } }
- 示例:LessThan,相当于where x.age < ?
package com.xuweiwei.springdata.repository; import com.xuweiwei.springdata.entity.Person; import org.springframework.data.repository.Repository; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public interface PersonRepository extends Repository<Person,Integer> { /** * 关键字:LessThan * @param age * @return */ List<Person> getByAgeLessThan(Integer age); }
package com.xuweiwei.springdata.test; import com.xuweiwei.springdata.entity.Person; import com.xuweiwei.springdata.repository.PersonRepository; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.text.ParseException; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public class SpringDataTest { private static ApplicationContext context = null; private static PersonRepository personRepository = null; static { context = new ClassPathXmlApplicationContext("applicationContext.xml"); personRepository = context.getBean(PersonRepository.class); } @Test public void testCreateTable(){ } @Test public void testBetween() throws ParseException { List<Person> personList = personRepository.getByAgeLessThan(100); for (Person person : personList) { System.out.println(person); } } }
- 示例:LessThanEqual,相当于where x.age <= ?
package com.xuweiwei.springdata.repository; import com.xuweiwei.springdata.entity.Person; import org.springframework.data.repository.Repository; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public interface PersonRepository extends Repository<Person,Integer> { /** * 关键字:LessThanEqual * @param age * @return */ List<Person> getByAgeLessThanEqual(Integer age); }
package com.xuweiwei.springdata.test; import com.xuweiwei.springdata.entity.Person; import com.xuweiwei.springdata.repository.PersonRepository; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.text.ParseException; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public class SpringDataTest { private static ApplicationContext context = null; private static PersonRepository personRepository = null; static { context = new ClassPathXmlApplicationContext("applicationContext.xml"); personRepository = context.getBean(PersonRepository.class); } @Test public void testCreateTable(){ } @Test public void testPrimary() throws ParseException { List<Person> personList = personRepository.getByAgeLessThanEqual(100); for (Person person : personList) { System.out.println(person); } } }
- 示例:GreaterThan
package com.xuweiwei.springdata.repository; import com.xuweiwei.springdata.entity.Person; import org.springframework.data.repository.Repository; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public interface PersonRepository extends Repository<Person,Integer> { /** * 关键字:GreaterThan * @param age * @return */ List<Person> getByAgeGreaterThan(Integer age); }
package com.xuweiwei.springdata.test; import com.xuweiwei.springdata.entity.Person; import com.xuweiwei.springdata.repository.PersonRepository; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.text.ParseException; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public class SpringDataTest { private static ApplicationContext context = null; private static PersonRepository personRepository = null; static { context = new ClassPathXmlApplicationContext("applicationContext.xml"); personRepository = context.getBean(PersonRepository.class); } @Test public void testCreateTable(){ } @Test public void testPrimary() throws ParseException { List<Person> personList = personRepository.getByAgeGreaterThan(100); for (Person person : personList) { System.out.println(person); } } }
- 示例:GreaterThanEqual,相当于where x.age >= ?
package com.xuweiwei.springdata.repository; import com.xuweiwei.springdata.entity.Person; import org.springframework.data.repository.Repository; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public interface PersonRepository extends Repository<Person,Integer> { /** * 关键字:GreaterThanEqual * @param age * @return */ List<Person> getByAgeGreaterThanEqual(Integer age); }
package com.xuweiwei.springdata.test; import com.xuweiwei.springdata.entity.Person; import com.xuweiwei.springdata.repository.PersonRepository; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.text.ParseException; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public class SpringDataTest { private static ApplicationContext context = null; private static PersonRepository personRepository = null; static { context = new ClassPathXmlApplicationContext("applicationContext.xml"); personRepository = context.getBean(PersonRepository.class); } @Test public void testCreateTable(){ } @Test public void testPrimary() throws ParseException { List<Person> personList = personRepository.getByAgeGreaterThanEqual(100); for (Person person : personList) { System.out.println(person); } } }
- 示例:Before,相当于where x.age < ?
package com.xuweiwei.springdata.repository; import com.xuweiwei.springdata.entity.Person; import org.springframework.data.repository.Repository; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public interface PersonRepository extends Repository<Person,Integer> { /** * 关键字:Before * @param age * @return */ List<Person> getByAgeBefore(Integer age); }
package com.xuweiwei.springdata.test; import com.xuweiwei.springdata.entity.Person; import com.xuweiwei.springdata.repository.PersonRepository; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.text.ParseException; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public class SpringDataTest { private static ApplicationContext context = null; private static PersonRepository personRepository = null; static { context = new ClassPathXmlApplicationContext("applicationContext.xml"); personRepository = context.getBean(PersonRepository.class); } @Test public void testCreateTable(){ } @Test public void testPrimary() throws ParseException { List<Person> personList = personRepository.getByAgeBefore(100); for (Person person : personList) { System.out.println(person); } } }
- 示例:After,相当于where x.age > ?
package com.xuweiwei.springdata.repository; import com.xuweiwei.springdata.entity.Person; import org.springframework.data.repository.Repository; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public interface PersonRepository extends Repository<Person,Integer> { /** * 关键字:Before * @param age * @return */ List<Person> getByAgeAfter(Integer age); }
package com.xuweiwei.springdata.test; import com.xuweiwei.springdata.entity.Person; import com.xuweiwei.springdata.repository.PersonRepository; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.text.ParseException; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public class SpringDataTest { private static ApplicationContext context = null; private static PersonRepository personRepository = null; static { context = new ClassPathXmlApplicationContext("applicationContext.xml"); personRepository = context.getBean(PersonRepository.class); } @Test public void testCreateTable(){ } @Test public void testPrimary() throws ParseException { List<Person> personList = personRepository.getByAgeAfter(100); for (Person person : personList) { System.out.println(person); } } }
- IsNull,相当于where x.last_name is null
package com.xuweiwei.springdata.repository; import com.xuweiwei.springdata.entity.Person; import org.springframework.data.repository.Repository; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public interface PersonRepository extends Repository<Person,Integer> { /** * 关键字:IsNull * @param * @return */ List<Person> getByLastNameIsNull(); }
package com.xuweiwei.springdata.test; import com.xuweiwei.springdata.entity.Person; import com.xuweiwei.springdata.repository.PersonRepository; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.text.ParseException; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public class SpringDataTest { private static ApplicationContext context = null; private static PersonRepository personRepository = null; static { context = new ClassPathXmlApplicationContext("applicationContext.xml"); personRepository = context.getBean(PersonRepository.class); } @Test public void testCreateTable(){ } @Test public void testPrimary() throws ParseException { List<Person> personList = personRepository.getByLastNameIsNull(); for (Person person : personList) { System.out.println(person); } } }
- 示例:LsNotNull,相当于where x.age is not null
package com.xuweiwei.springdata.repository; import com.xuweiwei.springdata.entity.Person; import org.springframework.data.repository.Repository; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public interface PersonRepository extends Repository<Person,Integer> { /** * 关键字:IsNotNull * @param * @return */ List<Person> getByLastNameIsNotNull(); }
package com.xuweiwei.springdata.test; import com.xuweiwei.springdata.entity.Person; import com.xuweiwei.springdata.repository.PersonRepository; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.text.ParseException; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public class SpringDataTest { private static ApplicationContext context = null; private static PersonRepository personRepository = null; static { context = new ClassPathXmlApplicationContext("applicationContext.xml"); personRepository = context.getBean(PersonRepository.class); } @Test public void testCreateTable(){ } @Test public void testPrimary() throws ParseException { List<Person> personList = personRepository.getByLastNameIsNotNull(); for (Person person : personList) { System.out.println(person); } } }
- 示例:
- Like,相当于where x.last_name like ?,精确匹配
- NotLike,相当于where x.last_name not like ? ,精确匹配
- StartingWith,相当于where x.last_name like ?,模糊匹配,会在将参数设置进去的时候,在左边加上%
- EndingWith,相当于where x.last_name like ?,模糊匹配,会在将参数设置进去的时候,在后边加上%
- Containing,相当于where x.last_name like ? ,模糊匹配,会在将参数设置进去的时候,在左右两边加上%
package com.xuweiwei.springdata.repository; import com.xuweiwei.springdata.entity.Person; import org.springframework.data.repository.Repository; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public interface PersonRepository extends Repository<Person,Integer> { /** * 关键字:Like * @param * @return */ List<Person> getByLastNameLike(String lastName); /** * 关键字:NotLike * @param * @return */ List<Person> getByLastNameNotLike(String lastName); /** * 关键字:StartingWith * @param * @return */ List<Person> getByLastNameStartingWith(String lastName); /** * 关键字:EndingWith * @param * @return */ List<Person> getByLastNameEndingWith(String lastName); /** * 关键字:Containing * @param * @return */ List<Person> getByLastNameContaining(String lastName); }
package com.xuweiwei.springdata.test; import com.xuweiwei.springdata.entity.Person; import com.xuweiwei.springdata.repository.PersonRepository; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.text.ParseException; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public class SpringDataTest { private static ApplicationContext context = null; private static PersonRepository personRepository = null; static { context = new ClassPathXmlApplicationContext("applicationContext.xml"); personRepository = context.getBean(PersonRepository.class); } @Test public void testCreateTable(){ } @Test public void testPrimary() throws ParseException { List<Person> personList = personRepository.getByLastNameLike("fd"); for (Person person : personList) { System.out.println(person); } personList = personRepository.getByLastNameNotLike("fd"); for (Person person : personList) { System.out.println(person); } personList = personRepository.getByLastNameStartingWith("fd"); for (Person person : personList) { System.out.println(person); } personList = personRepository.getByLastNameEndingWith("a"); for (Person person : personList) { System.out.println(person); } personList = personRepository.getByLastNameContaining("d"); for (Person person : personList) { System.out.println(person); } } }
- 示例:Not,相当于where x.last_name <> ? 或where x.last_name != ?
package com.xuweiwei.springdata.repository; import com.xuweiwei.springdata.entity.Person; import org.springframework.data.repository.Repository; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public interface PersonRepository extends Repository<Person,Integer> { /** * 关键字:Not * @param * @return */ List<Person> getByLastNameNot(String lastName); }
package com.xuweiwei.springdata.test; import com.xuweiwei.springdata.entity.Person; import com.xuweiwei.springdata.repository.PersonRepository; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.text.ParseException; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public class SpringDataTest { private static ApplicationContext context = null; private static PersonRepository personRepository = null; static { context = new ClassPathXmlApplicationContext("applicationContext.xml"); personRepository = context.getBean(PersonRepository.class); } @Test public void testCreateTable(){ } @Test public void testPrimary() throws ParseException { List<Person> personList = personRepository.getByLastNameNot("fa"); for (Person person : personList) { System.out.println(person); } } }
- 示例:in,相当于where x.age in (12,3,4)
package com.xuweiwei.springdata.repository; import com.xuweiwei.springdata.entity.Person; import org.springframework.data.repository.Repository; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public interface PersonRepository extends Repository<Person,Integer> { /** * 关键字:In * @param * @return */ List<Person> readByAgeIn(List<Integer> age); }
package com.xuweiwei.springdata.test; import com.xuweiwei.springdata.entity.Person; import com.xuweiwei.springdata.repository.PersonRepository; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.text.ParseException; import java.util.Arrays; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public class SpringDataTest { private static ApplicationContext context = null; private static PersonRepository personRepository = null; static { context = new ClassPathXmlApplicationContext("applicationContext.xml"); personRepository = context.getBean(PersonRepository.class); } @Test public void testCreateTable(){ } @Test public void testPrimary() throws ParseException { List<Person> personList = personRepository.readByAgeIn(Arrays.asList(34,9,12)); for (Person person : personList) { System.out.println(person); } } }
- 示例:NotIn,相当于where x.age not in(2,3,4)
- 代码:略
- 示例:TRUE,相当于where x.active = true ,遗憾的是,MySQL不支持boolean类型的字段。
- 示例:FALSE,相当于where x.active =false,遗憾的是,MySQL不支持Boolean类型的字段。
- SpringData会有坑的,记载如下,就是上面的第5点,支持属性的级联查询,如果当前类有符合条件的属性,则优先使用,而不是级联属性,如果需要使用级联属性,则属性之间使用_连接。
- 以下面的场景为例,一个地区有许多人们,所以地区是主表,而人们是从表,人们表有一个外键。
- Address,java
package com.xuweiwei.springdata.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ @Table @Entity public class Address { private Integer id; private String province; private String city; @Id @GeneratedValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } }
package com.xuweiwei.springdata.entity; import javax.persistence.*; import java.util.Date; /** * @author 许威威 * @description: * <dl> * <dt> * 注意 * </dt> * <dd> * 此处我之所以不使用@Column来自定义数据库列的名称,是因为我使用的是Hibernate的驼峰规则,在applicationContext.xml中查看到 * </dd> * </dl> * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ @Entity @Table(name="person") public class Person { private Integer id; private String lastName; private String email; private Integer age; private Date birthday; private Date createTime; private Address address; @Id @GeneratedValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Temporal(TemporalType.DATE) public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Temporal(TemporalType.TIMESTAMP) public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } @JoinColumn(name="address_id") @ManyToOne public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } }
package com.xuweiwei.springdata.repository; import com.xuweiwei.springdata.entity.Person; import org.springframework.data.repository.Repository; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public interface PersonRepository extends Repository<Person,Integer> { List<Person> getByAddressId(Integer id); }
package com.xuweiwei.springdata.test; import com.xuweiwei.springdata.entity.Person; import com.xuweiwei.springdata.repository.PersonRepository; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.List; /** * @author 许威威 * @description: * @motto 代码虐我千百遍,我视代码如初恋 * @created date :2018-05-11 * @modified by: */ public class SpringDataTest { private static ApplicationContext context = null; private static PersonRepository personRepository = null; static { context = new ClassPathXmlApplicationContext("applicationContext.xml"); personRepository = context.getBean(PersonRepository.class); } @Test public void testCreateTable(){ } @Test public void test(){ List<Person> personList = personRepository.getByAddressId(1); for (Person person : personList) { System.out.println(person); } } }
- 这样,貌似是没有问题的,但是如果我在Person.java中也增加addressId属性,那么情况就会如下所示。