jpa的使用
目录
4. 声明 UserRepository接口,继承JpaRepository
什么是jpa?
JPA是Java Persistence API的简称,中文名Java持久层API, 是 Sun 官方提出的 Java 持久化规范。它为 Java 开发人员提供了一种对象/ 关联映射工具来管理 Java 应用中的关系数据。 他的出现主要是为了简化现有的持久化开发工作和整合 ORM 技术。
spring data jpa
Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套 JPA 应用框架,底层使用了 Hibernate 的 JPA 技术实现, 可使开发者用极简的代码即可实现对数据的访问和操作。 它提供了包括增删改查等在内的常用功能, 且易于扩展!学习并使用 Spring Data JPA 可以极大提高开发效率。
springboot演示jpa
1.pom依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
2.application.properties 配置
spring.datasource.url=jdbc:mysql://localhost:3306/java-jpa?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
spring.datasource.username=root
spring.datasource.password=x5
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#这是创建数据库表的配置
spring.jpa.properties.hibernate.hbm2ddl.auto=update
#这是数据库的方言配置。
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
#该配置当在执行数据库操作的时候会在控制台打印 sql 语句,方便我们检查排错等。
spring.jpa.show-sql=true
这里介绍一下hibernate.hbm2ddl.auto的配置
-
create:表示每次加载Hibernate时都会删除上一次生成的表(包括数据), 然后重新生成新表,即使两次没有任何修改也会这样执行。 适用于每次执行单测前清空数据库的场景。
-
create-drop:表示每次加载Hibernate时都会生成表, 但当SessionFactory关闭时,所生成的表将自动删除。
-
update:最常用的属性值,第一次加载Hibernate时创建数据表 (前提是需要先有数据库),以后加载Hibernate时不会删除上一次生成的表 ,会根据实体更新,只新增字段,不会删除字段(即使实体中已经删除)。
-
validate:每次加载Hibernate时都会验证数据表结构, 只会和已经存在的数据表进行比较,根据model修改表结构,但不会创建新表。 不配置此项,表示禁用自动建表功能。
3.建立用户实体类
@Entity
public class User {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Integer id;
@Column(nullable = false, unique = true)
private String username;
@Column(nullable = false)
private String password;
//省略了get,set方法。。。
}
这里的一些注解解释如下:
-
@Entity 是一个类注解,用来注解该类是一个实体类用来进行和数据库中的表 建立关联关系,首次启动项目的时候,默认会在数据中生成一个同实体类相同名 字的表(table),也可以通过注解中的 name 属性来修改表(table)名称, 如@Entity(name=“user”) , 这样数据库中表的名称则是 user 。 该注解十分重要,如果没有该注解首次启动项目的时候你会发现数据库没有生 成对应的表。
-
@Table 注解也是一个类注解,该注解可以用来修改表的名字, 该注解完全可以忽略掉不用,@Entity 注解已具备该注解的功能。
-
@Id 类的属性注解,该注解表明该属性字段是一个主键,该属性必须具备,不可缺少。
-
@GeneratedValue 该注解通常和 @Id 主键注解一起使用,用来定义主键的 呈现形式,该注解通常有多种使用策略,先总结如下: @GeneratedValue(strategy= GenerationType.IDENTITY) 该注解由数据库自动生成,主键自增型,在 mysql 数据库中使用最频繁,oracle 不支持。
- @GeneratedValue(strategy= GenerationType.AUTO) 主键由程序控制,默认的主键生成策略,oracle 默认是序列化的方式,mysql 默认是主键自增的方式。
- @GeneratedValue(strategy= GenerationType.SEQUENCE) 根据底层数据库的序列来生成主键,条件是数据库支持序列,Oracle支持,Mysql不支持。
- @GeneratedValue(strategy= GenerationType.TABLE) 使用一个特定的数据库表格来保存主键,较少使用。
上面这些主键生成策略中,以 mysql 为例, IDENTITY 和 AUTO 用的较多, 二者当中 IDENTITY 用的多些,以下文章当中主键均使用 @GeneratedValue(strategy= GenerationType.IDENTITY) 的生成策略。
-
@Column 是一个类的属性注解,该注解可以定义一个字段映射到数据库属性的具体特征,比如字段长度,映射到数据库时属性的具体名字等。
-
@Transient 是一个属性注解,该注解标注的字段不会被映射到数据库当中。
4. 声明 UserRepository
接口,继承JpaRepository
public interface UserRepository extends JpaRepository<User,Integer> {
}
JpaRepository<User,Integer> 泛型中的第一个参数是实体类的类名
,第二个参数是主键的类型
。
这里的 JpaRepository继承了接口PagingAndSortingRepository和QueryByExampleExecutor。 而PagingAndSortingRepository又继承CrudRepository。
所以,JpaRepository接口同时拥有了基本CRUD功能以及分页功能。 因此,这里我们可以继承JpaRepository, 从而获得Spring为我们预先定义的多种基本数据操作方法。
5.定义测试类,演示添加操作
@Autowired
UserRepository userRepository;
@Test
public void userAddTest(){
User user = new User();
user.setUsername("五十六精研");
user.setPassword("123456");
userRepository.save(user);
}
运行后发现添加完成
6.查询
查询可以分为基本查询和自定义查询,一种是 spring data 默认已经实现了的, 只需要继承JpaRepository
,一种是根据查询的方法来自动解析成 SQL。
1.基本查询
基本查询只需要调用 spring data 中实现好的放法即可。
@Test
public void testQuery(){
User user=new User();
user.setUsername("张三");
user.setPassword("123");
user.setId(2);
System.out.println("无条件查询全部:"+userRepository.findAll());
System.out.println("查询记录数量:"+userRepository.count());
System.out.println("根据id查询:"+userRepository.findById(2));
//save方法id存在是修改,不存在是添加
//System.out.println("修改:"+userRepository.save(user));
//根据id删除
//userRepository.deleteById(6);
}
2.自定义查询
自定义的简单查询就是根据方法名来自动生成SQL, 主要的语法是findXXBy,readAXXBy,queryXXBy,countXXBy, getXXBy
后面跟属性名称,其中属性名开头的第一个字母大小写都可以,例如:
- User findByUsername(String username);
- List findByUsernameAndPassword(String username, String password);
- Integer deleteById(Integer id);
- Integer countByUserName(String username);
- List findByusername(String username);
使用方法就是将自定义的方法在UserRepository
类中定义,就可以调用了。
3.复杂的查询
3.1 分页查询
在实际的开发中我们需要用到分页、删选、连表等查询的时候就需要特殊的方法 或者自定义 SQL,以分页查询为例,spring data jpa已经帮我们实现了分页的功能, 在查询的方法中,需要传入参数Pageable,当查询中有多个参数的时候 Pageable建议做为最后一个参数传入。Pageable是 spring 封装的分页实现类, 使用的时候需要传入页数、每页条数和排序规则。
@Test
public void testPage(){
//page页(从0开始),size条
int page=0,size=2;
Sort sort = Sort.by(Sort.Direction.ASC,"id");//查询的排序选项。提供一个属性,以进行排序
Pageable pageable = PageRequest.of(page,size,sort);//可以加sort排序也可以不加
Page<User> pageUser=userRepository.findAll(pageable);
System.out.println("分页查询后的结果:"+pageUser.toList());
}
其中 Sort中的构造方法是私有的private
所以需要使用Sort.by来调用。
Sort.by(Sort.Direction.ASC,"id");的第一个参数是正序或倒序,第二个参数 是进行排序的字段,需要排序的字段可以多个。
Pageable中的构造方法也是受保护的protected
所以需要使用PageRequest.of来调用。 其中page是页,size是每页多少条。
jpa中的分页是先按照每页多少条进行分页后,在按页进行查询,如果查询的页 超过了所分的页,那么查询的结果将为空的集合,负数则会报错。
由于Page类继承了Slice类,而Slice又继承了Streamable类,所以Page可以调用 Streamable类中的toList()方法获取查询后的数据。
3.2 自定义SQL查询
和Hibernate一样使用Hql语句
3.2.1 第一种使用注解@Query
@Transactional
@Modifying
@Query("update User u set u.username = ?1 where u.id = ?2")
int modifyByIdAndUserId(String username, Integer id);
@Transactional
@Modifying
@Query("delete from User where id = ?1")
void deleteByUserId(Integer id);
@Query("from User")
List<User> queryAll();
删除与修改的话注意要加@Modifying 和 @Transactional注解
3.2.2 使用EntityManager完全自定义可拼接的sql
编写查询语句:
@Autowired
EntityManager entityManager;
@Test
public void testSql2(){
String sql="select * from user";
List<User> list = entityManager.createNativeQuery(sql,User.class).getResultList();
System.out.println(list);
}
entityManager.createNativeQuery(sql)执行sql语句后返回Query
对象 并调用Query对象中的getResultList()方法获取sql查询之后的数据。
以上就是jap的内容。
总结
jpa是一个对数据库操作的框架,他已经为我们定已好了简单的对单表CRUD的操作。 也可以通过自定义的方法名实现操作,还可以使用注解和实体管理器(entityManager) 自定义sql,并为我们实现了分页查询。
参照文档: