hibernate的JPA

  • 2019-05-16
  • 133
  • 2

JPA概述

全称是:Java Persistence API。是SUN公司推出的一套基于ORM的规范。hibernate框架中提供了JPA的实现。JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。,Hibernate中有两套实现数据库数据操作的方式:

  1. hibernate自己的操作方式 (全是xml配置方式)
  2. JPA的操作方式(使用注解来替代之前的部分xml方式)

JPA环境搭建

  • 导入hibernate-entitymanager-5.0.7.Final.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">
	
	<!-- 要求至少得有一个持久化单元(至少得有一个数据库的连接信息) -->
	<persistence-unit name="mysql">
			<!-- mysql的数据库连接信息 -->
			<properties>
				<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
				<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpa"/>
				<property name="hibernate.connection.username" value="root"/>
				<property name="hibernate.connection.password" value="1234"/>
				<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
				
				<property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"/>
				<property name="hibernate.show_sql" value="true"/>
				<property name="hibernate.format_sql" value="true"/>
				<property name="hibernate.hbm2ddl.auto" value="update"/>
			
			</properties>
	</persistence-unit>
	
	
	
	
	<!-- <persistence-unit name="oracle">
			oracle的数据库连接信息
	</persistence-unit>
	
	
	<persistence-unit name="db2">
			db2的数据库连接信息
	</persistence-unit> -->
	
</persistence>

常用注解说明

@Entity
	作用:指定当前类是实体类。写上此注解用于在创建SessionFactory时,加载映射配置。
@Table
	作用:指定实体类和表之间的对应关系。
	属性:
		name:指定数据库表的名称
@Id
	作用:指定当前字段是主键。
@GeneratedValue
	作用:指定主键的生成方式。JPA的主键生成方式详解见2.4小节的说明。
	属性:
		strategy :指定主键生成策略。JPA支持四种生成策略,具体介绍看2.4小节。
@Column
	作用:指定实体类属性和数据库表之间的对应关系
	属性:
		name:指定数据库表的列名称。
		unique:是否唯一  
			nullable:是否可以为空  
			inserttable:是否可以插入  
			updateable:是否可以更新  
			columnDefinition: 定义建表时创建此列的DDL  
			secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字。  

持久化类使用注解配置

package com.husaky.bean;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
//所有的注解都在persistence下
@Entity // 当前类是持久化类
@Table(name="cst_customers") //当前持久化类和哪个表做映射
// 1的一方
public class Customer 
{    @Id //当前的属性是oid属性
	 @Column(name="cust_id") // 和表的哪个字段做映射
	 @GeneratedValue(strategy=GenerationType.IDENTITY) //oid的增长策略
	 private Long cust_id;// '客户编号(主键)',

	 // 其它属性和表中的字段映射
	 @Column(name="cust_name") 
	 private String cust_name;// '客户名称(公司名称)',
	 @Column(name="cust_source") 
	 private String cust_source;// '客户信息来源',
	 @Column(name="cust_industry") 
	 private String cust_industry;//'客户所属行业',
	 @Column(name="cust_level") 
	 private String cust_level;// '客户级别',
	 @Column(name="cust_address") 
	 private String cust_address;// '客户联系地址',
	 @Column(name="cust_phone") 
	 private String cust_phone;// '客户联系电话',
	 
	 
	 // 配置1对多的关系
	 // targetEntity: 对方的字节码文件类型
	 // mappedBy:自己在对方中的属性名    出现哪一方 意味着哪一方不会去维护外键了
	 	/*cascade
	 		  CascadeType.All 即使级联保存 又是级联删除         save-update,delete
	 		  CascadeType.PERSIST 级联保存		 	    save-update
	 		  CascadeType.REMOVE 级联删除				delete
	 		*/
	 			
	 @OneToMany(targetEntity=Linkman.class, mappedBy="customer",cascade=CascadeType.ALL)
	 private Set<Linkman> linkmans=new HashSet<Linkman>();
	 
	 
	 
	public Set<Linkman> getLinkmans() {
		return linkmans;
	}
	public void setLinkmans(Set<Linkman> linkmans) {
		this.linkmans = linkmans;
	}
	public Long getCust_id() {
		return cust_id;
	}
	... 
	 
}

JPA单表CURD操作

