Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据库的访问和操作。
它提供了包括增删改查等在内的常用功能,且易于扩展
Spring Data JPA是Spring提供的一套对JPA操作更加高级的封装,是在JPA规范下的专门用来进行数据持久化的解决方案
* 搭建环境
1. 在pom文件中引入依赖
4.2.4.RELEASE
5.0.7.Final
1.6.6
1.2.12
0.9.1.2
5.1.6
junit
junit
4.9
test
org.aspectj
aspectjweaver
1.6.8
org.springframework
spring-aop
${spring.version}
org.springframework
spring-context
${spring.version}
org.springframework
spring-context-support
${spring.version}
org.springframework
spring-orm
${spring.version}
org.springframework
spring-beans
${spring.version}
org.springframework
spring-core
${spring.version}
org.hibernate
hibernate-core
${hibernate.version}
org.hibernate
hibernate-entitymanager
${hibernate.version}
org.hibernate
hibernate-validator
5.2.1.Final
c3p0
c3p0
${c3p0.version}
log4j
log4j
${log4j.version}
org.slf4j
slf4j-api
${slf4j.version}
org.slf4j
slf4j-log4j12
${slf4j.version}
mysql
mysql-connector-java
${mysql.version}
org.springframework.data
spring-data-jpa
1.9.0.RELEASE
org.springframework
spring-test
4.2.4.RELEASE
javax.el
javax.el-api
2.2.4
org.glassfish.web
javax.el
2.2.4
2. 创建spring核心配置文件applicationContext.xml
3. 编修实体类,使用jpa注解配置映射关系
@Entity
@Table(name = "cst_customer")
public class Customer implements Serializable {
@Id
@Column(name = "cust_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long custId;
@Column(name = "cust_name")
private String custName;
@Column(name = "cust_source")
private String custSource;
@Column(name = "cust_industry")
private String custIndustry;
@Column(name = "cust_level")
private String custLevel;
@Column(name = "cust_address")
private String custAddress;
@Column(name = "cust_phone")
private String custPhone;
//getter and setter
...
//toString
...
}
* 编写一个符合springDataJpa的dao层接口
1. 编写dao层接口,不需要编写dao层的实现类
2. dao层接口规范
1. 需要继承两个接口(JpaRepository,JpaSpecificationExecutor)
2. 需要提供响应的泛型
public interface ICustomerDao extends JpaRepository, JpaSpecificationExecutor {
}
* 方法
1. findOne(id):根据id查询
2. save(实体类对象):保存或者更新(依据:传递的实体类对象中,是否包含id属性)
3. delete(id):根据id删除
4. findAll():查询全部
* 测试类(简单的CRUD)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class SpringdataJpaTest {
@Autowired
private ICustomerDao dao;
/**
* 测试查询findOne
* @throws Exception
*/
@Test
public void testFindOne() throws Exception{
Customer customer = dao.findOne(1l);
System.out.println(customer);
}
/**
* 测试save保存
*/
@Test
public void testSave() throws Exception{
Customer customer = new Customer();
customer.setCustName("Levi222");
customer.setCustIndustry("it");
dao.save(customer);
}
/**
* 测试save更新
*/
@Test
public void testSave1() throws Exception{
Customer customer = dao.findOne(1l);
customer.setCustName("hello");
dao.save(customer);
}
/**
* 删除
*/
@Test
public void testDelete() throws Exception{
dao.delete(2l);
}
}
1. 通过JdkDynamicAopProxy的invoke方法创建了一个动态代理对象
2. SimpleJpaRepository当中封装了JPA的操作(借助JPA的api完成数据库的CRUD)
3. 通过hibernate完成数据库操作(封装了jdbc)
1. Spring Data JPA中接口定义的其他方法进行查询
/**
* 判断客户是否存在exists,这里使用的是查询用户的数量是否大于0
* 判断id为2的客户是否存在
* 1. 可以查询以下id为4的客户
* 如果值为空,代表不存在,如果不为空,代表存在
* 2. 判断数据库中id为4的客户的数量
* 如果数量为0,代表不存在,如果大于0,代表存在
*/
@Test
public void testExists(){
boolean exists = dao.exists(2l);
System.out.println(exists?"存在":"不存在");
}
/**
* getOne()根据id从数据库中查询
* @Transactional
* : 保证getOne正常运行,否则延迟加载默认事务结束,no session错误
* : 一般不在test方法上声明事务,在service上加,并使用一次才会不报错
* findOne:
* em.find() :立即加载
* getOne:
* em.getReference :延迟加载
* * 返回的是一个客户的动态代理对象
* * 什么时候用,什么时候查询
*/
@Test
@Transactional
public void testGetOne(){
Customer customer = dao.getOne(1l);
System.out.println(customer);
}
2. 使用JPQL的方式进行查询
1. 在dao中增加方法
/**
* Jpql形式
* @param custName
* @return
*/
@Query(value = "from Customer where custName =?1")
public Customer findJpql(String custName);
@Query(value = "from Customer where custName=?2 and id=?1")
public Customer findCustNameAndId(Long id,String name);
@Query(value = "update Customer set custName= ?2 where custId = ?1" )
@Modifying
public void updateCustomer(long custId,String custName);
2. 在测试类中测试
@Test
public void testFindJpql(){
Customer hello = dao.findJpql("hello");
System.out.println(hello);
}
@Test
public void testFindMoreParam(){
Customer hello = dao.findCustNameAndId(1l, "hello");
System.out.println(hello);
}
/**
* 不建议在测试方法中加事务以及不回滚,
* 解决办法:在service中加事务
*/
@Test
@Transactional
//在测试方法中默认是都回滚,所以要关闭否则修改无效
@Rollback(value = false)
public void testModify(){
dao.updateCustomer(1l,"hehe");
}
@Test//在service中只需加事务就可以解决
public void testModifyService(){
service.updateCustomer(1l,"haha");
}
3. 使用SQL的方式进行查询
1. 在dao中增加方法
/**
* 使用sql的形式查询:
* 查询全部的客户
* sql : select * from cst_customer;
* Query : 配置sql查询
* value : sql语句
* nativeQuery : 查询方式
* true : sql查询
* false:jpql查询
*
*/
@Query(value="select * from cst_customer where cust_name like ?1",nativeQuery = true)
public List