SpringDataJpa简单使用步骤
1、添加相关依赖
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.my.data.test</groupId>
<artifactId>SpringDataJpaTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<spring.version>5.1.2.RELEASE</spring.version>
<hibernate.version>5.4.1.Final</hibernate.version>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
<c3p0.version>0.9.5.2</c3p0.version>
<mysql.version>8.0.15</mysql.version>
</properties>
<dependencies>
<!-- junit单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- spring beg -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring对orm框架的支持包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring end -->
<!-- hibernate beg -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.1.Final</version>
</dependency>
<!-- hibernate end -->
<!-- c3p0 beg -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>${c3p0.version}</version>
</dependency>
<!-- c3p0 end -->
<!-- log end -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- log end -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- spring data jpa 的坐标-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.9.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- el beg 使用spring data jpa 必须引入 -->
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.4</version>
</dependency>
<!-- el end -->
</dependencies>
</project>
2、整合SpringData与Spring及其配置文件–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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<!-- 配置数据库连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/my_test?serverTimezone=GMT%2B8"/>
<property name="user" value="root" />
<property name="password" value="666666" />
</bean>
<!-- 配置entityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="packagesToScan" value="com.my.data.test.entity" />
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<!-- 根据entity自动生成表 -->
<property name="generateDdl" value="false"/>
<property name="database" value="MYSQL"/>
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
<property name="showSql" value="true" />
</bean>
</property>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"></bean>
</property>
</bean>
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- 整合spring data jpa -->
<jpa:repositories base-package="com.my.data.test.dao"
transaction-manager-ref="transactionManager"
entity-manager-factory-ref="entityManagerFactory">
</jpa:repositories>
<!-- 扫描指定包下所有 -->
<context:component-scan base-package="com.my.data.test"/>
</beans>
3、创建对应实体类,并添加相应的映射关系配置
package com.my.data.test.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "data_jpa_test")
public class DataJpaTest {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private Integer id;
@Column(name="name")
private String name;
@Column(name = "age")
private Integer age;
@Column(name = "address")
private String address;
@Column(name = "des")
private String des;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
@Override
public String toString() {
return "DataJpaTest [id=" + id + ", name=" + name + ", age=" + age + ", address=" + address + ", des=" + des
+ "]";
}
}
4、创建相应的dao层接口,并继承所需接口
package com.my.data.test.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import com.my.data.test.entity.DataJpaTest;
public interface SpringDataJpaDao extends JpaRepository<DataJpaTest, Integer>, JpaSpecificationExecutor<DataJpaTest> {
}
5、测试并加载applicationContext配置文件
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class SpringDataJpaTest {
@Autowired
private SpringDataJpaDao jpaDao;
@Test
public void test1() {
DataJpaTest dataJpa = new DataJpaTest();
dataJpa.setAddress("地址");
dataJpa.setAge(11);
dataJpa.setName("姓名");
dataJpa.setDes("描述");
jpaDao.save(dataJpa);
}
}
6、使用JPQL的方式 — 自定义sql
dao配置自定义sql
public interface SpringDataJpaDao extends JpaRepository<DataJpaTest, Integer>, JpaSpecificationExecutor<DataJpaTest> {
@Query(value = "from DataJpaTest d where d.id = :id")
public DataJpaTest findById(@Param("id") Integer id);
/*更新删除需添加如下注解*/
@Transactional/*开启事务*/
@Modifying/*将该操作标识为修改或删除操作,默认为只读*/
@Query(value = "update DataJpatest d set d.name = :name where d.id = :id")
public Integer updateById(@Param("id") Integer id,@Param("name") String name);
}
使用测试
@Test
public void test1() {
DataJpaTest dataJpa = jpaDao.findById(1);
System.out.println(dataJpa.toString());
}
@Test
public void test2() {
int res = jpaDao.updateById(1, "gg");
System.out.println(res);
}
多表映射
1、Specifications动态查询
查询方法
查询方式
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class SpringDataJpaTest {
@Autowired
private SpringDataJpaDao jpaDao;
@Test
public void testSpecifications() {
Specification<DataJpaTest> specification = new Specification<DataJpaTest>() {
public Predicate toPredicate(Root<DataJpaTest> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//cb:构建查询,添加查询方式
//root:从实体DataInfo对象中按照dataSource属性进行查询
return cb.like(root.get("name").as(String.class), "%g%");
}
};
DataJpaTest jpaTest = jpaDao.findOne(specification);
System.out.println(jpaTest.toString());
}
}
2、JPA中一对多
主表
@Entity
@Table(name = "data_jpa_test")
//toString时添加,避免溢出
@Proxy(lazy = false)
public class DataJpaTest {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="test1_id")
private Integer test1Id;
@Column(name="name")
private String name;
@Column(name = "age")
private Integer age;
@Column(name = "address")
private String address;
@Column(name = "des")
private String des;
/**
* @OneToMany指向从表
* 一对多:@JoinColumn中name指向从表外键,referencedColumnName指向自己对应的主键
* 注意:referencedColumnName指向表中的column,不是实体类中的属性名
*/
@OneToMany(targetEntity = DataJpaTest2.class)
@JoinColumn(name = "cid",referencedColumnName = "test1_id")
private Set<DataJpaTest2> test2List = new HashSet<DataJpaTest2>();
public Integer getTest1Id() {
return test1Id;
}
public void setTest1Id(Integer test1Id) {
this.test1Id = test1Id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
public Set<DataJpaTest2> getTest2List() {
return test2List;
}
public void setTest2List(Set<DataJpaTest2> test2List) {
this.test2List = test2List;
}
@Override
public String toString() {
return "DataJpaTest [name=" + name + ", age=" + age + ", address=" + address + ", des=" + des
+ "]";
}
}
从表
@Entity
@Table(name = "data_jpa_test2")
//toString时添加,避免溢出
@Proxy(lazy = false)
public class DataJpaTest2 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="test2_id")
private Integer test2Id;
/**
* @ManyToOne指向主表
* 多对一:@JoinColumn中name指向自己对应主表的外键,refereencedColumnName指向主表外键
* 注意:referencedColumnName指向表中的column,不是实体类中的属性名
*/
@ManyToOne(targetEntity = DataJpaTest.class)
@JoinColumn(name = "cid",referencedColumnName = "test1_id")
private DataJpaTest dataJpaTest;
/**
* 相应的外键必须设置为不能存储更新,只能随主表进行修改或增加
*/
@Column(name = "cid",insertable=false,updatable=false)
private Integer cid;
@Column(name="name")
private String name;
@Column(name = "age")
private Integer age;
@Column(name = "address")
private String address;
@Column(name = "des")
private String des;
public Integer getTest2Id() {
return test2Id;
}
public void setTest2Id(Integer test2Id) {
this.test2Id = test2Id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
public DataJpaTest getDataJpaTest() {
return dataJpaTest;
}
public void setDataJpaTest(DataJpaTest dataJpaTest) {
this.dataJpaTest = dataJpaTest;
}
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
@Override
public String toString() {
return "DataJpaTest2 [name=" + name + ", age=" + age + ", address=" + address + ", des=" + des
+ "]";
}
}
测试方法
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class SpringDataJpaTest {
@Autowired
private SpringDataJpaDao jpaDao;
@Autowired
private SpringDataJpaDao2 jpaDao2;
@Test
public void oneToManyTest() {
DataJpaTest2 test2 = new DataJpaTest2();
test2.setAddress("地址2");
test2.setName("姓名2");
test2.setAge(12);
test2.setDes("描述2");
DataJpaTest test = new DataJpaTest();
test.setAddress("地址1");
test.setName("姓名1");
test.setAge(11);
test.setDes("描述");
//主表中加入从表
test.getTest2List().add(test2);
//先存从表再存主表
jpaDao2.save(test2);
jpaDao.save(test);
}
}
3、JPA中多对多
主表
@Entity
@Table(name = "data_jpa_test")
//toString时添加,避免溢出
@Proxy(lazy = false)
public class DataJpaTest {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="test1_id")
private Integer test1Id;
@Column(name="name")
private String name;
@Column(name = "age")
private Integer age;
@Column(name = "address")
private String address;
@Column(name = "des")
private String des;
/**CascadeType:
* 1、MERGE:主表添加数据,并新增从表数据,会在从表中搜索,若不存在则添加
* 2、REMOVE:删除主表数据,会删除对应主表数据
* 3、PERSIST:新增主表数据并加入相应从表数据时,若从表数据不存在,则报错,反之添加成功
* 4、REFRESH:级联刷新,获取主表对象里也同时也重新获取最新的从表的对象
* 5、ALL:所有
* @JoinTable:
* name:中间表表名
* joinColumns:当前表在中间表中的字段
* inverseJoinColumns:关联表在中间表中的字段
*/
@ManyToMany(targetEntity = DataJpaTest2.class,cascade = CascadeType.PERSIST)
@JoinTable(name = "test_t1t2",
joinColumns = {@JoinColumn(name = "t1_id",referencedColumnName = "test1_id")},
inverseJoinColumns = {@JoinColumn(name = "t2_id",referencedColumnName = "test2_id")})
private List<DataJpaTest2> test2List = new ArrayList<DataJpaTest2>();
public Integer getTest1Id() {
return test1Id;
}
public void setTest1Id(Integer test1Id) {
this.test1Id = test1Id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
public List<DataJpaTest2> getTest2List() {
return test2List;
}
public void setTest2List(List<DataJpaTest2> test2List) {
this.test2List = test2List;
}
@Override
public String toString() {
return "DataJpaTest [name=" + name + ", age=" + age + ", address=" + address + ", des=" + des
+ "]";
}
}
从表
@Entity
@Table(name = "data_jpa_test2")
//toString时添加,避免溢出
@Proxy(lazy = false)
public class DataJpaTest2 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="test2_id")
private Integer test2Id;
/**
* mappedBy指向关联表中的属性名
*/
@ManyToMany(mappedBy = "test2List")
private List<DataJpaTest> testList = new ArrayList<DataJpaTest>();
/**
* 相应的外键必须设置为不能存储更新,只能随主表进行修改或增加
*/
@Column(name = "cid",insertable=false,updatable=false)
private Integer cid;
@Column(name="name")
private String name;
@Column(name = "age")
private Integer age;
@Column(name = "address")
private String address;
@Column(name = "des")
private String des;
public Integer getTest2Id() {
return test2Id;
}
public void setTest2Id(Integer test2Id) {
this.test2Id = test2Id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public List<DataJpaTest> getTestList() {
return testList;
}
public void setTestList(List<DataJpaTest> testList) {
this.testList = testList;
}
@Override
public String toString() {
return "DataJpaTest2 [name=" + name + ", age=" + age + ", address=" + address + ", des=" + des
+ "]";
}
}
测试方法
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class SpringDataJpaTest {
@Autowired
private SpringDataJpaDao jpaDao;
@Autowired
private SpringDataJpaDao2 jpaDao2;
@Test
@Transactional
@Rollback(false)
public void oneToManyTest() {
DataJpaTest2 test2 = new DataJpaTest2();
test2.setAddress("地址2");
test2.setName("姓名2");
test2.setAge(12);
test2.setDes("描述2");
DataJpaTest test = new DataJpaTest();
test.setAddress("地址1");
test.setName("姓名1");
test.setAge(11);
test.setDes("描述");
//主表中加入从表
test.getTest2List().add(test2);
//直接存储
jpaDao.save(test);
}
}
4、多表查询
1、查询所有
2、fetch的用法