hibernate JPA学习
文章目录
jpa环境搭建
第一步:拷贝Hibernate的全部jar包到工程中,并且加入jar实现包。
第二步:创建主配置文件
要求:在src下面的META-INF文件夹下面创建一个名称为persistence.xml的文件。
<?xml version="1.0" encoding="UTF-8"?>
<persistence 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"
version="2.0">
<!-- 配置持久化单元,可以配置多个,但是名称不能重复
name:用于指定持久化单元名称
transaction-type:指定事务的类型。
JTA:Java Transaction API
RESOURCE_LOCAL:指的是本地代码事务。(我们用这个)
-->
<persistence-unit name="myJPAUnit" transaction-type="RESOURCE_LOCAL">
<!-- JPA规范的提供商 可以不写。-->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<!-- 指定由Jpa注解的实体类位置 可以不写。-->
<class>com.itheima.domain.Customer</class>
<!-- 连接库相关的一些配置,都是用hibernate的,所以只需要把之前hibernate主配置文件中的部分内容拷贝过来即可 -->
<properties>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/day58_ee287_jpa"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value="1234"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/><!-- 数据库的方言 -->
<!-- 第二部分:hibernate的可选配置 -->
<!-- 是否显示hibernate生成的SQL语句 -->
<property name="hibernate.show_sql" value="true"/>
<!-- 是否使用格式化输出sql语句到控制台 -->
<property name="hibernate.format_sql" value="false"/>
<!-- 配置hibernate采用何种方式生成DDL语句 -->
<property name="hibernate.hbm2ddl.auto" value="update"/><!-- update表示检测实体类的映射配置和数据库的表结构是否一致,如果不一致,更新表结构 -->
<!-- 设置hibernate的连接池提供商 -->
<property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"/>
</properties>
</persistence-unit>
</persistence>
第三步:编写实体类并使用注解配置
package com.itheima.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* 客户的实体类
* @author zhy
* 使用的注解都是JPA规范,所以导包,都需要导入javax.persistence包下的
*/
@Entity//表明该类是一个实体类
@Table(name="cst_customer")//建立当前类和数据库表的对应关系
public class Customer implements Serializable {
@Id//表明当前字段是主键
@Column(name="cust_id")//表明对应数据库的主键字段是cust_id
//strategy:使用JPA中提供的主键生成策略。此属性用不了uuid。generator属性可以使用hibernate中的主键生成策略
@GeneratedValue(strategy=GenerationType.IDENTITY)//指定主键生成策略。
//声明一个主键生成器name属性:给生成器起个名字。strategy:指定的就是hibernate中包含的生成策略
//@GenericGenerator(name="uuid",strategy="uuid")
//@GeneratedValue(generator="uuid")
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;
}
第四步:编写工具类,用于获取JPA的操作数据库对象
public final class JPAUtil {
//JPA的实体管理器工厂:相当于Hibernate的SessionFactory
private static EntityManagerFactory em;
//使用静态代码块赋值
static {
//注意:该方法参数必须和persistence.xml中persistence-unit标签name属性取值一致
em = Persistence.createEntityManagerFactory("myPersistUnit");
}
/**
* 使用管理器工厂生产一个管理器对象
* @return
*/
public static EntityManager getEntityManager() {
return em.createEntityManager();
}
}
jpa入门案例
@Test
public void testAdd() {
// 定义对象
Customer c = new Customer();
c.setCustName("传智学院");
// 获取实体管理对象
EntityManager em = JpaUtils.getEntityManager();
// 获取事务对象
EntityTransaction tx = em.getTransaction();
// 开启事务
tx.begin();
// 执行操作
em.persist(c);
// 提交事务
tx.commit();
// 释放资源
em.close();
}
JPA的CRUD操作
查询一个
//立即加载不能修改为延迟
Customer c = em.find(Customer.class, 1L);
//延迟加载不能修改为立即
Customer c1 = em.getReference(Customer.class, 112l);
查询所有
JPQL的写法:
* 表名使用实体类名称替代
* 列名使用实体类属性名称替代
* 不能使用*号。查询所有,需要在from关键字后面的类名上加别名
* 例如: select c from Customer c
* 查询条件可以使用?作为参数占位符。
* 给占位符赋值时,占位符索引位置从1开始
* 获取结果集的方法
* getResultList():查询结果是一个List集合
* getSingleResult():查询结果是一个对象
Query query = em.createQuery("select c from Customer c where custName like ? ");
query.setParameter(1,"%学院%");
List list = query.getResultList();
更新一个
当一个session保存具有相同的oid对象时
直接用hibernate的update会报错;
这时我们用em.merge(ustomer)
Customer c = em.find(Customer.class, 1L);
c.setCustName("江苏传智学院");
//提交事务
tx.commit(); //使用JPA中快照机制实现更新
删除一个
Customer c = em.find(Customer.class, 6L);
em.remove(c);
JPA的多表映射
一对多关系映射
客户配置
@OneToMany(targetEntity=LinkMan.class,mappedBy="customer"//放弃维护关联关系)
private Set<LinkMan> linkmans = new HashSet<LinkMan>(0);
联系人配置
@ManyToOne(targetEntity=Customer.class)
@JoinColumn(name="lkm_cust_id",referencedColumnName="cust_id")
private Customer customer;//用它的主键,对应联系人表中的外键
保存操作
创建一个客户和一个联系人
建立客户和联系人的双向关联关系
先保存客户,再保存联系人,保存成功
如果只保存客户,没级联,因为客户放弃维护关联关系,就只保存了客户
有级联则保存成功
如果只保存联系人,有级联则保存成功,
没有级联则保存失败,因为持久态对象关联一个临时态,请先保存临时态
更新操作
创建一个联系人
查询id为5的客户
为5这个客服分配该联系人
更新客户 放弃维护关联关系,运行成功,数据库没变化
更新客户 不放弃维护关联关系,报错,因为持久态对象关联一个临时态,请先保存临时态
这时需要级联保存cascade=CascadeType.PERSIST
删除操作
删除客户
如果客户放弃维护关联关系,删除报错,因为客户放弃关联关系就不会修改外键为null
如果客户不放弃维护关联关系,删除成功,外键修改为null;
或者级联删除
查询操作
它可以使用对象导航的方式customer.getLinkmans()
一的一方默认懒加载,fetch=FetchType.EAGER
立即加载,
多的一方默认立即加载
多对多关系映射
用户配置
用户和角色俩配置可以互换
@ManyToMany(mappedBy="users",cascade=CascadeType.ALL)
private Set<SysRole> roles = new HashSet<SysRole>(0);
角色配置
@ManyToMany(cascade=CascadeType.ALL)
//加入一张表
@JoinTable(name="user_role_ref",
joinColumns={@JoinColumn(name="role_id",referencedColumnName="role_id")},//写的是当前实体在中间表的外键字段
inverseJoinColumns={@JoinColumn(name="user_id",referencedColumnName="user_id")}//写的是对方实体在中间表的外键字段
)
private Set<SysUser> users = new HashSet<SysUser>(0);
保存操作
如果只保存用户,没级联,因为用户放弃维护关联关系,就只保存了用户
有级联则成功
如果只保存角色,有级联则保存成功,
没有级联则保存失败
删除操作
多对多都不能配置级联删除
JPA中使用c3p0连接池
和hibernate中使用方法一样
把EntityManager和线程绑定
1.与spring整合
暂时不讲
2.当事务类型为JTA时
这个方法可以,好像不怎么用
entityManagerFactory.createEntityManager(SynchronizationType.SYNCHRONIZED);
3.自己手写
private static EntityManagerFactory entityManagerFactory;
private static ThreadLocal<EntityManager> EntityManager = new ThreadLocal<>();
static {
entityManagerFactory = Persistence.createEntityManagerFactory("myJPAUnit");
}
public static EntityManager getTLEntityManager() {
EntityManager entityManager = EntityManager.get();
if (entityManager == null) {
entityManager = entityManagerFactory.createEntityManager();
EntityManager.set(entityManager);
}
return EntityManager.get();
}
}
hibernate中使用jpa注解映射配置
只需这一步就OK
<!–第三部分:映射配置文件的位置–>
<mapping class="com.itheima.domain.Customer"/>
上一篇: 室友爆笑,每次看到你,总是笑声起
下一篇: 风中飘落的相思
推荐阅读
-
canvas游戏开发学习之五:运用样式与颜色(一)
-
php学习笔记之 函数声明_php基础
-
javascript学习笔记(二十) 获得和设置元素的特性(属性)_基础知识
-
YII Framework学习之request与response用法(基于CHttpRequest响应),yiichttprequest_PHP教程
-
nginx学习心得
-
php学习心得
-
升级Hibernate3.5:javax.persistence.OneToMany.orphanRemoval()Z HibernateJavaNoSuchMethodErrororphanRemovalOneToMany
-
MySQL入门学习(3)_MySQL
-
PHP笔记学习节选(创世纪新篇)
-
hibernate基础 PHP 数组基础知识小结