1,1 配置pom文件
1.1.1 导入6项依赖
1.1.2 在pom.xml文件中配置jdk版本为1.8
org.apache.maven.plugins
maven-compiler-plugin
1.8
UTF-8
1.2.1 在src/main/resources 下创建 db.properties文件
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///jpa
jdbc.username=root
jdbc.password=root
创建文件时,命名空间选择如下
applicationContext.xml详情:
true
true
update
2.1 创建持久化类和 SpringData的核心接口Repository的子接口
SpringData_Repository接口概述
Repository 接口是 Spring Data 的一个核心接口,它是一个空接口,不提供任何方法(和Serializable一样,Serializable也是一个空接口),开发者需要在自己定义的接口中声明需要的方法 public interface Repository
与继承 Repository 等价的一种方式,就是在持久层接口上使用 @RepositoryDefinition 注解,并为其指定 domainClass 和 idClass 属性。
Repository 的子接口
1.Repository: 仅仅是一个标识,表明任何继承它的均为仓库接口类
2.CrudRepository: 继承 Repository,实现了一组 CRUD 相关的方法
3.PagingAndSortingRepository: 继承 CrudRepository,实现了一组分页排序相关的方法
4.JpaRepository: 继承 PagingAndSortingRepository,实现一组 JPA 规范相关的方法
5.自定义的 XxxxRepository 需要继承 JpaRepository,这样的 XxxxRepository 接口就具备了通用的数据访问控制层的能力。
6.JpaSpecificationExecutor: 不属于Repository体系,实现一组 JPA Criteria 查询相关的方法
2.1.1 创建持久化类Person
package com.qx.springdata;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="jpa_persons")
public class Person {
private Integer id;
private String lastName;
private String email;
private Date birth;
@GeneratedValue // 按照数据库默认的方式进行自增
@Id
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 Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
}
package com.qx.springdata;
import org.springframework.data.repository.Repository;
/**
* 操作person类的接口
* 需要继承自Repository
* 参1: 代表当前操作的实体类
* 参2: 代表实体类的主键类型
* @author dell
*
*Repository是springdata的核心接口,这个接口的实现规定了spring data操作数据库的规范--命名规范
*查询是以get或者是find或者是read开头
*/
public interface PersonRepository extends Repository {
Person getByLastName(String lastName);
}
3.1 创建测试类, 自动生成数据库表
3.1.1 创建一测试类TestSpringData
package com.qx.springdata.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.qx.springdata.PersonRepository;
public class TestSpringData {
private ApplicationContext context;
private PersonRepository personRepository;
@org.junit.Before //该注解含义在执行@Test注解之前先执行这个代码
public void Before(){
context=new ClassPathXmlApplicationContext("applicationContext.xml");
personRepository=context.getBean(PersonRepository.class);
System.out.println("测试前");
}
@Test
public void testHellord(){
//Person person = personRepository.getByLastName("bb");
//System.out.println(person);
}
}
运行前:数据库jpa是空的
运行后: 自动生成了 表 jpa_persons (生成了两种表,且jpa_persons这种表主键并不是自增的)
注意:
生成了两张表,且jpa_persons这种表主键并不是自增的, 跟持久化类id的注解@GeneratedValue 有关
当注解是
@GeneratedValue // 按照数据库默认的方式进行自增
@Id
public Integer getId() {
return id;
}
或是
@GeneratedValue(strategy=GenerationType.AUTO) // 按照数据库默认的方式进行自增
@Id
public Integer getId() {
return id;
}
时,都将会生成两张表,其中一个是hibernate_sequence,且表jpa_persons的主键并非自增
只有为下面这种注解方式时,才会只生成一张表,且jpa_persons表的主键id是自增的
@GeneratedValue(strategy=GenerationType.IDENTITY) // 按照指定的方式进行自增
@Id
public Integer getId() {
return id;
}
package com.qx.springdata;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="jpa_persons")
public class Person {
private Integer id;
private String lastName;
private String email;
private Date birth;
@GeneratedValue(strategy=GenerationType.IDENTITY) // 按照指定的方式进行自增
@Id
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 Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
@Override
public String toString() {
return "Person [id=" + id + ", lastName=" + lastName + ", email=" + email + ", birth=" + birth + "]";
}
}
往jpa_persons表中插入几条数据,以便测试:
在PersonRepository接口中按命名规范,定义方法:
/**
* 操作person类的接口
* 需要继承自Repository
* 参1: 代表当前操作的实体类
* 参2: 代表实体类的主键类型
* @author dell
*
*Repository是springdata的核心接口,这个接口的实现规定了spring data操作数据库的规范--命名规范
*查询是以get或者是find或者是read开头
*/
public interface PersonRepository extends Repository {
//根据名字查找
Person getByLastName(String lastName);
//查询名字以xxx开头同时id小于xxx的值
List getByLastNameStartingWithAndIdLessThan(String lastName,Integer id);
List getByLastNameEndingWithAndIdLessThan(String lastName,Integer id);
//查询对应邮件的人
List getByEmailIn(List emails);
//查询邮件在对应里面里面且id小于某个值的人
List getByEmailInAndIdLessThan(List emails,Integer id);
}
public class TestSpringData {
private ApplicationContext context;
private PersonRepository personRepository;
@org.junit.Before //该注解含义在执行@Test注解之前先执行这个代码
public void Before(){
context=new ClassPathXmlApplicationContext("applicationContext.xml");
personRepository=context.getBean(PersonRepository.class);
System.out.println("测试前");
}
@Test
public void testHellord(){
Person person = personRepository.getByLastName("张三");
System.out.println(person);
}
@Test
public void testKeyWords(){
// List list = personRepository.getByLastNameStartingWithAndIdLessThan("张", 8);
// System.out.println(list);
// List list = personRepository.getByLastNameEndingWithAndIdLessThan("c", 8);
// System.out.println(list);
//使用 Arrays.asList(T... a)可以把传进来的一个可变参数数组快速转变成集合
List list = personRepository.getByEmailIn(Arrays.asList("[email protected]","[email protected]","[email protected]"));
System.out.println(list);
List list2=personRepository.getByEmailInAndIdLessThan(Arrays.asList("[email protected]","[email protected]","[email protected]"), 6);
System.out.println(list2);
}
}
测试testKeyWords结果:底层执行的sql语句和查询结果:
INFO: HHH000228: Running hbm2ddl schema update
测试前
七月 30, 2017 11:17:24 下午 org.hibernate.hql.internal.QueryTranslatorFactoryInitiator initiateService
INFO: HHH000397: Using ASTQueryTranslatorFactory
Hibernate:
select
person0_.id as id1_0_,
person0_.birth as birth2_0_,
person0_.email as email3_0_,
person0_.lastName as lastName4_0_
from
jpa_persons person0_
where
person0_.email in (
? , ? , ?
)
[Person [id=2, lastName=bb, [email protected], birth=2017-07-01 19:31:44.0]
, Person [id=3, lastName=cc, [email protected], birth=2017-07-09 22:24:17.0]
, Person [id=6, lastName=张三, [email protected], birth=2017-07-29 22:25:45.0]
]
Hibernate:
select
person0_.id as id1_0_,
person0_.birth as birth2_0_,
person0_.email as email3_0_,
person0_.lastName as lastName4_0_
from
jpa_persons person0_
where
(
person0_.email in (
? , ? , ?
)
)
and person0_.id
[Person [id=2, lastName=bb, email=bb@163.com, birth=2017-07-01 19:31:44.0]
, Person [id=3, lastName=cc, email=cc@163.com, birth=2017-07-09 22:24:17.0]
]
2.2.1新建一实体类 Address
package com.qx.springdata;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* 给类同时加@Entity 和 @Table的原因:
* 当你从数据库读取数据时,由于你要读取的表映射有实体类(@Entity注解的),那么后台会自动帮你
* 实例化一个对象:
* 创建一个Entity Bean对象相当于新建一条记录,删除一个Entity Bean对象会同时从数据库中删除
* 对应记录,修改一个Entity Bean时,容器会自动将Entity Bean的状态和数据库同步.
* @author dell
*
*/
@Entity //该注解用于指明这是一个实体bean
@Table(name="jpa_addresses") //该注解用于指明Entity所要映射到的数据库表
public class Address {
private Integer id;
private String provience;
private String city;
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Id
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getProvience() {
return provience;
}
public void setProvience(String provience) {
this.provience = provience;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Address [id=" + id + ", provience=" + provience + ", city=" + city + "]";
}
}
2.2.2 在Person类中增加一属性 Address并设置getter setter方法
private Address address;
@JoinColumn(name="address_id") //该注解用来修饰代表关联实体的属性,用于映射底层的外键列
@ManyToOne //一个地址对应着多个人,人和地址之间多对一的关系
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
List getByAddressIdGreaterThan(Integer addressId);
//查询关联数据
@Test
public void testKeyWords2(){
List list = personRepository.getByAddressIdGreaterThan(110);
System.out.println(list);
}
注意:定义方法时要注意:
在Person类中增加一属性addressId, 设置getter setter方法
而Person类中有一关联属性Address,那么这次去调用方法
List
会优先使用自带的属性AddressId
List
接口中同时定义两个方法
List getByAddressIdGreaterThan(Integer addressid);//注意,如果对象中存在这个属性,会优先使用自带的属性而不是关联数据
List getByAddress_IdGreaterThan(Integer addressid);
//查询关联数据
@Test
public void testKeyWords2(){
List list = personRepository.getByAddressIdGreaterThan(110);
System.out.println(list);
List list2=personRepository.getByAddress_IdGreaterThan(110);
System.out.println(list2);
}