SpringData

Spring Data概述

  • SpringDate:Spring的一个子项目.用于简化数据库访问,支持NoSQL和关系型数据库.其主要目标是使数据库的访问变得方便快捷.
  • SpringDate项目支持NoSQL存储:
    • MongoDB(文档数据库)
    • Neo4j(图形数据库)
    • Redis(键/值数据库)
    • Hbase(列族数据库)
  • SpringDate项目支持的关系型存储技术:
    • JDBC
    • JPA

JPA Spring Data概述

  • JPA Spring Data:致力于减小数据访问层(DAO)的开发量.开发者惟一要作的,就只是声明持久层的接口,其余都交给Spring Data JPA来作.
  • 框架是怎么代替开发者实现业务逻辑的?好比:当有一个UserDao.findUserById()这样一个方法声明,大体应该能判断出这事根据定条件ID查询出知足条件的User对象.Spring Data JPA作的即是规范方法的名字,根据符合规范的名字来肯定方法须要实现声明样的逻辑

使用Spring Data JPA进行持久层开发的四个步骤:

  • 配置Spring整合JPA
  • 在Spring配置文件中配置SpringData,让Spring为声明的接口建立代理对象.配置了jpa:repositories后,Spring初始化容器时将会扫描base-package指定的包目录及子目录,为继承Repository或其子接口的接口建立代理对象,并将代理对象注册为SpringBean,业务层即可以经过Spring自动封装的特性来直接使用该对象.
  • 声明持久层的接口,该接口继承Repository,Repository是一个标记型接口,它不包含任何方法,如必要,Spring Data可实现Repository其余子接口,其中定义了一些经常使用的增删改查,以及分页相关的方法.
  • 在接口中声明须要的方法.Spring Data将根据给定的策略来为其生成实现代码

环境搭建

  • 1.引入相应jar包
  • 2.建立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/context http://www.springframework.org/schema/context/spring-context-4.0.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">
	<!-- 1.配置数据源 -->
	<context:property-placeholder location="classpath:db.properties"/>
	
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="user" value="${jdbc.user}"></property>
		<property name="password" value="${jdbc.password}"></property>	
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
	</bean>
	
	<!-- 2.配置JPA的EntityMangerFactory -->
	<bean id="entityManagerFactory" 
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="dataSource" ref="dataSource"></property>
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
		</property>
		<!--指定包扫描-->
		<property name="packagesToScan" value="com.springdata.test"></property>
		<property name="jpaProperties">
			<props>
				<!-- 二级缓存相关 -->
				<!--  
				<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
				<prop key="net.sf.ehcache.configurationResourceName">ehcache-hibernate.xml</prop>
				-->
				<!-- 生成的数据表的列的映射策略 -->
				<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
				<!-- hibernate 基本属性 -->
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.format_sql">true</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop>
			</props>
		</property>
	</bean>
	
	<!-- 3.配置事务管理器 -->
	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory"></property>
	</bean>
	
	<!-- 4.配置支持注解的事务 -->
	<tx:annotation-driven transaction-manager="transactionManager"/>	
	<!-- 5.配置SpringData -->
	<!-- 加入 jpa 的命名空间 -->
	<!-- base-package:扫描Repository Bean 所在的 package -->
	 <jpa:repositories base-package="com.springdata.test"
	 	entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>

</beans>
复制代码
  • 3.数据库里对外链接
jdbc.user=root
jdbc.password=root
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/jpa
复制代码
  • 4.新建junit测试类,测试是否成功链接数据库
class SpringDataTest {

	private ApplicationContext  ctx = null;
	
	{
		ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
	}
	
	@Test
	void testDataSource() throws SQLException {
		DataSource dataSource = ctx.getBean(DataSource.class);
		System.out.println(dataSource.getConnection());
	}

}
复制代码

链接成功打印出链接信息mysql

测试JPA

