注解
//Hibernate 的 HQL 查询功能支持命名参数。这使得 HQL 查询功能既能接受来自用户的简单输入,又无需防御 SQL 注入攻击
String hql = "UPDATE Employee set salary = :salary " +
"WHERE id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("salary", 1000);
query.setParameter("employee_id", 10);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);
主键生成策略
例如:<generator class = “native” / >
注解(对于PO类中所有属性,如果你不写注解,默认情况下也会在表中生成对应的列,列的名称就是属性的名称,列的类型也即属性的类型)
@Entity:声明一个实体
Table(name=“table_name”):来描述类与表之间的对应关系
@id:声明一个主键(double和float浮点类型和它们对应的封装类不能作为主键,这是因为判断是否唯一是通过equals方法来判断的,不能够准确的匹配)
@GeneratedValue(strategy=GenerationType.AUTO):用它来声明一个主键生成策略。
@Column:定义列
@Transient:创建数据库时,忽略该字段,不创建
@Temporal(TemporalType.Date):声明日期类型
JPA API
/*
加载配置文件创建实体管理工厂
根据实体管理工厂,创建实体管理器
创建事务对象,开启事务
增删改查操作
提交事务
释放资源
*/
@Test
public void testApplicationEntityManager() {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("MyJPA");
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
User user = new User();
user.setName("hly");
//以上两行为新建状态
//托管状态
em.persist(user);
//事务提交或调用flush()方法后会同步到数据库
em.getTransaction().commit();
//根据主键获取对象
//System.err.println(em.find(User.class,1));
//System.err.println(em.getReference(User.class,1));
em.close();
entityManagerFactory.close();
}
/*
1. Persistence
Persistence 类是用于获取 EntityManagerFactory 实例。该类包含一个名为 createEntityManagerFactory 的 静态方法 。
2. EntityManagerFactory
EntityManagerFactory 接口主要用来创建 EntityManager 实例。
3. EntityManager
在 JPA 规范中, EntityManager 是完成持久化操作的核心对象。实体作为普通 Java 对象,只有在调用 EntityManager 将其持久化后才会变成持久化对象。EntityManager 对象在一组实体类与底层数据源之间进行 O/R 映射的管理。它可以用来管理和更新 Entity Bean, 根椐主键查找 Entity Bean, 还可以通过JPQL语句查询实体。
------------------------------------------------------------------
实体的状态分为:
新建状态: 新创建的对象,尚未拥有持久性主键。
持久化状态:已经拥有持久性主键并和持久化建立了上下文环境
游离状态:拥有持久化主键,但是没有与持久化建立上下文环境
删除状态: 拥有持久化主键,已经和持久化建立上下文环境,但是从数据库中删除。
4. EntityTransaction
*/
关联映射
- 单向多对一关联
@ManyToOne
@JoinColumn(name="c_id")
/*
注解@ManyToOne(fetch=FetchType.EAGER)默认的是立即加载,需要懒加载的时候,要加fetch参数修改. 可以使用targetEntity属性指定关联实体类型 @ManyToOne(targetEntity=Classes.class)
*/
- 单向一对多关联
@OneToMany(targetEntity=xxx.class,cascade={CascadeType.REMOVE})
@JoinColumn(name="c_id")
/*
注解@OneToMany(fetch=FetchType.LAZY)默认的是懒加载,需要懒加载的时候,要加fetch参数修改,使用@JoinColumn(name=“c_id”) 设置关联外键
*/
- 双向的一对多的关联
//一的这端:Classes
//mappedBy: 设置关联的外键 避免出现中间表
@OneToMany(mappedBy="classInfo",fetch=FechType.EAGER,cascade={CascadeType.REMOVE})
//多的一端:student
@ManyToOne
@JoinColumn(name="c_id")
/*
①双向关联关系,两遍默认都会维护关系,可能冲突,也影响效率,正常情况关系交给“多”的一端维护,一的这端@OneToMany(mappedBy=“classes”,这个属性放弃关系维护
②一旦使用 mappedBy属性,那么@JoinColumn这个注解就不能使用了,用了会出错
*/
- 双向多对多的关联
//*student 表:*
@ManyToMany
@JoinTable(name="course",
joinColumns={@JoinColumn(name=:sid",referencedColumnName="stu_id")},
inverseJoinColumns=:@JoinColumn(name="sid",referencedColumnName="sid")})
/*
@JoinTable(name="中间表",
joinColumns={@JoinColumn(name="当前对象在中间表的外键名",referencedColumnName="当前对象表的主键")},
inverseJoinColumns={@JoinColumn(name="关联表在中间表的外键名",referencedColumnName="关联表的主键")})
*/
//Student这边维护关系,subject就要放弃关系的维护,使用mappedBy将维护权交给另外一方
//*subject 表*
@ManyToMany(mappedBy="subjects")
//处理双向多对多的关联,还可以将对对多关联,转换为两个一对多的关联