SpringDataJpa
什么是jpa
jpa是一个开发规范,是一个orm框架的开发规范。是sun公司定义的。
orm:对象关系映射。是一个解决问题的一个思路。对对象操作就可以实现对数据库操作。
JPA由EJB 3.0软件专家组开发,作为JSR-220实现的一部分。但它又不限于EJB 3.0,你可以在Web应用、甚至桌面应用中使用。JPA的宗旨是为POJO提供持久化标准规范。总的来说,JPA包括以下3方面的技术:
- ORM映射元数据,JPA支持XML和JDK 5.0注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中;
- JPA 的API,用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来。
- 查询语言,这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
什么是SpringDataJpa
jpa的提供商:
1、Hibernate(使用)
完全支持jpa。业内最好的一个jpa框架。
2、OpenJpa
是apache旗下的一个开源项目,也是jpa规范的实现。
3、TopLink
也是一个开源项目。是Oracle公司的。
什么是SpringDataJpa:
并不是jpa规范的实现。基于原生jpa的api进行了再次的封装,提供更简单的使用方法,和更好的用户体验。如果要使用SpringDataJpa还是需要使用Hibernate。
原生Jpa入门
一、需求
向客户表中插入一条数据。
如果使用Jpa框架可以不用先建表。可以使用框架生成表。
二、实现步骤
1)创建一个工程。
创建一个java工程即可。可以使用maven管理工程。添加依赖。
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.hibernate.version>5.0.7.Final</project.hibernate.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!--<scope>test</scope>-->
</dependency>
<!-- hibernate对jpa的支持包 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${project.hibernate.version}</version>
</dependency>
<!-- c3p0 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>${project.hibernate.version}</version>
</dependency>
<!-- log日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- Mysql and MariaDB -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!--如果是jdk1.8不需要引入此jar包-->
<!-- <dependency>-->
<!-- <groupId>javax.xml.bind</groupId>-->
<!-- <artifactId>jaxb-api</artifactId>-->
<!-- <version>2.3.0</version>-->
<!-- </dependency>-->
</dependencies>
2)创建一个配置文件。
配置文件必须在classpath:/META-INF/persistence.xml
。配置连接数据库的相关配置。
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<!--持久化单元配置,在配置文件中至少有一个
name:持久化单元名称
transaction-type:事务模式。RESOURCE_LOCAL:本地事务,单数据库的事务 JTA:分布式事务,多个数据库的事务
-->
<persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
<!--配置JPA提供商-->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<!--连接数据库配置-->
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpa"/>
<!--Hibernate的属性配置-->
<!--是否打印sql语句-->
<property name="hibernate.show_sql" value="true"/>
<!--是否格式化sql语句-->
<property name="hibernate.format_sql" value="true"/>
<!--是否自动创建数据库表
可选值:create、update、none
create:程序自动创建数据库表,如果表存在则先删除后创建
update:程序自动创建数据库表,如果表存在则不创建。
none:不会创建表
-->
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
</persistence>
3)创建一个Entity类。
对应数据库中每个表创建一个实体类。配置映射关系。
import javax.persistence.*;
//代表是一个jpa的实体类
@Entity
//配置实体类和数据库中表的映射关系,name属性对应表名
@Table(name = "cst_customer")
public class Customer {
//配置主键的生成策略
//GenerationType.IDENTITY代表自增长
@GeneratedValue(strategy = GenerationType.IDENTITY)
//标记主键
@Id
//配置属性和字段的映射关系,如果属性名和字段完全一样,则不需配置
@Column(name = "cust_id")
private long custId;
@Column(name = "cust_name")
private String custName;
@Column(name = "cust_source")
private String custSource;
@Column(name = "cust_industry")
private String custIndustry;
@Column(name = "cust_level")
private String custLevel;
@Column(name = "cust_address")
private String custAddress;
@Column(name = "cust_phone")
private String custPhone;
public long getCustId() {
return custId;
}
public void setCustId(long custId) {
this.custId = custId;
}
public String getCustName() {
return custName;
}
public void setCustName(String custName) {
this.custName = custName;
}
public String getCustSource() {
return custSource;
}
public void setCustSource(String custSource) {
this.custSource = custSource;
}
public String getCustIndustry() {
return custIndustry;
}
public void setCustIndustry(String custIndustry) {
this.custIndustry = custIndustry;
}
public String getCustLevel() {
return custLevel;
}
public void setCustLevel(String custLevel) {
this.custLevel = custLevel;
}
public String getCustAddress() {
return custAddress;
}
public void setCustAddress(String custAddress) {
this.custAddress = custAddress;
}
public String getCustPhone() {
return custPhone;
}
public void setCustPhone(String custPhone) {
this.custPhone = custPhone;
}
}
4)编写测试程序,实现数据添加。
- 创建一个
EntityManagerFactory
对象。在系统中一般都是单例的。 - 使用工厂对象创建一个
EntityManager
对象。一个EntityManager
就是一个连接。是一个多例对象。使用完毕之后就关闭。 - 开启事务。
- 创建一个
Customer
对象。 - 使用
Entitymanager
对象的persist
方法向数据库插入数据。 - 事务提交
- 关闭连接
import com.itheima.jpa.entity.Customer;
import org.junit.Test;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class JpaTest {
@Test
public void firstTest(){
// 1. 创建一个`EntityManagerFactory`对象。在系统中一般都是单例的。
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
// 2. 使用工厂对象创建一个`EntityManager`对象。一个`EntityManager`就是一个连接。是一个多例对象。使用完毕之后就关闭。
EntityManager entityManager = factory.createEntityManager();
// 3. 开启事务。
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
// 4. 创建一个`Customer`对象。
Customer customer = new Customer();
customer.setCustName("小王");
customer.setCustLevel("VIP");
customer.setCustSource("电话");
customer.setCustPhone("12345678910");
customer.setCustAddress("浙江绍兴");
// 5. 使用`Entitymanager`对象的`persist`方法向数据库插入数据。
entityManager.persist(customer);
// 6. 事务提交
transaction.commit();
// 7. 关闭连接
entityManager.close();
//系统关闭之前关闭工厂对象
factory.close();
}
}
配置文件细节说明
persistence-unit
:持久化单元。每个配置文件中至少有一个持久化单元的配置。
name
:持久化单元的名称。不能重复。transaction-type
:事务类型
RESOURCE_LOCAL
:单数据库的事务。
JTA
:分布式事务,跨数据库的事务,多个数据库的事务。
property
:
hibernate.show_sql
:是否在控制台输出sql语句。true输出,false不输出。hibernate.hbm2ddl.auto
:是否自动创建表
create:自动创建表,先删除后创建。仅供测试使用。不能应用在正式环境。
update
:自动创建表,如果表存在就直接使用,如果不存在就创建。可以应用在正式环境。
none:不自动创建表。如果表存在就直接使用,如果不存在就报错。
实体类说明
@Entity
:代表是一个jpa的实体类。
@Table
:配置实体类和表的映射关系,name:配置表名。
@Column
:配置实体类的属性和字段的映射关系。如果实体类的属性和字段名称相同可以不用配置此注解。
@Id
:标记哪个属性是主键属性。
@GeneratedValue
:主键的生成方式。如果手动生成主键,可以没有此注解。如果主键需要框架生成需要配置此注解。
1)GenerationType.IDENTITY
:自增长主键。推荐在mysql下使用,不能在Oracle使用。
2)GenerationType.SEQUENCE
:使用序列生成主键,一般是在Oracle下使用,不推荐在mysql下使用(但可以使用),在mysql中使用表生成主键。(表锁)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "cust_seq")
- generator:生成器的名称
@SequenceGenerator(name = "cust_seq", sequenceName = "cust_sequence")
- @SequenceGenerator:定义一个生成器
- name:生成器的名称
- sequenceName:Oracle数据库中序列对象的名称
3)GenerationType.TABLE
:使用数据库的表生成主键。(行锁)
@GeneratedValue(strategy = GenerationType.TABLE, generator = "tab_gen")
@TableGenerator(name = "tab_gen", table = "ids_gen", pkColumnName = "ids", valueColumnName = "vals", pkColumnValue = "customer", allocationSize = 1)
- name:生成器的名称
- table:生成主键的表的名称
- pkColumnName:主键字段的名称
- valueColumnName:值字段的名称
- pkColumnValue:主键字段的值
- allocationSize:生成主键的步长,默认是50
4)GenerationType.AUTO
:由框架自动选择,默认是使用数据库表生成主键。不推荐使用。