JPA工程的创建
new Project->jpa project 创建 ,这里使用hibernate的jpa实现作为案例
jar包下载 点击打开链接
配置文件persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="jpa" transaction-type="RESOURCE_LOCAL">
<!--
配置用什么ORM框架
1. 实际上配置的是 javax.persistence.spi.PersistenceProvider 接口的实现类
2. 如果JPA项目中只有一个JPA的实现产品,则可以不配置该节点
-->
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!-- 配置持久化类 -->
<class>cn.bing.pojo.Product</class>
<properties>
<!-- 配置数据源信息 -->
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<!-- 配置JPA实现产品的属性,即hibernate的属性 -->
<property name="hibernate.format_sql" value="true"/><!-- 是否格式化sql语句 -->
<property name="hibernate.show_sql" value="true"/> <!-- 是否在控制台打印sql语句 -->
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
创建实体类
将java中的实体和数据库中的表建立映射
@Table(name="product")
@Entity
public class Product {
private Integer id;
private String productName;
private BigDecimal price;
private String produceAddress;
private String remark;
@Column(name="id")
@GeneratedValue(strategy=GenerationType.AUTO)
@Id
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name="product_name")
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
@Column(name="produce_address")
public String getProduceAddress() {
return produceAddress;
}
public void setProduceAddress(String produceAddress) {
this.produceAddress = produceAddress;
}
@Column(name="price")
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
@Column(name="remark")
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
注解说明
* @Entity :表示这是实体类,将映射到指定的数据库表
* @Table: 当实体类和映射的数据库表名不同名时候使用@Table标注说明和@Entity一起使用,属性name表示表名
* @id:表名这个是主键 (用于get方法或者属性)和@Column一起使用
* @Column:属性name在数据库表中对应的字段名,如果两者名字相同,可以不写,(用于get方法或者属性),
属性columnDefinition:表示该字段在数据库中的实际类型,可以通过这个属性指定
* @GeneratedValue:表示主键的生成
属性generator 表示 生成器的名称,根据生成策略选择是否需要该属性。
属性strategy表示主键的生成策略
GenerationType.AUTO, JPA自动选择
GenerationType.IDENTITY, 采用数据库id 自增长的策略生成, ORACLE不支持
GenerationType.SEQUENCE, 采用数据库序列生成主键
@SequenceGenerator(name="Emp_Gen", sequenceName="Emp_Seq")
@Id @GeneratedValue(generator="Emp_Gen")
private int id;
GenerationType.TABLE, 采用数据库表策略生成主键
@Column(name="order_id")
//定义表生成器
@TableGenerator(name="ID_GENERATOR", //生成器名称
table="ID_GENERATOR", //生成器使用的表
pkColumnName="PK_NAME", //表中对应的字段名
pkColumnValue="ORDER_ID", //上述字段的值
valueColumnName="PK_VALUE", //值
initialValue=100,
allocationSize=5)//表示主键一次增加5
@GeneratedValue(strategy=GenerationType.TABLE,
generator="ID_GENERATOR")//这里的生成器和上面的生成器名称对应
@Id
public Integer getOrderId() {
return orderId;
}
数据库中定义的生成器使用的表ID_GENERATOR
* 如果希望实体的某个字段不参与映射,可以使用注解@Transient,它 表示该属性并非一个映射到数据库表的字段的映射,这样ORM将忽略这个字段的映射
CRUD操作
1. insert操作,实体管理器的persist()方法,事务提交后,添加到数据库中
public static void main(String[] args) {
//创建实体管理工厂
String persistenUnitName = "jpa";//名称和persistence.xml 的persistence-unit 名称一致
EntityManagerFactory factory = Persistence.createEntityManagerFactory(persistenUnitName);
//创建EntityManager
EntityManager entityManager = factory.createEntityManager();
//开启事务
EntityTransaction transaction = entityManager.getTransaction();
//持久化操作
Product product = new Product();
product.setPrice(new BigDecimal("8.80"));
product.setProductName("火龙果");
product.setProduceAddress("广东南澳");
product.setRemark("火龙果的指定产地");
//添加product到数据库,执行持久化,开启事务
transaction.begin();
entityManager.persist(product);
transaction.commit();
//关闭EntityManager
entityManager.close();
//关闭EntityManagerFactory
factory.close();
}
打印的日志:
Hibernate:
insert
into
product
(price, produce_address, product_name, remark)
values
(?, ?, ?, ?)
2. update操作
在实体的生命周期内,存在一个持久化的状态,并且对持久态的修改,在事务提交后,更新到数据中
如何获取到一个持久态的对象
* 新生对象调用,persist方法
* 查询的方法, 例如find,getreference,query语句等。
//持久化操作
Product product = new Product();
product.setPrice(new BigDecimal("8.80"));
product.setProductName("红富士");
product.setProduceAddress("山东烟台");
product.setRemark("著名苹果品种");
//添加product到数据库,执行持久化,开启事务
transaction.begin();
entityManager.persist(product);
product.setRemark("改下备注。。。");
transaction.commit();
打印日志:
Hibernate:
insert
into
product
(price, produce_address, product_name, remark)
values
(?, ?, ?, ?)
Hibernate:
update
product
set
price=?,
produce_address=?,
product_name=?,
remark=?
where
id=?
3. 删除
实体管理器的remove方法,获取到持久态的对象后,在调用remove方法删除,实体对象进入removed状态,获取持久态的方法和前面一样。
transaction.begin();
Product pd = entityManager.find(Product.class, 3);
entityManager.remove(pd);
transaction.commit();
4. 查询
find 和 getReference方法, 区别
getReference是懒加载,并且如果id不存在getReference方法抛出异常
public static void main(String[] args) {
//创建实体管理工厂
String persistenUnitName = "jpa";//名称和persistence.xml 的persistence-unit 名称一致
EntityManagerFactory factory = Persistence.createEntityManagerFactory(persistenUnitName);
//创建EntityManager
EntityManager entityManager = factory.createEntityManager();
//开启事务
EntityTransaction transaction = entityManager.getTransaction();
//持久化操作
transaction.begin();
//find方法,调用立即查询
Product pd = entityManager.find(Product.class, 11);
//getReference懒加载,用到才回去发送sql查询,并且id没有值时候,报异常
// Product pd2 = entityManager.getReference(Product.class, 2);
// System.out.println(pd2);
transaction.commit();
//关闭EntityManager
entityManager.close();
//关闭EntityManagerFactory
factory.close();
}
5 .连续的两次相同的查询,只会发送一个SQL ,是有由于一级缓存的存在
Order order3 = entityManager.find(Order.class, 125);
System.out.println(order3);
Order order4 = entityManager.find(Order.class, 125);
Hibernate:
select
order0_.order_id as order_id1_12_0_,
order0_.entr_bal as entr_bal2_12_0_,
order0_.remark as remark3_12_0_,
order0_.source_no as source_n4_12_0_,
order0_.user_id as user_id5_12_0_
from
order_info order0_
where
order0_.order_id=?
Order [orderId=125, entrBal=110.25, sourceNo=REC1000098, remark=深圳通充值]