上一篇:Spring Boot 参数校验、自定义Filter、自定义Property
JPA(Java Persistence API)是 Sun 官⽅提出的 Java 持久化规范。它为 Java 开发⼈员提供了⼀种对象/关联映射工具来管理 Java 应用中的关系数据。
JPA 是⼀套规范,不是⼀套产品,那么像 Hibernate、TopLink、JDO 它们是⼀套产品,如果说这些产品实现了这个 JPA 规范,那么就可以叫它们为 JPA 的实现产品。
Spring Data JPA是 Spring 基于 ORM 框架、JPA 规范的基础上封装的⼀套 JPA 应⽤框架,可使开发者用极简的代码即可实现对数据的访问和操作
mysql
mysql-connector-java
org.springframework.boot
spring-boot-starter-data-jpa
数据库连接以及设置的相关语句,依情况语句可能会稍微有些差别
# 数据库连接
Spring.datasource.url=jdbc:mysql://localhost:3306/springdemo?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone = GMT
Spring.datasource.username=root
Spring.datasource.password=
Spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据库设置
Spring.jpa.properties.hibernate.hbm2ddl.auto=update
Spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
Spring.jpa.show-sql=true
create:每次加载 hibernate 时都会删除上⼀次的生成的表,然后根据 model 类重新生成新表
create-drop:每次加载 hibernate 时根据 model 类生成表,但是 sessionFactory ⼀关闭,表就自动删除。
update:最常用的属性,初次加载 hibernate 时根据 model 类会自动建立表结构(前提是先建立
数据库),之后加载 hibernate 时根据 model 类⾃动更新表结构,即使表结构改变,表中的行仍
然存在,不会删除以前的行。当部署到服务器后,第一次运行之后表结构才会被马上建立
validate:每次加载 hibernate 时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
主要是指定⽣成表名的存储引擎为 InneoDB
是否打印出自动⽣产的 SQL,⽅便调试的时候查看
package wen.jpademo.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.io.Serializable;
@Entity
public class User implements Serializable {
@Id
@GeneratedValue
private int id;
@Column(nullable = false, unique = true)
private String username;
@Column(nullable = false)
private String password;
@Column(nullable = false, unique = true)
private String email;
@Column(nullable = false, unique = true)
private String nickname;
@Column(nullable = false)
private String regTime;
public User() {
}
public User(String username, String password, String email, String nickname, String regTime) {
this.id = id;
this.username = username;
this.password = password;
this.email = email;
this.nickname = nickname;
this.regTime = regTime;
}
//get,set方法省略
还可以用@Getter、@Setter注解的形式,点击参考
package wen.jpademo.domain;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.io.Serializable;
@Entity
public class User implements Serializable {
@Id
@GeneratedValue
@Getter
@Setter
private int id;
@Getter
@Setter
@Column(nullable = false, unique = true)
private String username;
@Getter
@Setter
@Column(nullable = false)
private String password;
@Getter
@Setter
@Column(nullable = false, unique = true)
private String email;
@Getter
@Setter
@Column(nullable = false, unique = true)
private String nickname;
@Getter
@Setter
@Column(nullable = false)
private String regTime;
public User() {
}
public User(String username, String password, String email, String nickname, String regTime) {
this.id = id;
this.username = username;
this.password = password;
this.email = email;
this.nickname = nickname;
this.regTime = regTime;
}
}
package wen.jpademo.repository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;
import wen.jpademo.domain.User;
public interface UserRepository extends JpaRepository {
User findByUsername(String username);
User findByUsernameOrEmail(String username, String email);
//分页查询
@Query("select u from User u")
Page findALL(Pageable pageable);
Page findByNickname(String nickname, Pageable pageable);
//自定义查询
@Transactional(timeout = 10)
@Modifying
@Query("update User set username = ?1 where id = ?2")
int modifyById(String username, int id);
@Transactional
@Modifying
@Query("delete from User where id = ?1")
void deleteById(int id);
@Query("select u from User u where u.email = ?1")
User findByEmail(String email);
}
package wen.jpademo;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.test.context.junit4.SpringRunner;
import wen.jpademo.domain.User;
import wen.jpademo.domain.UserDetail;
import wen.jpademo.repository.UserInfo;
import wen.jpademo.repository.UserDetailRepository;
import wen.jpademo.repository.UserRepository;
import javax.annotation.Resource;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class JpademoApplicationTests {
@Test
public void contextLoads() {
}
@Resource
private UserRepository userRepository;
@Resource
private UserDetailRepository userDetailRepository;
//自带CRUD测试
@Test
public void test() {
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
String formattedDate = dateFormat.format(date);
userRepository.save(new User("aa", "[email protected]", "aa", "aa123456", formattedDate));
userRepository.save(new User("bb", "[email protected]", "bb", "bb123456", formattedDate));
userRepository.save(new User("cc", "[email protected]", "cc", "cc123456", formattedDate));
Assert.assertEquals(3, userRepository.findAll().size());
Assert.assertEquals("bb123456", userRepository.findByUsernameOrEmail("bb", "[email protected]").getNickname());
userRepository.delete(userRepository.findByUsername("aa"));
}
@Test
public void testUserDetail() {
userDetailRepository.save(new UserDetail(35, "杏花村", "打球"));
}
//分页查询
@Test
public void testPageQuery() {
int page = 1;
int size = 2;
Sort sort = new Sort(Sort.Direction.DESC, "id");
Pageable pageable = new PageRequest(page, size, sort);
userRepository.findALL(pageable);
userRepository.findByNickname("bb123456", pageable);
}
//自定义查询
@Test
public void testCustomQuery() {
userRepository.modifyById("bibi", 35);
userRepository.deleteById(37);
userRepository.findByEmail("cc");
}
}
第二种方式,创建用户详情类UserDetail.java:
package wen.jpademo.domain;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.io.Serializable;
@Entity
public class UserDetail implements Serializable {
@Id
@GeneratedValue
@Getter
@Setter
private int id;
@Column(nullable = false, unique = true)
@Getter
@Setter
private int userId;
@Column(nullable = true)
@Getter
@Setter
private String address;
@Column(nullable = true)
@Getter
@Setter
private String hobby;
public UserDetail() {
}
public UserDetail(int userId, String address, String hobby) {
this.userId = userId;
this.address = address;
this.hobby = hobby;
}
}
package wen.jpademo.repository;
public interface UserInfo {
String getUsername();
String getEmail();
String getAddress();
String getHobby();
}
package wen.jpademo.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import wen.jpademo.domain.UserDetail;
import java.util.List;
public interface UserDetailRepository extends JpaRepository {
@Query("select u.username as username, u.email as email, d.address as address, d.hobby as hobby from User u, UserDetail d " +
"where u.id = d.userId and d.hobby =?1")
List findUserInfo(String hobby);
}
这里用用的查询语句使HQL,必须声明类的名和属性
//多表查询
@Test
public void testUserInfo() {
List userInfos = userDetailRepository.findUserInfo("打球");
for (UserInfo userInfo : userInfos) {
System.out.println("address: " + userInfo.getAddress());
}
}