【自我提升】JPA从搭建到CRUD快速入门(IDEA+MAVEN)

写在前面:今天又学习一点新的东西,方面日后查询和巩固学习,下面将学习过程记录下来。

一、创建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&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;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大体上可以分为五个步骤:

  1. 获取EntityManager对象
  2. 开启事务
  3. CRUD操作
  4. 提交事务
  5. 释放资源

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);
        }

差不多敲完上面的代码后,基本就熟练了,入门上手应该是够了。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

记录菌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值