Jpa学习(一)

JPA学习总结

JPA简介

JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。

JPA包含的技术
ORM映射元数据

JPA支持XML和JDK5.0注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中;

API

用来操作实体对象,执行CRUD操作,框架在后台替代我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来。

查询语言

这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。


引入相关jar包

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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.pec</groupId>
    <artifactId>jpa_learn01</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <project.hibernate.version>5.4.2.Final</project.hibernate.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
        <!--hibernate对jpa支持的依赖 -->
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-entitymanager -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${project.hibernate.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-c3p0</artifactId>
            <version>${project.hibernate.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
在resources目录下创建一个META-INF,在该目录下创建persistence.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <!--配置persistence-unit节点
        持久化单元
            name;持久化单元名称
            transaction-type:事务管理的方式
                JPA:多个数据源,多个数据库,主要是实现分布式数据库的
                RESOURCE_LOCAL:单个数据源,单个数据库,本地实现的
     -->
    <persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
        <!--配置JPA的实现方式 -->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <!--配置JPA的实现方的配置信息(可选配置) -->
        <properties>
            <!--数据库信息 -->
            <!--用户名:
                密码:
                驱动:
                数据库地址:-->
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="Luoguibin6!"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql:///jpa?serverTimezone=UTC"/>
            <!--配置实现方(hibernate)的配置信息 -->
            <!--显示sql       false|true
            自动创建数据库表的策略:hibernate.hbm2ddl.auto
                        create:自动创建表,不管数据库是否有表,都会创建表
                        update:如果数据库中没有表,再创建表,如果有表,则不会再创建表
                        none:不管有无表,都不会创建表,如果不进行配置,默认状态下就会采用这种方式
            -->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            <!--<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>-->
        </properties>
    </persistence-unit>
</persistence>

封装JPA操作工具类

package com.pec.oa.utils;

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

public class JPAUtil {
    private static EntityManagerFactory entityManagerFactory;
    //加载持久化数据单元文件,生成一个实体管理器工厂对象
    static {
        entityManagerFactory=Persistence.createEntityManagerFactory("myJpa");
    }
    public static EntityManager getEntityManager(){
        return entityManagerFactory.createEntityManager();
    }
}
配置数据库表与实体类映射
package com.pec.oa.pojo;

import javax.persistence.*;
import java.io.Serializable;
import java.sql.Timestamp;

/**
 * 配置实体类和数据库表的映射关系
 * 配置实体类中属性和数据库表中字段的映射关系
 * @Entity:声明实体类
 * @Table:配置实体类和表的映射关系
 *      name:配置数据库表的名称
 */
@Entity
@Table(name = "u_user")
public class User implements Serializable {
    @Id //配置主键
    @GeneratedValue(strategy =GenerationType.IDENTITY )//配置主键生成的策略,默认是auto
                            //IDENTITY:自动增长,前提是底层数据库必须支持自动增长,mysql
                            //SEQUENCE:序列,底层数据库必须支持序列,Oracle
                            //Table:JPA提供的一直机制,通过一种数据库表的形式的主键自增
                            //auto:由程序自动的选择一种主键生成策略。
    @Column(name = "u_id")
    private Integer uId;
    @Column(name = "u_username")
    private String uUsername;
    @Column(name = "u_password")
    private String uPassword;
    @Column(name = "u_sex")
    private String uSex;
    @Column(name = "u_age")
    private Integer uAge;
    @Column(name = "u_registryDate")
    private Timestamp uRegistryDate;

    public User() {
    }
    public Integer getuId() {
        return uId;
    }

    public void setuId(Integer uId) {
        this.uId = uId;
    }

    public String getuUsername() {
        return uUsername;
    }

    public void setuUsername(String uUsername) {
        this.uUsername = uUsername;
    }

    public String getuPassword() {
        return uPassword;
    }

    public void setuPassword(String uPassword) {
        this.uPassword = uPassword;
    }

    public String getuSex() {
        return uSex;
    }

    public void setuSex(String uSex) {
        this.uSex = uSex;
    }

    public Integer getuAge() {
        return uAge;
    }

    public void setuAge(Integer uAge) {
        this.uAge = uAge;
    }

    public Timestamp getuRegistryDate() {
        return uRegistryDate;
    }

    public void setuRegistryDate(Timestamp uRegistryDate) {
        this.uRegistryDate = uRegistryDate;
    }

    @Override
    public String toString() {
        return "User{" +
                "uId=" + uId +
                ", uUsername='" + uUsername + '\'' +
                ", uPassword='" + uPassword + '\'' +
                ", uSex='" + uSex + '\'' +
                ", uAge=" + uAge +
                ", uRegistryDate=" + uRegistryDate +
                '}';
    }
}

创建测试类完成增删查改操作
package com.pec.oa.test;

import com.pec.oa.pojo.User;
import com.pec.oa.utils.JPAUtil;
import org.junit.Test;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import java.sql.Timestamp;

public class TestJpa {
    /**
     * 测试JPA的插入操作
     * 加载配置文件创建实体管理类工厂 EntityManagerFactory对象(线程安全)
     * 通过实体管理类工厂创建实体管理类
     *获取事务对象,加载事务
     *完成增删改查此操作
     *提交事务
     * 释放资源
     * 实体管理器对象EntityManager的方法:
     * beginTransaction():创建一个事务对象
     *      persist():保存
     *      merge():更新
     *      remove():删除
     *      find/getReference:根据id查询
     * Transaction对象:事务
     *      begin:开启事务
     *      commit:提交事务
     *      rollback:回滚
     */
    @Test
    //增加数据
    public void test01(){
       //使用工具类创建实体对象
        EntityManager entityManager =JPAUtil.getEntityManager();
        //获取事务对象
        EntityTransaction tx =entityManager.getTransaction();
        //开启事务
        tx.begin();
        User user =new User();
        user.setuUsername("张三");
        user.setuPassword("123456");
        user.setuRegistryDate(new Timestamp(System.currentTimeMillis()));
        entityManager.persist(user);
        //提交
        tx.commit();
        //释放资源
        entityManager.close();
        //managerFactory.close();
    }
    /**
     * 查询数据
     * find(操作对象实例【反射】,id),通过id查询
     * 当调用find方法的时候就会进行sql查询(立即查询),当调用find方法的时候就会查询
     */
    @Test
    public void test02(){
        //1.创建实体类对象管理器
        EntityManager entityManager =JPAUtil.getEntityManager();
        //2.进行查询操作,查询不属于事务性操作
        User user=entityManager.find(User.class,1);
        System.out.println(user);
        entityManager.close();
    }

    /**
     * 查询数据
     * 使用getReference()方法使用同样的参数,但是过程不一样
     * getReference()方法查询得到的是一个代理对象,只有当这个对象被引用的时候才会去查询。
     * 类似于(延时加载)懒加载
     */
    @Test
    public void test03(){
        //1.创建实体类对象管理器
        EntityManager entityManager =JPAUtil.getEntityManager();
        //2.进行查询操作,查询不属于事务性操作
        User user=entityManager.getReference(User.class,1);
        System.out.println(user);
        entityManager.close();
    }
    /**
     * 删除操作
     */
    @Test
    public void test04() {
        EntityManager entityManager =JPAUtil.getEntityManager();
        //获取事务对象
        EntityTransaction tx =entityManager.getTransaction();
        //开启事务
        tx.begin();
        //完成增删改查操作
        User user =entityManager.find(User.class,1);
        entityManager.remove(user);
        //提交
        tx.commit();
        //释放资源
        entityManager.close();
    }
    /**
     * 更新操作
     * merge()方法
     */
    @Test
    public void test05() {
        EntityManager entityManager =JPAUtil.getEntityManager();
        //获取事务对象
        EntityTransaction tx =entityManager.getTransaction();
        //开启事务
        tx.begin();
        //完成增删改查操作
        User user =entityManager.find(User.class,3);
        user.setuUsername("李四");
        entityManager.merge(user);
        //提交
        tx.commit();
        //释放资源
        entityManager.close();
    }
}

测试使用Jpql进行操作
package com.pec.oa.test;

import com.pec.oa.utils.JPAUtil;
import org.junit.Test;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.List;

public class TestJpql {
    /**
     * 查询全部
     * 创建query对象
     * 1.根据jpql创建查询对象
     * 2.
     */
    @Test
    public void test01(){
        EntityManager entityManager =JPAUtil.getEntityManager();
        String jpql="from com.pec.pojo.User order by id desc";
        Query query =entityManager.createQuery(jpql);
        List list =query.getResultList();
        for(Object o:list){
            System.out.println(o);
        }
    }

    /**
     * 统计个数count(实体类的属性)
     * getSingleResult()获取单个结果集
     */
    @Test
    public void test02(){
        EntityManager entityManager =JPAUtil.getEntityManager();
        String jpql1="select count(id) from com.pec.pojo.User";
        Query query =entityManager.createQuery(jpql1);
       Object o = query.getSingleResult();
        System.out.println(o);
    }

    /**
     * 分页,这个分页默认的是先经过全表查询之后才分页的,所以并不能减轻数据库的压力
     * jpql:from User
     * 分页参数:
     *          setFirstResult:起始位置,不包括起始位置
     *          setMaxResult:每页展示的最大条数。
     * 观察jpql语句可以看到内部还是使用limit关键字进行查询的,从0开始查询不包括0,所以只用带一个参数2
     */
    @Test
    public void test03(){
        EntityManager entityManager =JPAUtil.getEntityManager();
        String jpql="from User";
        Query query =entityManager.createQuery(jpql);
        query.setFirstResult(0);
        query.setMaxResults(2);
        List list =query.getResultList();
        for(Object o:list){
            System.out.println(o);
        }
    }

    /**
     * 条件查询,hibernate4.1之后对占位符做了修改,所以在JPA中可以使用
     *      from User where uUsername like ?0,0代表这个占位符的索引
     */
    @Test
    public void test04(){
        EntityManager entityManager =JPAUtil.getEntityManager();
        String jpql="from com.pec.pojo.User where uUsername like ?1";
        Query query =entityManager.createQuery(jpql);
        query.setParameter(1,"张%");
        List list =query.getResultList();
        for(Object o:list){
            System.out.println(o);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值