JPA教程一

  • 随着时间的推移市面上涌现了越来越多的ORM框架,那么作为java的官方势必要开始一些动作,于是oracle引入新的JPA ORM规范出于两个原因:
    其一,简化现有Java EE和Java SE应用开发工作;其二,oracle希望整合ORM技术,实现天下归一

  • 1.JPA是什么: 全称Java Persistence API,通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中
    简而言之:用于对象持久化的 API,使得应用程序以统一的方式访问持久层

  • 2.那么JPA 与 Hibernate究竟是什么关系呢:
    JPA 是一种 ORM 规范,而HIbernate是JPA的一种实现,mybtais也是JPA的一种实现

备注:JPA和HIbernate是同一个人写的

Jpa代码+库表问价
链接:https://pan.baidu.com/s/1cYDKsiIeDQ3FOZTVx8PAew
提取码:7hje

一:JPA第一个例子

目录结构

  • 创建Maven项目
    在这里插入图片描述

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>

<persistence version="2.1"
             xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">


    <!--
    persistence-unit:负责将固定数量的一组类映射到数据库中
    name:该属性是必须填写的,其定义了持久化单元的名字-->
    <persistence-unit name="mysql-jpa">
        <!-- 2.添加持久化类:就是将带有注解的实体类交给JPA进而实现映射到数据库中 -->
        <class>bj.sh.gy.enity.User</class>

        <properties>
            <!-- 3.设置连库四要素 -->
            <property name="javax.persistence.jdbc.driver"  value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/hibernates" />
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="root" />
            <!-- 5.配置JPA实现产品的基本属性:配置Hibernate的基本属性 -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>
    </persistence-unit>
</persistence>

实体类

package bj.sh.gy.enity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * @author LXY
 * @desc
 * @time 2022-10-16  0:59
 */
@Table(name = "user")
@Entity
public class User {

    @Id
    @Column(name = "id")
    private int id;

    @Column(name = "name")
    private String name;
    @Column(name = "age")
    private int age;
    @Column(name = "t_version")
    private int t_version;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getT_version() {
        return t_version;
    }