public class Demo
{
	@Test  //保存
	public void t1()
	{
		// 加载数据库信息  sessionFactory
		EntityManagerFactory factory = Persistence.createEntityManagerFactory("mysql");
		// 获取连接  session
		EntityManager em = factory.createEntityManager();
		// 开启事务
		EntityTransaction tx = em.getTransaction(); //先获取事务
		tx.begin(); //开启事务
		
		Customer customer = new Customer();
		customer.setCust_name("jack");
		// 相当于save()
		em.persist(customer);
		
		tx.commit();
		em.close();
	
	}
	
	// 查询
	@Test
	public void t2()
	{
		EntityManagerFactory factory = Persistence.createEntityManagerFactory("mysql");
		EntityManager em = factory.createEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		// get()方法 立即加载
		/*Customer customer = em.find(Customer.class,1L);
		System.out.println(customer.getCust_name());*/
		// load()方法 延迟加载
		Customer customer = em.getReference(Customer.class, 1L);
		System.out.println(customer.getCust_name());
		tx.commit();
		em.close();
	}
	
	@Test //修改
		  // 测试jpa中的一级缓存 完全可以使用
	public void t3()
	{
		EntityManagerFactory factory = Persistence.createEntityManagerFactory("mysql");
		EntityManager em = factory.createEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		
		// 先查后改
		Customer customer = em.find(Customer.class, 1L);
		System.out.println(customer.getCust_name());
		customer.setCust_name("rose1111");
		
		// update()
		/*em.merge(customer);*/
		tx.commit();
		em.close();
	}

	@Test
	public void  t4()
	{
		// 加载持久化单元
		EntityManagerFactory factory = Persistence.createEntityManagerFactory("mysql");
		// 获取连接
		EntityManager em = factory.createEntityManager();
		// 开启事务
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		
		// 删除  先查后删
		Customer customer = em.find(Customer.class, 1L);
		// delete()
		em.remove(customer);
		// 提交
		tx.commit();
		// 关闭资源
		em.close();
	}
}

JPA的多种查询

package com.husaky.utils;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class JPAUtils
{
	static EntityManagerFactory factory;
	static
	{
		factory = Persistence.createEntityManagerFactory("mysql");
	}
	
	// 返回一个连接
	public static EntityManager getEntityManager()
	{
		return factory.createEntityManager();
	}
}

public class Demo2 
{
	// 全查
		// JPA方式: 类似query的方式
	@Test
	public void test1()
	{
		EntityManager em = JPAUtils.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		
		// 全查  from 类名
		Query qr = em.createQuery("from Customer");
		List<Customer> list = qr.getResultList(); // 之前的list()
		for (Customer customer : list) {
			System.out.println(customer);
		}
		tx.commit();
		em.close();
	}
	
	// 条件查
	@Test
	public void test2()
	{
		EntityManager em = JPAUtils.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		// 条件查  from 类 where 属性名
		Query qr = em.createQuery("from Customer where cust_name like ?");
		qr.setParameter(1, "b%"); // hibernate对于占位符?是从0开始 JPA是从1开始
		List<Customer> list = qr.getResultList();
		for (Customer customer : list) {
			System.out.println(customer);
		}
		tx.commit();
		em.close();
	}
	
	
	// 聚合查
	@Test
	public void test3()
	{
		EntityManager em = JPAUtils.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		
		Query qr = em.createQuery("select count(*) from Customer");
		Object obj = qr.getSingleResult(); // uniqueResult()
		System.out.println(obj);
		tx.commit();
		em.close();
	}
	
	
	
	
	
	@Test
	public void test()
	{
		EntityManager em = JPAUtils.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		
		// 分页查
		Query qr = em.createQuery("from Customer");
		qr.setFirstResult(1);
		qr.setMaxResults(3);
		List<Customer> list = qr.getResultList();
		for (Customer customer : list) {
			System.out.println(customer);
		}
		tx.commit();
		em.close();
	}
	
}

JPA一对多操作

package com.husaky.bean;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

// N
@Entity
@Table(name="cst_linkman")
public class Linkman
{
	  @Id
	  @Column(name="lkm_id")
	  @GeneratedValue(strategy=GenerationType.IDENTITY)
	  private Long lkm_id;// '联系人编号(主键)',
	 
	  @Column(name="lkm_name")
	  private String lkm_name;// '联系人姓名',
	  
	  @Column(name="lkm_gender")
	  private String lkm_gender;// '联系人性别',
	 
