2021-01-27

什么是ORM

Object relational Mapping 对象关系映射!ORM是一种持久层的开发思想
在这里插入图片描述

什么是ORM

1、java开发者不需要关注SQL语句
2、非常方便进行关联关系操作(一对一,一对多,多对多)
3、底层封装JDBC,封装了重复的JDBC操作

JPA是什么

JPA与Hibernate等ORM框架的关系

在这里插入图片描述
JPA :是ORM的规范(一套接口)(不干活的)
Hibernate:是一种流行的ORM实现(干活的)

JPA简介

JPA的全称是JAVA Persistence API 即Java 持久化API,是SUN公司推出的一套基于ORM的规范,内部是由一系列的接口和抽象类构成。
JPA通过JDK5.0注解描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中

二话不说上代码

数据库
    CREATE TABLE customer (
      cust_id BIGINT(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
      cust_name VARCHAR(32) NOT NULL COMMENT '客户名称(公司名称)',
      cust_source VARCHAR(32) DEFAULT NULL COMMENT '客户信息来源',
      cust_industry VARCHAR(32) DEFAULT NULL COMMENT '客户所属行业',
      cust_level VARCHAR(32) DEFAULT NULL COMMENT '客户级别',
      cust_address VARCHAR(128) DEFAULT NULL COMMENT '客户联系地址',
      cust_phone VARCHAR(64) DEFAULT NULL COMMENT '客户联系电话',
      PRIMARY KEY (`cust_id`)
    ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
    
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.jsonString</groupId>
  <artifactId>springdatajpa_demo01_01_jpa</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  
  <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.hibernate.version>5.0.7.Final</project.hibernate.version>
    </properties>

    <dependencies>
        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!-- hibernate对jpa的支持包 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${project.hibernate.version}</version>
        </dependency>

        <!-- c3p0 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-c3p0</artifactId>
            <version>${project.hibernate.version}</version>
        </dependency>

        <!-- log日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <!-- Mysql and MariaDB -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
    </dependencies>
  
</project>
配置文件
<?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">
	<!-- 让Hibernate维护表结构 -->
	<!-- persistence-unit:持久化单元,类似于数据源
		name:单元名称,一个项目必须唯一的
		transaction-type:事务类型
			JTA:分布式事务(多个数据库的操作)
			RESOURCE_LOCAL:本地事务(只有一个数据库的操作)	
	 -->
	 <persistence-unit name="jsonStringJpa" transaction-type="RESOURCE_LOCAL" >
	 	<!-- provider:Jpa的具体提供商(ORM实现) -->
	 	<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
	 
		 <!--数据库连接属性-->
		 <properties>
		 	<property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1/springdatajpa_2021?characterEncoding=utf8"/>
		 	<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
		 	<property name="javax.persistence.jdbc.user" value="root"/>
		 	<property name="javax.persistence.jdbc.password" value="albee1222"/>
		 	<!-- 查看hibernate生成的sql语句方便调试 -->
		 	<property name="hibernate.show_sql" value="true"/>
		 	
		 	 <!--让hibernate维护表结构  
		 	create:每次先删除表,再创建表
		 	update:有表,判断表有无改变,如果有,修改表;如果没有,什么也不干
		 	nont:什么都不干
		 -->
		 <property name="hibernate.hbm2ddl.auto" value="update"/>
		 </properties>
	 </persistence-unit>
</persistence>
工具类
package com.jsonString.util;

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

/**
 * Jpa工具类
 * @author 16427
 *
 */
public class JpaUtil {
	//保证一个项目一个工厂
	private static EntityManagerFactory factory=null;
	/**
	 * 创建工厂,只创建1次
	 */
	static {
		factory=Persistence.createEntityManagerFactory("jsonStringJpa");
	}
	/**
	 * 每次获取EntityManager来使用
	 */
	public static EntityManager getEntityManager() {
		return factory.createEntityManager();
	}
}

实体类
package com.jsonString.pojo;

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;

/**
 * 客户实体类
 */
@Entity //标记,代表开始映射此类
@Table(name="customer")  //映射表
public class Customer implements Serializable {
	@Id //映射主键
	//此种策略适用于有数据库自动增长的策略:auto_increment:mysql数据库(Orcle没有自增长策略的)
	//@GeneratedValue(strategy=GenerationType.IDENTITY) //主键生成策略.IDENTITY:利用数据库自增策略
	
	//@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="aaaa")//序列机制数据库:oracle
	
	//@GeneratedValue(strategy=GenerationType.TABLE)//适用于没有自动增长策略和序列机制的数据库 性能不好
	@Column(name="cust_id") //映射字段
    private Long custId;
	@Column(name="cust_name")
    private String custName;
	@Column(name="cust_source")
    private String custSource;
	@Column(name="cust_level")
    private String custLevel;
	@Column(name="cust_industry")
    private String custIndustry;
	@Column(name="cust_address")
    private String custAddress;
	@Column(name="cust_phone")
    private String custPhone;
    //省略get和set
	public Long getCustId() {
		return custId;
	}
	public void setCustId(Long custId) {
		this.custId = custId;
	}
	public String getCustName() {
		return custName;
	}
	public void setCustName(String custName) {
		this.custName = custName;
	}
	public String getCustSource() {
		return custSource;
	}
	public void setCustSource(String custSource) {
		this.custSource = custSource;
	}
	public String getCustLevel() {
		return custLevel;
	}
	public void setCustLevel(String custLevel) {
		this.custLevel = custLevel;
	}
	public String getCustIndustry() {
		return custIndustry;
	}
	public void setCustIndustry(String custIndustry) {
		this.custIndustry = custIndustry;
	}
	public String getCustAddress() {
		return custAddress;
	}
	public void setCustAddress(String custAddress) {
		this.custAddress = custAddress;
	}
	public String getCustPhone() {
		return custPhone;
	}
	public void setCustPhone(String custPhone) {
		this.custPhone = custPhone;
	}
	@Override
	public String toString() {
		return "Customer [custId=" + custId + ", custName=" + custName + ", custSource=" + custSource + ", custLevel="
				+ custLevel + ", custIndustry=" + custIndustry + ", custAddress=" + custAddress + ", custPhone="
				+ custPhone + "]";
	}
	
	
    
}
package com.jsonString.pojo;

public class CustomerVo {
	private String custLevel;
	private Long custCount;
	public String getCustLevel() {
		return custLevel;
	}
	public void setCustLevel(String custLevel) {
		this.custLevel = custLevel;
	}
	public Long getCustCount() {
		return custCount;
	}
	public void setCustCount(Long custCount) {
		this.custCount = custCount;
	}
	@Override
	public String toString() {
		return "CustomerVo [custLevel=" + custLevel + ", custCount=" + custCount + "]";
	}
	public CustomerVo(String custLevel, Long custCount) {
		super();
		this.custLevel = custLevel;
		this.custCount = custCount;
	}
	public CustomerVo() {
		super();
	}
	
	
}

单元测试
package com.jsonString.test;

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

import org.junit.Test;

import com.jsonString.pojo.Customer;
import com.jsonString.util.JpaUtil;

public class Demo1 {
	@Test
	public void test1() {//注意:使用该方法一定要有主键策略
		//1.创建实体管理器工厂(类似于mybatis的SqlSessionFactory)
		EntityManagerFactory factory=Persistence.createEntityManagerFactory("jsonStringJpa");
		//2.创建实体管理器(类似于mybatis的SqlSession)
		EntityManager em=factory.createEntityManager();
		//3.获取事务对象(增删改操作需要事务,查询不需要)
		EntityTransaction tx=em.getTransaction();
		//4.开启事务
		tx.begin();
		//5.执行操作
		Customer cust=new Customer();
		cust.setCustName("jsonString0642");
		cust.setCustIndustry("IT");
		cust.setCustLevel("VIP");
		em.persist(cust);
		//6.提交事务
		tx.commit();
		//7.释放资源
		em.close();
		factory.close();
	}
	@Test
	public void test() {
		//1、加载配置文件创建实体类管理器工厂
		EntityManagerFactory factory=Persistence.createEntityManagerFactory("jsonStringJpa");
		//2、根据实体类管理器工厂创建实体类管理器
		EntityManager em=factory.createEntityManager();
		//3、获取事务对象
		EntityTransaction tx=em.getTransaction();
		//4、开启事务
		tx.begin();
		//5、保存客户实体
		Customer c=new Customer();
		c.setCustId(3L);//没有主键策略要自己指定主键
		c.setCustName("jsonString没有主键策略");
		c.setCustLevel("白金VIP");
		em.persist(c);
		//6、提交事务
		tx.commit();
		//7、释放资源
		em.close();
		factory.close();
	}
	/**
	 * 使用JpaUtil工具类
	 */
	@Test
	public void test2() {
		//1.从工具获取EntityManager
		EntityManager em=JpaUtil.getEntityManager();
		//2.获取事务对象(增删改操作需要事务,查询不需要事务)
		EntityTransaction tx=em.getTransaction();
		try {
			//3.开启事务
			tx.begin();
			//4.执行操作
			Customer cust=new Customer();
			cust.setCustId(15L);
			cust.setCustName("jsonStringJpaUtil");
			cust.setCustIndustry("工厂");
			cust.setCustLevel("VIP");
			em.persist(cust);
			//5.提交事务
			tx.commit();
		}catch(Exception e) {
			e.printStackTrace();
			//6.事务回滚
			tx.rollback();
		}finally {
			//7.释放资源
			em.close();
		}
	}
	/**
	 * 查询一个(不需要事务)
	 */
	@Test
	public void test3() {
		EntityManager em=JpaUtil.getEntityManager();
		try {
			//find();立刻加载方式
			//Customer cust=em.find(Customer.class, 11L);
			//getReference();延迟加载方式。什么是延迟加载?没有用到就不查询数据库,用到就查询数据库
			Customer cust=em.getReference(Customer.class, 11L);
			System.out.println(cust);
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			//7.释放资源
			em.close();
		}
	}
	/**
	 * 修改
	 */
	@Test
	public void test4() {
		EntityManager em=JpaUtil.getEntityManager();
		EntityTransaction tx=em.getTransaction();
		try {
			tx.begin();
			/**
			 * 1)直接修改(项目中大部分都采用这种方式)
			 * 2)先查询,再修改
			 */
			//1直接修改
			/*Customer cust=new Customer();
			cust.setCustId(11L);
			cust.setCustName("JsonString修改");*/
			//2.先查询,再修改
			Customer cust=em.find(Customer.class, 11L);
			cust.setCustName("JsonString先查询再修改");
			em.merge(cust);
			tx.commit();
		}catch(Exception e) {
			e.printStackTrace();
			tx.rollback();
		}finally {
			em.close();
		}
	}
	/**
	 * 删除
	 */
	@Test
	public void test5() {
		EntityManager em=JpaUtil.getEntityManager();
		EntityTransaction tx=em.getTransaction();
		try {
			tx.begin();
			//必须先查询再删除
			Customer cust=em.find(Customer.class, 11L);
			//Customer cust=new Customer();
			//cust.setCustId(11L);
			em.remove(cust);
			tx.commit();
		}catch(Exception e) {
			e.printStackTrace();
			tx.rollback();
		}finally {
			em.close();
		}
	}

}

package com.jsonString.test;


import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.junit.Test;

import com.jsonString.pojo.Customer;
import com.jsonString.pojo.CustomerVo;
import com.jsonString.util.JpaUtil;

/**
 * 演示Jpa的查询操作
 * @author 16427
 *
 */
public class Demo2 {
	//全部数据查询
	@Test
	public void test2() {
		EntityManager em=JpaUtil.getEntityManager();
		try {
			//1.创建Query对象,进行JPQL
			//String jpql="select c from Customer c";//完整的写法
			String jpql="from Customer";//简化写法
			Query query=em.createQuery(jpql);
			//2.取出并封装数据
			List<Customer> list=query.getResultList();
			for(Customer cust:list) {
				System.out.println(cust);
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			//7.释放资源
			em.close();
		}
	}
	//分页查询数据
	@Test
	public void test3() {
		EntityManager em=JpaUtil.getEntityManager();
		try {
			String jpql="from Customer";//简化版本
			Query query=em.createQuery(jpql);
			//模拟页面参数
			int pageNum=2;
			int pageSize=2;
			//获取结果之前,设置分页参数
			query.setFirstResult((pageNum-1)*pageSize);//查询起始行号,从零开始
			query.setMaxResults(pageSize);//页面大小
			List<Customer> list=query.getResultList();
			for(Customer cust:list) {
				System.out.println(cust);
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			em.close();
		}
	}
	/**
	 * 条件查询数据 -- 精准查询
	 */
	@Test 
	public void test4() {
		EntityManager em=JpaUtil.getEntityManager();
		try {
			//第一种占位方式:名称
			//String jpql="from Customer where custName=:abc";
			//第二种占位方式:?序号(推荐使用)
			String jpql="from Customer where custName=?1 and custLevel = ?2";
			Query query= em.createQuery(jpql);
			//设置参数
			//query.setParameter("abc", "jsonString没有主键策略");//第一种占位方式:名称
			query.setParameter(1, "jsonStringJpaUtil");
			query.setParameter(2, "VIP");
			List<Customer> list=query.getResultList();
			for(Customer cust:list) {
				System.out.println(cust);
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			em.close();
		}
	}
	/**
	 * 条件查询数据--模糊查询
	 *
	 */
	@Test
	public void test5() {
		EntityManager em=JpaUtil.getEntityManager();
		try {
			String jpql="from Customer where custName like ?1";
			Query query=em.createQuery(jpql);
			query.setParameter(1, "%Json%");
			List<Customer> list=query.getResultList();
			for(Customer cust:list) {
				System.out.println(cust);
				
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			em.close();
		}
	}
	/**
	 * 排序查询数据
	 */
	@Test
	public void test6() {
		EntityManager em=JpaUtil.getEntityManager();
		try {
			String jpql="from Customer order by custId desc";
			Query query=em.createQuery(jpql);
			List<Customer> list=query.getResultList();
			for(Customer cust:list) {
				System.out.println(cust);
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			em.close();
		}
	}
	/**
	 * 统计查询数据
	 */
	@Test
	public void test7() {
		EntityManager em=JpaUtil.getEntityManager();
		try {
			String jpql="select count(1) from Customer";
			Query query=em.createQuery(jpql);
			//注意通常统计结果只有一个值
			Object result =query.getSingleResult();
			System.out.println(result);
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			em.close();
		}
	}
	/**
	 * 分组统计查询数据-- 对象数据返回
	 */
	@Test
	public void test8() {
		EntityManager em=JpaUtil.getEntityManager();
		try {
			/**
			 * SQL
			 * 需求:统计每种客户级别的人数
			 * SELECT cust_level,COUNT(cust_id) FROM customer GROUP BY cust_level			 
			 * */
			String jpql="select custLevel,count(1) from Customer group by custLevel";
			Query query=em.createQuery(jpql);
			//分组查询的结果有多个,返回对象数组的list集合
			List<Object[]> list=query.getResultList();
			for(Object[] array:list) {
				for(Object obj:array) {
					System.out.println(obj+"\t");
				}
				System.out.println();
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			em.close();
		}
	}
	/**
	 * 分组统计查询数据-- JavaBean对象返回
	 * 
	 */
	@Test
	public void test9() {
		EntityManager em=JpaUtil.getEntityManager();
		try {
			String jpql="select new com.jsonString.pojo.CustomerVo(custLevel,count(custId)) from Customer group by custLevel";
			Query query =em.createQuery(jpql);
			//分组查询的结果多个,返回对象数组List集合
			List<CustomerVo> list=query.getResultList();
			for(CustomerVo vo:list) {
				System.out.println(vo);
			}
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			em.close();
		}
	}
	@Test
	public void test10() {
		EntityManager em=JpaUtil.getEntityManager();
		try {
			String jpql="select custLevel,count(1) from Customer group by custLevel";
			Query query=em.createQuery(jpql);
			List<Object[]> list=query.getResultList();
			for(Object[] array:list) {
				for(Object obj:array) {
					System.out.println(obj+"\t");
				}
				System.out.println();
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			em.close();
		}
		
		
	}
}

JPA的核心API介绍

1、Persistence(一般)

作用:加载persistence.xml配置文件创建实体类管理器工厂(加载完配置文件到内存然后进行后续操作)
方法:createEntityManagerFactory(“持久化单元名称”)

2、EntityManagerFactory(比较重要)

作用:用于生产实体类管理器
方法: createEntityManager();
close();
细节: 1、这个类是一个重量级的类,它维护了非常多的信息:如全字段插入、全字段更新、根据id查询、根据id删除等这一系列通用的sql语句 。(如根据id以外某个字段查询的这些不通用的sql语句则交给EntityManager管理)
2、这个类是线程安全的
使用原则:一个项目只有一个这个对象

3、EntityManager(非常重要)

作用:获取事务对象,与数据库的交互都是他来完成
方法: persist() 保存
merge()更新
remove()删除
getReference()||findOne()查询一个对象
细节:1、由于工厂(EntityManagerFactory) 已经维护了非常多的信息,所以这个类维护信息就少了、维护了参数而已,它就是轻量级的对象
2、它是线程不安全的
使用原则:
一次请求,用的都是同一个 EntityManager对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值