    public void setT_version(int t_version) {
        this.t_version = t_version;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

测试类

package bj.sh.gy.Test;

import bj.sh.gy.enity.User;

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

/**
 * @author LXY
 * @desc
 * @time 2022-10-16  11:01
 */
public class test {
    public static void main(String[] args) {
        //1.创建实体管理器工厂
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("mysql-jpa");
        //2.创建实体管理器
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        //3.获取事务
        EntityTransaction transaction = entityManager.getTransaction();
        //4.开启事务
        transaction.begin();
        //5.创建一个带有数据的实体类对象
        User user = new User();
        user.setId(64);
        user.setName("王五");
        //6.保存实体:类似于HIbernate中的save()方法,但是也有不同的地方,就是在数据库主键自增情况下:若提前设置id属性值,JPA EntityManager 的 persist方法将抛出异常,而Hibernate Session的 save 方法可以执行,将忽略提前设置的id值
        entityManager.persist(user);
        //7.提交事务
        transaction.commit();
        //8.关闭JPA的相关对象
        entityManager.close();
        entityManagerFactory.close();

    }
}

成功运行

在这里插入图片描述

二:注解

在这里插入图片描述
@Data

  • @Data 是lombok.Data; 下的,作用是打上这个注解不用写get set 构造器 tostring等方法,自动生成,减少代码书写

@Entity

  • 修饰实体类,指明该类将映射到指定的数据表,

@Table

  • 当实体类与映射的数据库表名不同名时需要使用 @Table 注解,该注解与 @Entity 注解并列使用,使用其 name 属性指明数据库的表名

@Id

  • 标识该属性为主键

@GeneratedValue

  • 标注主键的生成策略,通过其 strategy 属性。通常与 @Id 注解一起使用。默认情况下 JPA 会自动选择一个最适合底层数据库的主键生成策略,MySQL 默认为 AUTO

常用策略有:

–IDENTITY:采用数据库 ID自增长的方式来自增主键字段,Oracle 不支持这种方式;

–AUTO: JPA自动选择合适的策略,是默认选项;

–SEQUENCE:通过序列产生主键,通过 @SequenceGenerator 注解指定序列名,MySql 不支持这种方式

–TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植

@Column

  • 当实体的属性与其映射的数据表的列不同名时使用。其 name 属性用来指明此属性在数据表中对应的列名;unique 属性指明是否为唯一约束;nullable 属性用来指明是否可以为空,false 为不能为空;length 属性指明此列的长度。

创建数据库表

CREATE TABLE `t_customer`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `age` int(11) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  `Creatad_TIME` datetime(0) DEFAULT NULL,
  `email` text CHARACTER SET utf8 COLLATE utf8_general_ci,
  `Last_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of t_customer
-- ----------------------------
INSERT INTO `t_customer` VALUES (1, 18, '2022-10-16', '2022-10-16 00:00:00', '2050599999@qq.com', '李四');
INSERT INTO `t_customer` VALUES (2, 18, '2022-10-16', '2022-10-16 00:00:00', '20505929999@qq.com', '李四2');
INSERT INTO `t_customer` VALUES (3, 18, '2022-10-16', '2022-10-16 12:13:46', '20505929999@qq.com', '李四2');
INSERT INTO `t_customer` VALUES (4, 18, '2022-10-16', '2022-10-16 00:00:00', '2050599999@qq.com', '李四');
INSERT INTO `t_customer` VALUES (5, 18, '2022-10-16', '2022-10-16 12:26:48', '2050599999@qq.com', '李四');


在这里插入图片描述

@Column(name=“email”,columnDefinition = “text”) //指明是dtext类型
@Column(name = “Last_name”) //指明字段名

@Column(name=“birthday”)
@Temporal(TemporalType.DATE) //指明是data类型

@Id //主键id
@Column(name = “id”, nullable = false) //nullable指明字段的值不能重复
@GeneratedValue(strategy = GenerationType.AUTO)//主键生成策略
测试类

   public static void main(String[] args) {
        //1.创建实体管理器工厂
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("mysql-jpa");
        //2.创建实体管理器
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        //3.获取事务
        EntityTransaction transaction = entityManager.getTransaction();
        //4.开启事务
        transaction.begin();


        customer customer=new customer();
        customer.setAge(18);
        customer.setEmail("2050599999@qq.com");
        customer.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        customer.setBirthday(new Date());
        customer.setName("李四");

        //6.保存实体:类似于HIbernate中的save()方法,但是也有不同的地方,就是在数据库主键自增情况下:若提前设置id属性值,JPA EntityManager 的 persist方法将抛出异常,而Hibernate Session的 save 方法可以执行,将忽略提前设置的id值
        entityManager.persist(customer);
        //7.提交事务
        transaction.commit();
        //8.关闭JPA的相关对象
        entityManager.close();
        entityManagerFactory.close();

    }

主键自增长

在这里插入图片描述
在这里插入图片描述

  • 如果使用的主键自增长使用persist会出错
    在这里插入图片描述

JPQL 语句

查询全部 (单表)

Query nativeQuery = entityManager.createNativeQuery("select  * from user ", User.class);
        List<User> resultList = nativeQuery.getResultList();
        for (User user : resultList) {

            System.out.println(user);
        }

在这里插入图片描述

查询一条

 User user = entityManager.find(User.class, 1);
        System.out.println(user);
- 另外一种方法
 User reference = entityManager.getReference(User.class, 1);

在这里插入图片描述

一对多查询

  • 创建实体类,Student和classses是多对一的映射关系
    在这里插入图片描述
    在这里插入图片描述
  • 查询多
Query nativeQuery = entityManager.createNativeQuery("select * from student", Student.class);
        List <Student>resultList = nativeQuery.getResultList();
        for (Student student : resultList) {
            System.out.println(student.getSage());
            System.out.println(student.getClasses().getCinfor());
        }

在这里插入图片描述

  • 查询一
    Query nativeQuery = entityManager.createNativeQuery("select * from classes", Classes.class);
        List <Classes> resultList = nativeQuery.getResultList();
        for (Classes classes : resultList) {
            System.out.println(classes.getCinfor());
        }

在这里插入图片描述

添加

  • 单表
   User user=new User();
        user.setT_version(1);
        user.setAge(15);
        user.setName("李先锋");
    entityManager.persist(user);

在这里插入图片描述

  • 一对多
Classes classes=new Classes();
    classes.setCid(UUID.randomUUID().toString());
    classes.setCinfor("教室");

    entityManager.merge(classes);   //先进行查询,如果没有就添加

在这里插入图片描述

   Student student=new Student();
        student.setId(UUID.randomUUID().toString());
        student.setSage("18");
        student.setSname("李现");

        Classes classes=new Classes();
        classes.setCid("3fd429e4-487c-45e2-ac76-26ad19fc07c9");
        student.setClasses(classes);

    entityManager.merge(student);   //先进行查询,如果没有就添加

在这里插入图片描述

修改

  • 单表和多表一样
    在这里插入图片描述
  Classes reference = entityManager.getReference(Classes.class, "4028f48183da2d760183da2d77b50000");
        reference.setCinfor("教室8");

删除

    Classes reference = entityManager.getReference(Classes.class, "3fd429e4-487c-45e2-ac76-26ad19fc07c9");
        entityManager.remove(reference);

在这里插入图片描述

  • 思考:为什么有主外键关系可以直接删除呢,
    在这里插入图片描述

JPQL 语法

查询全部

Query query = entityManager.createQuery("select  u from bj.sh.gy.enity.User u ");
        List<User> resultList = query.getResultList();
        for (User user : resultList) {
            System.out.println(user);
        }

在这里插入图片描述

占位查询

JPQL 语句支持两种方式的参数定义方式 : 命名参数和位置参数 。 。在同一个查询语句中只允许使用一种参数定义方式

  Query query = entityManager.createQuery("select  u from bj.sh.gy.enity.User u where  u.id=:id");
        query.setParameter("id",1);
        List resultList = query.getResultList();
        System.out.println(resultList.get(0));

在这里插入图片描述

 Query query = entityManager.createQuery("select  u from bj.sh.gy.enity.User u where u.id=?1");
        query.setParameter(1, 1);
        List resultList = query.getResultList();
        System.out.println(resultList.get(0));

在这里插入图片描述

命名查询

  • 以在实体 bean 上通过 @NamedQuery or @NamedQueries 预先定义一个或多个查询语句,
    Query query = entityManager.createNamedQuery("getUser");

        List resultList = query.getResultList();
        System.out.println(resultList);

在这里插入图片描述
在这里插入图片描述

排序

  Query query = entityManager.createQuery("select  u from bj.sh.gy.enity.User u  order by u.age  desc ");

        List resultList = query.getResultList();
        System.out.println(resultList);

在这里插入图片描述

查询部分数据

 Query query = entityManager.createQuery("select  u.age,u.name from bj.sh.gy.enity.User u  ");
        List<Object[]> list = query.getResultList();//因为只是查询的是Customer表中的一个列name,所以此时List 集合中的元素不再是 Customer整体这个对子昂, 而是一个 Object[] 对象数组

        for (Object[] objects : list) {
            System.out.print(objects[0]);
            System.out.println(objects[1]);
        }

在这里插入图片描述

构造器赋值

  Query query = entityManager.createQuery("select  new bj.sh.gy.enity.User( u.name,u.age) from bj.sh.gy.enity.User u  ");
        List <User>resultList = query.getResultList();
        System.out.println(resultList);

在这里插入图片描述

聚合函数

  • avg
  • min
  • count
  • sum
  • max
Query query = entityManager.createQuery("select  count(u) from bj.sh.gy.enity.User u  ");
        String s = query.getResultList().toString();
        System.out.println(s);

在这里插入图片描述

in

  • in
  • BETWEEN…and
  • LIKE:
  • IS NULL&& IS NOT NULL
  • IS EMPTY:IS EMPTY

在这里插入图片描述

      Query query = entityManager.createQuery("select  u from bj.sh.gy.enity.User u where u.age in(15,16) ");
        List <User>resultList = query.getResultList();

函数

  1. CONCAT 字符串拼接
    2. SUBSTRING 字符串截取
    3. TRIM 去掉空格
    4. LOWER 转换成小写
    5. UPPER 装换成大写
    6. LENGTH 字符串长度
    7. LOCATE 字符串定位
       Query query = entityManager.createQuery("select  concat(u.name ,'ssss')  from bj.sh.gy.enity.User u where u.name like '%%%' ");
        List <User>resultList = query.getResultList();
        System.out.println(resultList);

在这里插入图片描述

计算函数

ABS 绝对值
SQRT 平方根
MOD 取余数
SIZE 取集合的数量
    Query query = entityManager.createQuery("select  abs(u.age*(-1))  from bj.sh.gy.enity.User u where u.name like '%%%' ");
        List <User>resultList = query.getResultList();
        System.out.println(resultList);

在这里插入图片描述

分页

      Query query = entityManager.createQuery("select  abs(u.age*(-1))  from bj.sh.gy.enity.User u where u.name like '%%%' ");
        List <User>resultList = query.setMaxResults(2).setFirstResult(0).getResultList();
        System.out.println(resultList);

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值