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(); }