Spring boot JPA
一、定义
JPA(Java Persistence API),Java持久化API,是定义对象关系映射(ORM)以及实体对象持久化的标准接口。JPA是JSR-220(EJB3.0)规范中的一部分,但是在JSR-220中规定实体对象(Entity Bean)由JPA进行支持,所以JPA不局限于EJB3.0,而是作为POJO持久化的标准规范,可以脱离容器独立运行、开发和测试。然和这套方案并未被企业广泛使用,相对地JPA更多的是依靠Hibernate的支持才的事使用。
在SpringBoot中JPA是一开Hibernate猜的是实现,Hibernate在3.2版本中已经对JPA实现了完全的支持。
JPA所维护的核心是实体(Entity Bean),而它是通过一个持久化上下文(Persistence Context)来使用的。持久化上下文包含以下3个部分
对象关系映射(Object Relational Mapping,简称ORM)描述,JPA支持注解和XML两种方式的描述,在Spring Boot中主要通过注解实现;
实体操作API,实现岁实体对象的CRUD操作,完成对象的查询和持久化;
查询语言,约定了面向对象的查询语言JPQL(Java Persistence Query Language),实现灵活的查询
二、JPA注解
@Entity :表明是一个实体类、
@Table :属性name指出映射数据库的表,这样实体就映射到对应的表上
@Id :标注属性为表的主键
@GeneratedValue :和@Id组合使用,致命主键采用何种侧路由说呢过成主键
GenerationType.IDENTITY,是要数据库递增策略
GenerationType.AUTO,主键由程序控制
GenerationType.ENERATOR,指定生成主键使用的生成器
GenerationType.TABLE,使用一个特定的数据库来保存主键
GenerationType.SYSTEM-UUID,使用系统生成的UUID进行配
@Column :通过指定name属性的值,关联数据库表的列
name字段用于指定映射到表结构的映射字段。
length代表此字段的长度约束,可以省略。
unique属性代表此字段是否开启唯一性约束,默认为false,唯一则为true 。
nullable代表此字段是否可以为空,默认为true 。 false代表不能为空 。
@DateTimeFormat用于映射数据库表时间的格式。
@Temporal :如果某个实体类的字段包含 Date类型,那么数据库中应该存储的是 “yyyy-MM-dd hh:MM:ss”的形式,针对这种形式的存储,@Temporal 有三种注解值对应
第一种:@Temporal(TemporalType.DATE)——》实体类会封装成日期“yyyy-MM-dd”的 Date类型。
第二种:@Temporal(TemporalType.TIME)——》实体类会封装成时间“hh-MM-ss”的 Date类型。
第三种:@Temporal(TemporalType.TIMESTAMP)——》实体类会封装成完整的时间“yyyy-MM-dd hh:MM:ss”的 Date类型。
@Query:定义SQL查询
nativeQuery = true ,说明定义的SQL是原生sql语句(所谓原生sql,也就是说这段sql拷贝到数据库中,然后把参数值给一下就能运行了),分页必须设为true
@Modifying : 在@Query注解中编写JPQL实现DELETE和UPDATE操作的时候必须加上@modifying注解,以通知Spring Data 这是一个DELETE或UPDATE操作
一版要结合@Transactional注解一起使用
@NamedQueries :属性name指定命名查询的名称,query属性指定命名查询的语句,在Entity上注释,不推荐使用
@Entity @Table(name="t_user") @NamedQueries({ @NamedQuery(name="findAllUser",query="SELECT u FROM User u"), @NamedQuery(name="findUserWithId",query="SELECT u FROM User u WHERE u.id = ?1"), @NamedQuery(name="findUserWithName",query="SELECT u FROM User u WHERE u.name = :name") }) public class User { /** * 主键 */ @Id @GeneratedValue private Long id; /** * 名字 */ @Column(name="name") private String name; }
public class TestNamedQuery { EntityManagerFactory emf = null; @Before public void before() { //根据在persistence.xml中配置的persistence-unit name 创建EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJPA"); } @After public void after() { //关闭EntityManagerFactory if(null != emf) { emf.close(); } } @Test public void testNamedQuery1() { EntityManager em = emf.createEntityManager(); List<User> users = em.createNamedQuery("findAllUser").getResultList();//根据User实体中定义的命名查询 } @Test public void testNamedQuery2() { EntityManager em = emf.createEntityManager(); Query query = em.createNamedQuery("findUserWithId");//根据User实体中定义的命名查询 query.setParameter(1, 2L); List<User> users = query.getResultList(); } @Test public void testNamedQuery3() { EntityManager em = emf.createEntityManager(); Query query = em.createNamedQuery("findUserWithName");//根据User实体中定义的命名查询 query.setParameter("name", "李坏"); List<User> users = query.getResultList(); } }
三、SpringBoot使用JPA
1、pom.xml依赖
<dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <!-- 排除默认的连接池 --> <!-- <exclusions> <exclusion> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jdbc</artifactId> </exclusion> </exclusions> --> </dependency> <!-- 连接池:HikariCP性能最好 --> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
2、application.yml配置,数据库、连接池配置
spring: datasource: url: jdbc:mysql://localhost:3306/dl?useUnicode=true&serverTimezone=UTC&characterEncoding=utf-8 username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver type: com.zaxxer.hikari.HikariDataSource hikari: minimum-idle: 10 maximum-pool-size: 25 auto-commit: true idle-timeout: 30000 pool-name: ExpendHikariCP max-lifetime: 1800000 connection-timeout: 30000 connection-test-query: SELECT 1 jpa: database-platform : org.hibernate.dialect.MySQLDialect
3、定义查询方式,目前有三种查询方式
a、方法命名查询 :方法名称组合
//根据id查找 public Order findById(@Param("id")String id); //查找全部的记录 public List<Order> findAll(); //根据订单号和id查找 public Order findByOrderNoAndStatus(@Param("orderNo")String orderNo,@Param("status")int status); //通过订单状态查找前10条记录 public List<Order> findFirst10ByStatus(@Param("status")int status); //通过订单状态查找前30条记录 public List<Order> findTop30ByStatus(@Param("status")int status); //根据订单号删除记录 public void deleteByOrderNo(@Param("orderNo")String orderNo);
b、@NamedQuery查询 : 即一个名称映射一个查询语句(要在实体类上写,不是接口里写)
@Entity @NamedQuery(name="Person.findByName",query="select p from Person p where p.name=?1") public class Person{ }
c、@Query查询
//普通多条件查询 @Query("select p from Order where p.payMethod = :payMethod and p.status = :status") public List<Order> findByPayMethodAndStatus(@Param("payMethod")String payMethod,@Param("status")int status); //分页查询 ,nativeQuery @Query(value="select * from tbl_order o where o.payMethod= :payMethod order by o.createTime desc LIMIT :start,:end",nativeQuery=true) Integer findRechargeRecord(@Param("payMethod") int payMethod,@Param("start") int start,@Param("end") int end); //修改订单状态,返回更新语句所影响的条数 @Modifying @Query("update Order o set o.status = :status where o.ordrerNo = :orderNo") int updateByOrderNo(@Param("orderNo")String orderNo,@Param("status")int status);
四、使用JPA Tools自动生成Entity对象
参考链接:https://www.cnblogs.com/zzllx/p/6481173.html
MYSQL jar包下载地址:https://mvnrepository.com/artifact/mysql/mysql-connector-java/5.1.41
1、注意表名的转换:例如表名前缀是tbl_user,生成的Entity就是 TblUser,如果不需要前缀,可以自行修改为User;
2、自动生成的Entity,没有添加主键策略,例如自增长,可以自行添加 @GeneratedValue(strategy=GenerationType.IDENTITY);
3、如果使用lombok,可以自行替换
4、JPA映射text类型,@Lob代表是长字段类型,默认的话,是longtext类型,所以需要下面这个属性来指定对应的类型。
columnDefinition="text"里面的类型可以随意改,后面mysql可能会有新的类型,只要是对应java的String类型,就可以在这里动态配置。
@Lob @Column(columnDefinition="text") public String explainStr;
常见问题解答
一、The server time zone value '�й���ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration.....
链接地址 : https://blog.csdn.net/aayygg1234/article/details/78205240
二、unknown column"***_***" in where clause (驼峰自动转换成下划线,导致找不到)
链接地址:https://blog.csdn.net/u013030980/article/details/78135335
浙公网安备 33010602011771号