<!--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>
spring: datasource: url: jdbc:mysql://localhost:3306/joe?serverTimezone=UTC username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver jpa: show-sql: true
2.1 driver-class-name(驱动类)
根据mysql版本不一样不同,有的是com.mysql.cj.jdbc.Driver,有的是com.mysql.jdbc.Driver,不会报错,可是会有提示信息。
提示:Loading class com.mysql.jdbc.Driver'. This is deprecated. The new driver class is com.mysql.cj.jdbc.Driver'.
2.2 time zone 异常
异常:java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone.
解决:在datasource-url后拼接参数 serverTimezone=UTC
html
@Data @Entity @Table(name = "user") public class User implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "user_id") private Long userId; @Column(name = "user_name") private String userName; private Long age; private String gender; private String address; }
3.1 实体类建议用工具生成,由于jpa要求实体类中的字段都必须在数据库中找到对应列,即类属性只能比表字段少不能多,不然会报异常:
org.springframework.dao.InvalidDataAccessResourceUsageException
java
如何生成 IDEA自动生成JPA实体
mysql
3.2 数据库全部的表必需要有主键,jpa要求全部的表都必须有主键列,实体类必须有@Id标注,能够是联合主键,可是不能没有,没有的话会报异常:
org.hibernate.AnnotationException: No identifier specified for entity: com.joe.jpa.domain.User
联合主键如何使用 JPA联合主键
spring
@Repository public interface UserRepository extends JpaRepository<User, Integer> { }
1.jpa已经给咱们提供了单表的增删改查操做,只须要在dao接口上实现 JpaRepository<T, ID>接口,就能够经过接口里的方法完成crud操做。
其中JpaRepository里的泛型,T是表的实体类,ID是表的主键对应的实体类属性数据类型,我这里是<User, Integer>。sql
即便自定义的UserRepository没有编写任何代码,注入后同样能够能使用 save(),findXXX(),delete(),count()等方法,而且测试有效,实际上是JPA内部 CrudRepository 提供, SimpleJpaRepository 实现的,而 JpaRepository 是CrudRepository的子类,咱们又实现了 JpaRepository因此就能够直接用。
详细类图在 JpaRepository 中 右键>Diagrams>show Diagrams...>java class Diagrams
能够查看。 图文步骤:IDEA查看类继承关系
数据库
save(S var1)
springboot
@Test public void testSave() { User user = new User(); user.setUserName("张三"); user.setAge(23); user.setGender("男"); userRepository.save(user); log.info("保存成功,主键:{}", user.getUserId()); }
查询所有dom
List<T> findAll();
ide
@Test public void testFindAll() { List<User> userList = userRepository.findAll(); log.info("查询全部:{}", userList); }
主键查询
Optional<T> findById(ID var1);
List<T> findAllById(Iterable<ID> var1);
spring-boot
@Test public void testFindById() { //主键查询-查询一个 Optional<User> userOptional = userRepository.findById(2); if (userOptional.isPresent()) { log.info("根据主键查询:{}", userOptional.get()); } //主键查询-查询多个 List<Integer> userIdList = Arrays.asList(new Integer[]{2, 3}); List<User> userListByIds = userRepository.findAllById(userIdList); log.info("根据多个主键查询:{}", userListByIds); }
save(S var1)
@Test public void testUpdate() { User user = new User(); user.setUserId(2); user.setUserName("李十四"); userRepository.save(user); log.info("保存成功"); }
添加和更新操做都是save(T t)方法,逻辑是根据主键判断的,若是数据库中有数据能匹配到参数中的主键,就更新匹配到的数据,不然就新添加。
void delete(T var1)
void deleteById(ID var1);
void deleteAll();
@Test public void testDelete(){ //删除名字是张三的记录 User user = new User(); user.setUserName("张三"); userRepository.delete(user); //删除主键是2的记录(李四) Integer userId = 2; userRepository.deleteById(userId); }
long count();
@Test public void testCount() { long count = userRepository.count(); System.out.println(count); }