	  @Column(name="lkm_phone")
	  private String lkm_phone;// '联系人办公电话',
	  
	  @Column(name="lkm_mobile")
	  private String lkm_mobile;// '联系人手机',
	  
	  @Column(name="lkm_email")
	  private String lkm_email;// '联系人邮箱',
	  
	  @Column(name="lkm_position")
	  private String lkm_position;// '联系人职位',
	 
	  @Column(name="lkm_memo")
	  private String lkm_memo;// '联系人备注',
	  
	  
	  // 配置1对多的关系
	  // 有一个客户的对象
	  //targetEntity:对方的字节码文件对象类型
	  @ManyToOne(targetEntity=Customer.class)
	  // 维护外键关系
	  /*name:外键字段名
	  referencedColumnName:指向的主键字段名*/
	  @JoinColumn(name="wj_id",referencedColumnName="cust_id")
	  private Customer customer;

	...

// JPA的一对多的
public class Demo3 
{
	@Test // 普通保存 
	public void test1()
	{
		EntityManager em = JPAUtils.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		// 保存一个客户3个联系人
		Customer customer = new Customer();
		customer.setCust_name("马总");
		
		Linkman linkman1 = new Linkman();
		linkman1.setLkm_name("大秘");
		Linkman linkman2 = new Linkman();
		linkman2.setLkm_name("中秘");
		Linkman linkman3 = new Linkman();
		linkman3.setLkm_name("小秘");
		
		// 双向关联(固定)
		customer.getLinkmans().add(linkman1);
		customer.getLinkmans().add(linkman2);
		customer.getLinkmans().add(linkman3);

		linkman1.setCustomer(customer);
		linkman2.setCustomer(customer);
		linkman3.setCustomer(customer);
		
		// 保存
		em.persist(customer);
		em.persist(linkman1);
		em.persist(linkman2);
		em.persist(linkman3);
		
		tx.commit();
		em.close();	
	}
	
	@Test //级联:在操作自己数据的时候 还会把自己关联的数据也操作了
		  // 级联保存  保存客户同时把客户下面的联系人都保存了
		  // @OneToMany(cascade=CascadeType.PERSIST)
	public void test2()
	{
		EntityManager em = JPAUtils.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		// 保存一个客户3个联系人
		Customer customer = new Customer();
		customer.setCust_name("马总");
		
		Linkman linkman1 = new Linkman();
		linkman1.setLkm_name("大秘");
		Linkman linkman2 = new Linkman();
		linkman2.setLkm_name("中秘");
		Linkman linkman3 = new Linkman();
		linkman3.setLkm_name("小秘");
		
		// 双向关联(固定)
		customer.getLinkmans().add(linkman1);
		customer.getLinkmans().add(linkman2);
		customer.getLinkmans().add(linkman3);

		linkman1.setCustomer(customer);
		linkman2.setCustomer(customer);
		linkman3.setCustomer(customer);
		
		// 保存
		em.persist(customer);
		
		tx.commit();
		em.close();
		
	}
	
	@Test //普通删除--报错
	public void test3()
	{
		EntityManager em = JPAUtils.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		// 删除一个客户
		Customer customer = em.find(Customer.class, 1L);
		em.remove(customer);
		tx.commit();
		em.close();
	}
	
	@Test // 级联删除
	public void test()
	{
		EntityManager em = JPAUtils.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		// 删除一个客户级联下面关联的联系人
		Customer customer = em.find(Customer.class, 2L);
		em.remove(customer);
		tx.commit();
		em.close();
	}
	
}


JPA多对多

两个持久化类

// 角色 N
@Entity
@Table(name="sys_role")
public class Role 
{
	@Id
	@Column(name="role_id")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Long role_id; // 主键
	@Column(name="role_name")
	private String role_name; // '角色名称',
	@Column(name="role_memo")
	private String role_memo; // '备注',
	
	
	// 配置多对多
	// 有user的集合
	/*targetEntity:对象的字节码文件对象
	mappedBy:自己在对方中的属性名
	*/
	@ManyToMany(targetEntity=User.class,mappedBy="roles")
	private Set<User> users=new HashSet<User>();
	
	public Set<User> getUsers() {
		return users;
	}
	public void setUsers(Set<User> users) {
		this.users = users;
	}
...
	
	
}

// 用户  N
@Entity
@Table(name="sys_user")
public class User 
{
	@Id
	@Column(name="user_id")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Long user_id;// '用户id',
	
