一:Spring Data JPA是什么,?
JPA是ORM规范,Hibernate、TopLink等是JPA规范的具体实现,这样的好处是开发者可以面向JPA规范进行持久层的开发,而底层的实现则是可以切换的。Spring Data Jpa则是在JPA之上添加另一层抽象(Repository层的实现),极大地简化持久层开发及ORM框架切换的成本。
实现技术:
1:ORM映射元数据: 支持XML和注解两种元数据的形式,元数据描述对象和表之间的映射关系
2:API: 操作实体对象来执行CRUD操作
3:查询语言: 通过面向对象而非面向数据库的查询语言(JPQL)查询数据,避免程序的SQL语句紧密耦合,减少写sql的频率
二:为什么要使用JPA
简化单表操作,Mybatis只做多表操作,
三:整合方式:
第一步:先引入依赖
<!-- springBoot JPA的起步依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- MySQL连接驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
第二步:在application.properties中配置数据库和jpa的相关属性
#DB Configuration:
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
#JPA Configuration:
spring.jpa.database=MySQL
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy
第三步:创建实体配置类 主要有三个注解
@Entity:表明该类 (UserEntity) 为一个实体类,属性值name:与数据库名称进行映射
@Id :表明该属性是唯一主键
@GeneratedValue(strategy = GenerationType.IDENTITY) :主键生成策略 IDENTITY代表主键自增
@Entity
public class User {
// 主键 自增
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// 用户名
private String username;
// 密码
private String password;
// 姓名
private String name;
//此处省略setter和getter方法... ...
}
第四步:写UserRepository 需要实现几个类才能实现对数据库的操作
public interface UserRepository extends JpaRepository<User,Long>{
public List<User> findAll();
}
JpaRepository<User,Long>类 :<表,id数据的类型>:提供了基本的增删改查的功能
第五步:编写测试类
@RunWith(SpringRunner.class)
@SpringBootTest(classes=MySpringBootApplication.class)
public class JpaTest {
@Autowired
private UserRepository userRepository;
@Test
public void test(){
//执行查询操作
List<User> users = userRepository.findAll();
System.out.println(users);
}
}
五:Spring Data JPA的方法:
- save操作(含merge操作,即update也在save里)
save(user) ,看前端所传对象里是否有主键id,如果没有就是添加,如果有就是更新操作
save方法会预检查该entity是否持久化,isNew会判断该对象的Id类型
是否实现Persistable或EntityInformation进行重写isNew方法,如果Id是Number类型,直接判断value==0 true 执行entityManager.persist 否则执行entityManager.merge()
/**
* save方法会预检查该entity是否持久化,isNew会判断该对象的Id类型 是否实现Persistable或EntityInformation进行
* 重写isNew方法,如果Id是Number类型,直接判断value==0 true 执行entityManager.persist 否则执行entityManager.merge()
*/
@Test
public void insert() {
User user= new User();
user.setName("lk");
user.setEmail("spring.jpa@163.com");
user.setAddress("Shanghai PuDong Area XueYe Road");
user.setPhone("13699999999");
//这里保存以后customer的id会被填充为保存后entity的id
User savedEntity = userRepository.save(user);
//保存并立即刷新数据库,由于customer以及提供id,会执行merge方法进行保存
// User savedAndFlush = userRepository.saveAndFlush(user);
List<User > batchUser = Arrays.asList(new User (), new User ());
//批量保存,saveAll是循环单挑插入,并不是batch操作,数据较大使用时请注意性能
// List<User > batchSaves = userRepository.saveAll(batchUser );
}
2.delete操作
delte操作会先执行查询(除了batch操作),在执行删除,若查询不到结果,抛出异常(EmptyResultDataAccessException)不执行删除
/**
* 删除操作,除了batch操作,其他方法均先查询后删除
*/
@Test
public void delete() {
//select * from customer where id=?;delete from customer where id=?;
//同delete(entity)
userRepository.deleteById(38L);
//select * from user ;循环遍历id单个删除...delete from customer where id=?...
userRepository.deleteAll();
User user = new User ();
user.setId(Long.valueOf(42L));
User userOther = new User ();
userOther.setId(41L);
List<User> deleteAll = Arrays.asList(user,userOther);
//循环执行delete(entity)
userRepository.deleteAll(deleteAll);
//不查询直接:delete from user ;(风险较大清空表)
userRepository.deleteAllInBatch();
//不查询直接:delete from user where id=? or id=?
userRepository.deleteInBatch(deleteAll);
}
3.查询操作 find关键字(主要陈述单表操作)
//select * from user;
userRepository.findAll();
//select * from user where id = 1;
userRepository.findById(1L);
//select * from user where address = "address";
userRepository.findUserByAddress("address");
//select * from user where name = "lk" and phone = "133";
userRepository.findUserNameAndPhone("133", "lk");
//select * from user where name like '%k';
userRepository.findUserNameLike("k");
//select * from user where name like 'k'; 如果需要模糊查询需要手动拼接 % 连接符
userRepository.findUserByNameLike("k");
//select * from user where name like "%l";
userRepository.findUserByNameStartingWith("l");
//select * from user where name like "%k%";
userRepository.findUserByNameContains("k");
/ /.....还有很多,不再一一列举......
=====分页排序
//排序关键字 Sort
//select * from customer order by name desc;
customerRepository.findAll(Sort.by(Direction.DESC, "name"));
//select * from customer limit 0,10;
customerRepository.findAll(PageRequest.of(0, 10));