写在前面:今天又学习一点新的东西,方面日后查询和巩固学习,下面将学习过程记录下来。
一、创建MAVEN工程
1. 打开IDEA创建一个纯净的maven工程项目
2. 打开pom文件,导入maven坐标
注意:我使用的postgres数据库,如果你使用的其他数据库,只需要将这个依赖替换即可。不管什么数据库,你都需要注意依赖的版本,和你自己下载的数据库相匹配。
maven仓库地址:
maven仓库地址https://central.sonatype.com/?smo=true
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<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>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.6.0</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
</dependencies>
二、项目结构完善
目录结构如下所示:
1. 创建实体类
package com.study.entity;
import lombok.Data;
import javax.persistence.*;
/**
* 客户类
*/
@Entity
@Table(name = "cst_customer")
@Data
public class Customer {
/**
* 声明主键的配置
* @Id 主键
* @GeneratedValue 主键生成策略,GenerationType.IDENTITY为自增策略
* @Column 配置属性和字段映射关系
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@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_phone")
private String custPhone;
@Column(name = "cust_address")
private String custAddress;
}
2. 创建工具类
通过静态代码块的形式来解决EntityManagerFactory创建实例浪费资源的问题。
- 第一次访问getEntityManager:首先经过静态代码块,创建工厂对象,再调用方法,创建一个EntityManager对象。
- 第二次访问getEntityManager,直接通过一个已经创建好的factory对象,返回一个EntityManager对象 。
package com.study.utils;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
/**
* 1. 解决通过EntityManagerFactory浪费资源的问题
* 2. 静态代码块的形式来解决
*
* 第一次访问getEntityManager:首先经过静态代码快,创建工厂对象,再调用方法,创建一个EntityManager对象
* 第二次访问getEntityManager,直接通过一个已经创建好的factory对象,返回一个EntityManager对象
*/
public class JPAUtil {
private static EntityManagerFactory factory;
static {
//加载配置文件,创建EntityManagerFactory
factory = Persistence.createEntityManagerFactory("myJpa");
}
/**
* 获取EntityManager实体对象
*/
public static EntityManager getEntityManager(){
return factory.createEntityManager();
}
}
3. persistence.xml 持久化配置
注意:如果使用的是mysql,则需要将数据库配置替换:
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/HeimaSpringData?userSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai"/>
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<!--需要配置persistence-unit节点
持久化单元:
name:持久化单元名称
transaction-type:事务管理的方式
JTA:分布式事务管理
RESOURCE_LOCAL:本地事务管理
-->
<persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
<!--jpa的实现方式-->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<!--可选配置:配置jpa实现方式的配置信息-->
<properties>
<!-- 数据库信息
用户名,javax.persistence.jdbc.user
密码, javax.persistence.jdbc.password
驱动, javax.persistence.jdbc.driver
数据库地址 javax.persistence.jdbc.url
-->
<property name="javax.persistence.jdbc.user" value="postgres"/>
<property name="javax.persistence.jdbc.password" value="123456"/>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/lianxi"/>
<!--配置jpa实现方(hibernate)的配置信息
显示sql : false|true
自动创建数据库表 : hibernate.hbm2ddl.auto
create : 程序运行时创建数据库表(如果有表,先删除表再创建)
update :程序运行时创建表(如果有表,不会创建表)
none :不会创建表
-->
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
-
create : 程序运行时创建数据库表(如果有表,先删除表再创建) update :程序运行时创建表(如果有表,不会创建表) none :不会创建表
三、JAP之CRUD操作
在测试目录下,创建一个测试类JpaTest.java;CRUD大体上可以分为五个步骤:
- 获取EntityManager对象
- 开启事务
- CRUD操作
- 提交事务
- 释放资源
1. 新增操作
@Test
public void testSave(){
//加载配置文件创建工厂
//通过实体管理工厂获取实体管理器
EntityManager em = JPAUtil.getEntityManager();
//获取事务对象,开启事务
EntityTransaction tx = em.getTransaction();
tx.begin();//开启事务
//完成增删改查操作
Customer customer = new Customer();
customer.setCustName("测试88");
customer.setCustIndustry("测试行业");
//保存
em.persist(customer);
//提交事务
tx.commit();
//释放资源
em.close();
}
2. find()查询和 getReference()查询,两个查询的结果都是一样的。只不过getReference()是懒加载,可以节省资源。
/**
* 查询操作
*/
@Test
public void testFind(){
//通过工具类获取一个EntityManager对象
EntityManager em = JPAUtil.getEntityManager();
EntityTransaction ts = em.getTransaction();
ts.begin();//开启事务
//根据id查询数据
Customer customer = em.find(Customer.class, 1L);
System.out.println(customer);
//提交事务
ts.commit();
//释放资源
em.close();
}
/**
* 查询操作
* 特点:获取的是一个动态代理对象,调用getReference不会立即发送sql语句查询。当调用查询结果对象的时候才会查询(什么时候用什么时候查)
* 什么时候用什么时候才加载,懒加载
* 一般用延迟加载的方式比较好,这样可以节省资源,避免浪费效率
*/
@Test
public void textReference(){
//通过工具类获取一个EntityManager对象
EntityManager em = JPAUtil.getEntityManager();
EntityTransaction ts = em.getTransaction();
ts.begin();//开启事务
//根据id查询数据
Customer customer = em.getReference(Customer.class, 1L);
System.out.println(customer);
//提交事务
ts.commit();
//释放资源
em.close();
}
3. 删除操作(先查询,然后删除)
/**
* 删除客户方法
*/
@Test
public void testDelete(){
EntityManager entityManager = JPAUtil.getEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
//根据id查询数据
Customer customer = entityManager.getReference(Customer.class, 4L);
//删除对象
entityManager.remove(customer);
transaction.commit();
entityManager.close();
}
4.更新操作(先查询后更新操作)
/**
* 客户的更新操作
*/
@Test
public void testUpdate(){
EntityManager entityManager = JPAUtil.getEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
//根据id查询数据
Customer customer = entityManager.find(Customer.class, 5L);
//更新对象
customer.setCustPhone("147852369");
entityManager.merge(customer);
transaction.commit();
entityManager.close();
}
jpql常用条件查询
在JPA(Java Persistence API)中,可以使用JPQL(Java Persistence Query Language)进行条件查询。JPQL是一种面向对象的查询语言,类似于SQL,但是操作的是实体对象而不是数据库表。
下面是一些示例JPQL查询的条件语句:
(1)基本的条件查询:例如查询工资大于50000的员工对象.
String jpql = "SELECT e FROM Employee e WHERE e.salary > :salary";
List<Employee> employees = entityManager.createQuery(jpql, Employee.class)
.setParameter("salary", 50000)
.getResultList();
(2)使用逻辑运算符:查询工资大于50000且所属部门为"IT"的员工对象.
String jpql = "SELECT e FROM Employee e WHERE e.salary > :minSalary AND e.department = :department";
List<Employee> employees = entityManager.createQuery(jpql, Employee.class)
.setParameter("minSalary", 50000)
.setParameter("department", "IT")
.getResultList();
(3)使用模糊查询:查询名字中包含"Smith"的员工对象。
String jpql = "SELECT e FROM Employee e WHERE e.name LIKE :keyword";
List<Employee> employees = entityManager.createQuery(jpql, Employee.class)
.setParameter("keyword", "%Smith%")
.getResultList();
(4)使用IN子句:查询所属部门为"IT"或"HR"的员工对象。
String jpql = "SELECT e FROM Employee e WHERE e.department IN :departments";
List<String> departmentList = Arrays.asList("IT", "HR");
List<Employee> employees = entityManager.createQuery(jpql, Employee.class)
.setParameter("departments", departmentList)
.getResultList();
(5) 使用like查询
String jpql = "FROM Customer WHERE custName LIKE ?";
List<Customer> customers = entityManager.createQuery(jpql, Customer.class)
.setParameter(1, "%Smith%")
.getResultList();
(6) 查询排序
String jpql = "select count(custId) from Customer";
Query query = em.createQuery(jpql);//创建Query查询对象,query对象才是执行jqpl的对象
(7)分页查询
//3.查询全部
//i.根据jpql语句创建Query查询对象
String jpql = "from Customer";
Query query = em.createQuery(jpql);
//ii.对参数赋值 -- 分页参数
//起始索引
query.setFirstResult(1);
//每页查询的条数
query.setMaxResults(2);
//iii.发送查询,并封装结果
/**
* getResultList : 直接将查询结果封装为list集合
* getSingleResult : 得到唯一的结果集
*/
List list = query.getResultList();
for(Object obj : list) {
System.out.println(obj);
}
差不多敲完上面的代码后,基本就熟练了,入门上手应该是够了。