	@Column(name="user_code")
	private String user_code;// '用户账号',
	@Column(name="user_name")
	private String user_name;// '用户名称',
	@Column(name="user_password")
	private String user_password;// '用户密码',
	@Column(name="user_state")
	private String user_state;//'1:正常,0:暂停',	
	
	
	// 配置多对多的关系
	// 有Role的集合
	@ManyToMany(targetEntity=Role.class,cascade=CascadeType.PERSIST)
	// 维护外键
	/*name: 中间表的名称
	joinColumns: 自己在中间表的配置
	inverseJoinColumns:	对方在中间表的配置
	*/
	@JoinTable(name="sys_user_role",
				joinColumns={
						// name:自己在中间表的外键字段名
						// referencedColumnName: 指向自己的主键字段名
						@JoinColumn(name="user_id",referencedColumnName="user_id")
				},
				inverseJoinColumns={
						/*name:对方在中间表的外键字段名
						referencedColumnName:指向对方的主键字段名*/
						@JoinColumn(name="role_id",referencedColumnName="role_id")
				})
	private Set<Role> roles=new HashSet<Role>();
	
	
	
	public Set<Role> getRoles() {
		return roles;
	}
	public void setRoles(Set<Role> roles) {
		this.roles = roles;
	}
	public Long getUser_id() {
		return user_id;
	}
...
	
}

测试

//JPA的多对多
public class Demo4
{
	@Test // 普通保存   
	public void test1()
	{
		EntityManager em = JPAUtils.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		// 2个用户 3个角色
		User user1 = new User();
		user1.setUser_name("jack");
		User user2 = new User();
		user2.setUser_name("rose");
		
		Role role1 = new Role();
		role1.setRole_name("员工");
		Role role2 = new Role();
		role2.setRole_name("班主任");
		Role role3 = new Role();
		role3.setRole_name("助教");
		
		// 双向关联
		user1.getRoles().add(role1);
		user1.getRoles().add(role2);
		user2.getRoles().add(role1);
		user2.getRoles().add(role3);
		
		role1.getUsers().add(user1);
		role1.getUsers().add(user2);
		role2.getUsers().add(user1);
		role3.getUsers().add(user2);
		
		// 保存
		em.persist(user1);
		em.persist(user2);
		em.persist(role1);
		em.persist(role2);
		em.persist(role3);
		
		tx.commit();
		em.close();
	}
	
	@Test // 级联保存 
		//@ManyToMany(targetEntity=Role.class,cascade=CascadeType.PERSIST)
	public void test2()
	{
		EntityManager em = JPAUtils.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		// 2个用户 3个角色
		User user1 = new User();
		user1.setUser_name("jack");
		User user2 = new User();
		user2.setUser_name("rose");
		
		Role role1 = new Role();
		role1.setRole_name("员工");
		Role role2 = new Role();
		role2.setRole_name("班主任");
		Role role3 = new Role();
		role3.setRole_name("助教");
		
		// 双向关联
		user1.getRoles().add(role1);
		user1.getRoles().add(role2);
		user2.getRoles().add(role1);
		user2.getRoles().add(role3);
		
		role1.getUsers().add(user1);
		role1.getUsers().add(user2);
		role2.getUsers().add(user1);
		role3.getUsers().add(user2);
		
		// 保存用户的时候级联保存角色
		em.persist(user1);
		em.persist(user2);
		
		tx.commit();
		em.close();
	}
	
	@Test  
	// 多对多以后操作的方向性
	// 给一个用户修改角色
	public void test3()
	{
		EntityManager em = JPAUtils.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		// 操作 给jack用户将员工修改成助教
		// 获取jack
		User user = em.find(User.class, 1L);
		// 获取员工
		Role role1 = em.find(Role.class,2L);
		// 获取助教
		Role role3 = em.find(Role.class,3L);
		// 删除员工
		user.getRoles().remove(role1);
		// 添加助教
		user.getRoles().add(role3);
		tx.commit();
		em.close();
	}
	
	@Test  //普通删除
	public void test5()
	{
		EntityManager em = JPAUtils.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		
		User user = em.find(User.class, 1L);
		em.remove(user);
		tx.commit();
		em.close();
	}
	
	
}

评论

粤ICP备17155863号

- 友情链接 - Theme by Qzhai