用JPA的EntityMangerFactory代码生成表
  • 1.新建一个实体类,定义属性,生成get/set,toString方法
    • 在实力类上加注解@Etity和@Table(name="JPA_PERSONS") //意思是在数据库中建表,name就是表名
    • 在属性id上面加上@GeneratedValue和@Id注解
@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;
	}
	只截取了一部分
复制代码
  • 2.在测试类中生成数据库表(里面不用写任何代码)
    • 测试类启动就会建立ApplicationContext对象,而后会生成上面配置文件的entityManagerFactory,经过entityManagerFactory生成数据库表(springdata配置文件的第二条)
@Test
	public void testJpa() {
		
	}
复制代码

启动无报错后就会在数据库中生成一个表(数据是后加的)spring

SpringData-Repository接口
  • 1.在数据库添加一条测试数据
  • 2.新建一个持久层映射类(继承Repository接口,也可使用注解)
    • @RepositoryDefinition注解要声明domainClass和idClass属性
    • 类中写查询方法
/**
 * 1.Repository是一个空接口,便是一个标记接口
 * 2.若咱们定义的接口继承了Repository,则该接口会被IOC容器识别为一个Repository Bean.
 * 归入到IOC容器中,进而能够在该接口中定义知足必定规范的方法.
 * 3.实际上,也能够经过@RepositoryDefinition 注解来替代继承Repository 接口
 *
 */
//传入的两个泛型:1.要处理的实体类的类型2.主键的类型
@RepositoryDefinition(domainClass=Person.class,idClass=Integer.class)
public interface PersonRepsotory{

	//根据lastName 来获取对应的Person
	Person getByLastName(String lastName);
}
复制代码
  • 3.在测试类中进行测试
    • 经过上下文获得持久层对象,在经过持久层调用查询方法查出表中数据
    • 参数是根据别名查询,因此参数是数据库中数据"tom"
@Test
	public void testGet() {
		PersonRepsotory personRepsotory = ctx.getBean(PersonRepsotory.class);
		Person person = personRepsotory.getByLastName("tom");
		System.out.println(person);
	}
复制代码

查询结果sql

条件查询

  • 在持久层类中写查询方法
//WHERE lastName LIKE ?% AND id < ?(以一个模糊作开始和id小于的条件作查询)
List<Person> getByLastNameStartingWithAndIdLessThan(String lastName,Integer id);
	
//WHERE lastName LIKE %? AND id < ?(以一个模糊作结束和id小于的条件作查询)
List<Person> getByLastNameEndingWithAndIdLessThan(String lastName,Integer id);
复制代码

测试类调用数据库

/*
	 * 条件查询的方法:以某字符开头而且id小于?的方法
	 */
	@Test
	public void testKeyWords() {
		List<Person> person = personRepsotory.getByLastNameStartingWithAndIdLessThan("c", 6);
		System.out.println(person);
		
		//(以一个模糊作结束和id小于的条件作查询)方法
		List<Person> person1 = personRepsotory.getByLastNameEndingWithAndIdLessThan("c", 6);
		System.out.println(person1);
	}
	
复制代码
@Query注解
  • 一些根据关键字没法实现的查询能够经过@Query注解来实现
//查询id值最大的那个Person对象
//使用@Query 注解能够自定义 JPQL 语句以实现灵活的查询
@Query("SELECT p FROM Person p WHERE p.id = (SELECT max(p2.id) FROM Person p2)")
Person getMaxIdPerson();
复制代码
  • 传递参数的两种方式
// 为@Query 注解传递参数的方式1:使用占位符.这种方式参数顺序必须一致
@Query("SELECT p FROM Person p WHERE p.lastName = ? AND p.email = ?")
List<Person> testQueryAnnotationParms1(String lastName, String email);

// @Query注解传递参数方式2:命名参数的方式,对参数名字进行绑定,能够不按顺序
@Query("SELECT p FROM Person p WHERE p.lastName = :lastName AND p.email = :email")
List<Person> testQueryAnnotationParms2(@Param("email") String email, @Param("lastName") String lastName);
复制代码
相关文章
相关标签/搜索