Spring Data加JPA (Maven构建Java工程)

  使用Maven构建一Java项目,起名springdata

Spring Data加JPA (Maven构建Java工程)_第1张图片

一 基本工作


1,1  配置pom文件

1.1.1 导入6项依赖

Spring Data加JPA (Maven构建Java工程)_第2张图片


1.1.2 在pom.xml文件中配置jdk版本为1.8

	  
	      
	          
	            org.apache.maven.plugins  
	            maven-compiler-plugin  
	              
	                1.8  
	                1.8  
	                UTF-8  
	              
	          
	      
	 

1.2 配置spring全局配置文件


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

1.2.2  在src/main/resouces 下创建spring全局配置文件 applicationContext.xml

创建文件时,命名空间选择如下

Spring Data加JPA (Maven构建Java工程)_第3张图片


applicationContext.xml详情:





	
	
	
	
	

	
	
		
		
		
		
	
	
	
	
		
		
		
			
		
		
		
		
		
		
		
		
			
					true
					true
					update
			
		
		
	
	
	
	
		
	
	
	
	
	
	
	


2.1 创建持久化类和 SpringData的核心接口Repository的子接口


SpringData_Repository接口概述

  • Repository 接口是 Spring Data 的一个核心接口,它是一个空接口,不提供任何方法(和Serializable一样,Serializable也是一个空接口),开发者需要在自己定义的接口中声明需要的方法  public interface Repository { } 

  • Spring Data可以让我们只定义接口,只要遵循 Spring Data的规范,就无需写实现类。
  • 与继承 Repository 等价的一种方式,就是在持久层接口上使用 @RepositoryDefinition 注解,并为其指定 domainClass 和 idClass 属性。

  • Repository 的子接口

    • 基础的 Repository 提供了最基本的数据访问功能,其几个子接口则扩展了一些功能。它们的继承关系如下:

    1.Repository: 仅仅是一个标识,表明任何继承它的均为仓库接口类

    2.CrudRepository: 继承 Repository,实现了一组 CRUD 相关的方法

    3.PagingAndSortingRepository: 继承 CrudRepository,实现了一组分页排序相关的方法

    4.JpaRepository: 继承 PagingAndSortingRepository,实现一组 JPA 规范相关的方法

    5.自定义的 XxxxRepository 需要继承 JpaRepository,这样的 XxxxRepository 接口就具备了通用的数据访问控制层的能力。

    6.JpaSpecificationExecutor: 不属于Repository体系,实现一组 JPA Criteria 查询相关的方法

命名规范:

Spring Data加JPA (Maven构建Java工程)_第4张图片

Spring Data加JPA (Maven构建Java工程)_第5张图片

LessThan,GreaterThan 指的是数字
After,Before指的是日期 Date
写错会提示


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;
	}
}

2.1.2 创建Repository的子接口PersonRepository(继承关系)

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);
		
	}
}

3.1.2 运行testHellord方法,生成数据库表

运行前:数据库jpa是空的

Spring Data加JPA (Maven构建Java工程)_第6张图片

运行后: 自动生成了 表 jpa_persons (生成了两种表,且jpa_persons这种表主键并不是自增的)

Spring Data加JPA (Maven构建Java工程)_第7张图片


注意:

生成了两张表,且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 + "]";
	}
	
}



自动生成的表:

Spring Data加JPA (Maven构建Java工程)_第8张图片


二 正式操作 ,CRUD

2.1 单表单对象

往jpa_persons表中插入几条数据,以便测试:

Spring Data加JPA (Maven构建Java工程)_第9张图片



在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


2.2 关联表,查询关联数据

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;
	}

2.2.3 在PersonRepository接口中按照命名规范,新定义一方法

List getByAddressIdGreaterThan(Integer addressId);

2.2.4 在测试类中,添加测试方法testKeyWords2

	//查询关联数据
	@Test
	public void testKeyWords2(){
		List list = personRepository.getByAddressIdGreaterThan(110);
		System.out.println(list);
	}

运行该测试方法.会发现自动生成了表jpa_addresses, 且jpa_persons自动多了一外键列address_id

Spring Data加JPA (Maven构建Java工程)_第10张图片


使用关联数据进行查询时,底层自动走的左外连接

Spring Data加JPA (Maven构建Java工程)_第11张图片


注意:定义方法时要注意:

List getByAddressIdGreaterThan(Integer addressId);

在定义方法时,如果对象中存在这个属性addressId,会优先使用自带的属性而不是关联数据


在Person类中增加一属性addressId, 设置getter setter方法

而Person类中有一关联属性Address,那么这次去调用方法

List getByAddressIdGreaterThan(Integer addressId);时,

会优先使用自带的属性AddressId

如果想用关联数据的,而里面刚好有一个属性是同名的,那么你需要加一个下划线分割一下.

List getByAddress_IdGreaterThan(Integer addressId);  使用_后,代表Address的id

Spring Data加JPA (Maven构建Java工程)_第12张图片


接口中同时定义两个方法

	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);
	}

运行测试方法,底层走的查询语句:

Spring Data加JPA (Maven构建Java工程)_第13张图片




你可能感兴趣的:(spring,data)