Spring Data加JPA (Maven构建Java工程)
来源:互联网 发布:怎么在mac上新建文件夹 编辑:程序博客网 时间:2024/06/04 22:19
使用Maven构建一Java项目,起名springdata
一 基本工作
1,1 配置pom文件
1.1.1 导入6项依赖
1.1.2 在pom.xml文件中配置jdk版本为1.8
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build>
1.2 配置spring全局配置文件
1.2.1 在src/main/resources 下创建 db.properties文件
jdbc.driverClass=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql:///jpajdbc.username=rootjdbc.password=root
1.2.2 在src/main/resouces 下创建spring全局配置文件 applicationContext.xml
创建文件时,命名空间选择如下
applicationContext.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:jpa="http://www.springframework.org/schema/data/jpa"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsdhttp://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"><!-- 导入数据库的配置信息,注意这个标签只能出现一次, 导入一个匹配文件 若想导入多个配置文件可以将 db.properties写成 *.properties--><context:property-placeholder location="classpath:db.properties"/><!-- 扫包(让spring扫描含有注解类:service注解),扫描包的目的是为了创建对象 --><context:component-scan base-package="com.qx.springdata"></context:component-scan><!-- 配置JPA要用到的dataSource --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="${jdbc.driverClass}"></property><property name="jdbcUrl" value="${jdbc.url}"></property><property name="user" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property></bean><!-- 配置 entityManagerFactory--><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><!-- 配置扫描包,扫描所有带有jpa注解的类(就是entity注解) --><property name="packagesToScan" value="com.qx.springdata"></property><!-- 配置具体实现的相关配置(因为指定了具体实现是hibernate,因此也需要为hibernate进行相关的配置) --><!-- JPA和JDBC一样是规范,你需要给它指定一个具体的实现 --><property name="jpaProperties"><props><prop key="hibernate.show_sql">true</prop><prop key="hibernate.format_sql">true</prop><prop key="hibernate.hbm2ddl.auto">update</prop></props></property></bean><!-- 配置事务管理器 --><bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"><property name="entityManagerFactory" ref="entityManagerFactory"></property></bean><!-- 注解驱动:扫描带有@Transaction注解的类或方法 --><tx:annotation-driven transaction-manager="transactionManager"/><!-- 配置扫描springdata 扫描的是继承自Repository接口的接口 (接口可以多继承) 目的:扫描jpa注解 --><jpa:repositories base-package="com.qx.springdata" entity-manager-factory-ref="entityManagerFactory"></jpa:repositories></beans>
2.1 创建持久化类和 SpringData的核心接口Repository的子接口
SpringData_Repository接口概述
Repository 接口是 Spring Data 的一个核心接口,它是一个空接口,不提供任何方法(和Serializable一样,Serializable也是一个空接口),开发者需要在自己定义的接口中声明需要的方法 public interface Repository<T, ID extends Serializable> { }
- 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 查询相关的方法
命名规范:
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 // 按照数据库默认的方式进行自增@Idpublic 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, Integer> {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("测试前");}@Testpublic void testHellord(){//Person person = personRepository.getByLastName("bb");//System.out.println(person);}}
3.1.2 运行testHellord方法,生成数据库表
运行前:数据库jpa是空的
运行后: 自动生成了 表 jpa_persons (生成了两种表,且jpa_persons这种表主键并不是自增的)
注意:
生成了两张表,且jpa_persons这种表主键并不是自增的, 跟持久化类id的注解@GeneratedValue 有关
当注解是
@GeneratedValue // 按照数据库默认的方式进行自增@Idpublic Integer getId() {return id;}或是
@GeneratedValue(strategy=GenerationType.AUTO) // 按照数据库默认的方式进行自增@Idpublic Integer getId() {return id;}时,都将会生成两张表,其中一个是hibernate_sequence,且表jpa_persons的主键并非自增
只有为下面这种注解方式时,才会只生成一张表,且jpa_persons表的主键id是自增的
@GeneratedValue(strategy=GenerationType.IDENTITY) // 按照指定的方式进行自增@Idpublic 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) // 按照指定的方式进行自增@Idpublic 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;}@Overridepublic String toString() {return "Person [id=" + id + ", lastName=" + lastName + ", email=" + email + ", birth=" + birth + "]";}}
二 正式操作 ,CRUD
2.1 单表单对象
往jpa_persons表中插入几条数据,以便测试:
在PersonRepository接口中按命名规范,定义方法:
/** * 操作person类的接口 * 需要继承自Repository * 参1: 代表当前操作的实体类 * 参2: 代表实体类的主键类型 * @author dell * *Repository是springdata的核心接口,这个接口的实现规定了spring data操作数据库的规范--命名规范 *查询是以get或者是find或者是read开头 */public interface PersonRepository extends Repository<Person, Integer> {//根据名字查找Person getByLastName(String lastName);//查询名字以xxx开头同时id小于xxx的值List<Person> getByLastNameStartingWithAndIdLessThan(String lastName,Integer id);List<Person> getByLastNameEndingWithAndIdLessThan(String lastName,Integer id);//查询对应邮件的人List<Person> getByEmailIn(List<String> emails);//查询邮件在对应里面里面且id小于某个值的人List<Person> getByEmailInAndIdLessThan(List<String> 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("测试前");}@Testpublic void testHellord(){Person person = personRepository.getByLastName("张三");System.out.println(person);}@Testpublic void testKeyWords(){//List<Person> list = personRepository.getByLastNameStartingWithAndIdLessThan("张", 8);//System.out.println(list);//List<Person> list = personRepository.getByLastNameEndingWithAndIdLessThan("c", 8);//System.out.println(list);//使用 Arrays.asList(T... a)可以把传进来的一个可变参数数组快速转变成集合List<Person> list = personRepository.getByEmailIn(Arrays.asList("bb@163.com","cc@163.com","zs@163.com"));System.out.println(list);List<Person> list2=personRepository.getByEmailInAndIdLessThan(Arrays.asList("bb@163.com","cc@163.com","zs@163.com"), 6);System.out.println(list2);}}
测试testKeyWords结果:底层执行的sql语句和查询结果:
INFO: HHH000228: Running hbm2ddl schema update测试前七月 30, 2017 11:17:24 下午 org.hibernate.hql.internal.QueryTranslatorFactoryInitiator initiateServiceINFO: HHH000397: Using ASTQueryTranslatorFactoryHibernate: 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=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], Person [id=6, lastName=张三, email=zs@163.com, 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 关联表,查询关联数据
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)@Idpublic 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;}@Overridepublic 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<Person> getByAddressIdGreaterThan(Integer addressId);
2.2.4 在测试类中,添加测试方法testKeyWords2
//查询关联数据@Testpublic void testKeyWords2(){List<Person> list = personRepository.getByAddressIdGreaterThan(110);System.out.println(list);}
运行该测试方法.会发现自动生成了表jpa_addresses, 且jpa_persons自动多了一外键列address_id
使用关联数据进行查询时,底层自动走的左外连接
注意:定义方法时要注意:
List<Person> getByAddressIdGreaterThan(Integer addressId);
在定义方法时,如果对象中存在这个属性addressId,会优先使用自带的属性而不是关联数据
在Person类中增加一属性addressId, 设置getter setter方法
而Person类中有一关联属性Address,那么这次去调用方法
List<Person> getByAddressIdGreaterThan(Integer addressId);时,
会优先使用自带的属性AddressId
如果想用关联数据的,而里面刚好有一个属性是同名的,那么你需要加一个下划线分割一下.
List<Person> getByAddress_IdGreaterThan(Integer addressId); 使用_后,代表Address的id
接口中同时定义两个方法
List<Person> getByAddressIdGreaterThan(Integer addressid);//注意,如果对象中存在这个属性,会优先使用自带的属性而不是关联数据List<Person> getByAddress_IdGreaterThan(Integer addressid);
测试类的测试方法:
//查询关联数据@Testpublic void testKeyWords2(){List<Person> list = personRepository.getByAddressIdGreaterThan(110);System.out.println(list);List<Person> list2=personRepository.getByAddress_IdGreaterThan(110);System.out.println(list2);}
运行测试方法,底层走的查询语句:
- Spring Data加JPA (Maven构建Java工程)
- maven构建spring mvc + spring data jpa+ sql server 配置
- spring data jpa+ spring +maven
- spring data jpa 构建查询
- maven+springmvc+spring data jpa
- 【Java.Data】Spring Data -JPA
- Maven构建Java工程
- Maven构建Java工程
- maven java工程构建
- Spring JPA Data + Hibernate + MySQL + Maven
- eclipse 使用maven 搭建spring + springMVC + spring Data + jpa 框架
- spring + springMVC + spring Data jpa + maven 项目框架搭建
- Spring data JPA中使用Specifications动态构建查询
- Spring data JPA中使用Specifications动态构建查询
- 【Java.Spring.DataAccess】ORM Data Access - JPA
- JAVA操作数据库一(Spring data jpa)
- Spring Data JPA动态查询 maven项目简单例子
- 使用spring data jpa + maven开发服务端接口
- 栈帧
- HDU 3595 博弈论,被支配的恐惧
- 自定义控件---组合控件---标题栏TopBar
- easyui-accordion(手风琴)
- Android 网络编程(二)HttpClient
- Spring Data加JPA (Maven构建Java工程)
- 今年暑假不AC
- JMock实践---(二)返回结果
- 关于最近学习AJAX一些感受
- 应聘相关(一)
- MQTT安装及使用
- The Tag Game
- PowerBI 学习笔记(5)—— Any Data,Way,Any Where,Any Time
- WoOden Sticks(贪心)