• JPA逆向工程


    1.1 说明

    所谓的逆向工程就是通过数据库的结构生成代码。 

    目的:提高开发的效率

     

    1.2 步骤

    1.2.1 第一步创建JPA项目

    1)创建项目

     

    2)指定项目名、JPA版本

     

    3)完成创建

     

    1.2.2 第二步生成JPA代码

    右击项目的src文件夹,选择new --> Other.. -->JPAJPA Entities from Tables 

    1.2.2.1 Step1:创建新的数据库连接

    1)选择新建数据库连接

     

    2)指定数据库类型

     

    3)新建数据库驱动

     

    4)配置驱动信息

    驱动版本号

     

    加载驱动jar

     

    配置jdbc四要素

     

    1.2.2.2 Step2:配置表与表直接的关联关系

    1)配置表关联关系

    选择表,全选即可。

     

    配置StudentScore一对多

     

     

    依次配置其它的关联关系即可。

     

    1.2.2.3 Step3:指定生成实体类的名称及结构

    1修改关联对象的属性名

     

    指定实体类的生成属性

     

    指定实体类的类名

     

    依次修改其它类的属性即可。

    1.2.2.4 Step4:生成代码

     

    1.2.3 第三步:导入所需jar依赖

    说明Maven项目是可以导入jar包到本地的。

    方法:打开DOS窗口,进入项目的pom文件所在目录,执行命令:

    mvn dependency:copy-dependencies

    前提:已经配置了Maven环境变量。

     

    1.2.4 第四步:更新项目

     

    JPQL语言 

    2.1 说明 

    JPQL : Java Persistence Query Language java持久化查询语言。 

    它的作用是通过类似SQL的语法去操作实体类的对象。 

    语法和SQL一样的,SQL操作的数据表,JPQL操作的对象

    作用:实现个性化的查询需求

    2.2 示例代码 

    package cn.zj.jpa;

    import java.util.List;

    import javax.persistence.EntityManager;

    import javax.persistence.EntityTransaction;

    import javax.persistence.Query;

    import javax.persistence.TypedQuery;

    import org.junit.Test;

    import cn.zj.jpa.entity.Student;

    import cn.zj.jpa.util.JPAUtils;

    public class StudentDAOTest {

    //1.查询所有学生的信息

    @Test 

    public void findAll(){

    //1获得操作对象

    EntityManager manager = JPAUtils.getEntityManager();

    //2.获得JPQL查询对象

    //标准的JPQL是必须要使用select

    //select语法: select 别名  from 类名 别名

    TypedQuery<Student> query = manager.createQuery("select s from Student s", Student.class);

    //返回多条查询的数据,getResultList

    //TypedQuery解决了HIbernate返回有警告的问题

    List<Student> students = query.getResultList();

    for (Student student : students) {

    System.out.println("学生名:"+student.getStuName());

    }

    manager.close();

    }

    //2.条件查询

    //需求:查询名字有张字的学生

    //注意:JPQL的语法,使用?设置参数,必须要在?后面设置下标值,下标值不能为负数

    @Test 

    public void findByCondition(){

    //1获得操作对象

    EntityManager manager = JPAUtils.getEntityManager();

    //2.获得JPQL查询对象

    //标准的JPQL是必须要使用select

    TypedQuery<Student> query = manager.createQuery("select s from Student s where s.stuName like ?1", Student.class);

    //3.设置条件

    query.setParameter(1, "%%");

    List<Student> students = query.getResultList();

    for (Student student : students) {

    System.out.println("学生名:"+student.getStuName());

    }

    manager.close();

    }

    @Test 

    public void findByCondition1(){

    //1获得操作对象

    EntityManager manager = JPAUtils.getEntityManager();

    //2.获得JPQL查询对象

    //标准的JPQL是必须要使用select

    TypedQuery<Student> query = manager.createQuery("select s from Student s where s.stuName like :stuName", Student.class);

    //3.设置条件

    query.setParameter("stuName", "%%");

    List<Student> students = query.getResultList();

    for (Student student : students) {

    System.out.println("学生名:"+student.getStuName());

    }

    manager.close();

    }

    //需求:返回学生表的记录数

    @Test 

    public void count(){

    //1获得操作对象

    EntityManager manager = JPAUtils.getEntityManager();

    //2.获得JPQL查询对象

    //标准的JPQL是必须要使用select

    //JPQL中的count操作返回值是Long值,所以用Long类型接收

    TypedQuery<Long> query = manager.createQuery("select count(s) from Student s", Long.class);

    //如果返回的是一个值的查询,使用getSingleResult

    Long count = query.getSingleResult();

    System.out.println(count);

    manager.close();

    }

    //需求:第二页,每页三条

    @Test 

    public void findByPage(){

    //1获得操作对象

    EntityManager manager = JPAUtils.getEntityManager();

    //2.获得JPQL查询对象

    //标准的JPQL是必须要使用select

    TypedQuery<Student> query = manager.createQuery("select s from Student s", Student.class);

    //设置分页条件

    //1.设置开始位置,下标从0开始,第四条数据的下标为3

    query.setFirstResult(3);

    //2.设置每页的记录

    query.setMaxResults(3);

    List<Student> students = query.getResultList();

    for (Student student : students) {

    System.out.println("学生名:"+student.getStuName());

    }

    manager.close();

    }

    /*

     * 命名查询语句的调用

     *

     * 所谓的命名查询,就是在实体类对象使用一个名字声明一条JPQL语句

         * 这样可以通过name值获得Query的语句

         *

         * 命名查询,在类名上做如下声明:

                      

            @NamedQuery(name="Student.findAll", query="SELECT s FROM Student s")

            public class Student {

     */

    @Test 

    public void findAllByNamedQuery(){

    //1获得操作对象

    EntityManager manager = JPAUtils.getEntityManager();

    //2.获得一个查询命名查询语句的对象

    //可以通过该对象调用实体类声明的命名查询语句

    TypedQuery<Student> query = manager.createNamedQuery("Student.findAll", Student.class);

    List<Student> students = query.getResultList();

    for (Student student : students) {

    System.out.println(student.getStuName());

    }

    manager.close();

    }

    //需求:通过JQOL删除有张字的学生

    @Test 

    public void removeByCondition(){

    //1获得操作对象

    EntityManager manager = JPAUtils.getEntityManager();

    EntityTransaction transaction = manager.getTransaction();

    transaction.begin();

    try {

    //2.获得JPQL查询对象

    //注意,调用操作的JPQL是不需要指定返回的类型

    Query query = manager.createQuery("delete from Student s where s.stuName like ?1");

    //参数对应?设置的下标值

    query.setParameter(1, "%%");

    int count = query.executeUpdate();

    System.out.println(count);

    transaction.commit();

    manager.close();

    } catch (Exception e) {

    transaction.rollback();

    e.printStackTrace();

    }

    }

    }

    2.3 JPQL补充:N+1问题

    在一对多或者多对多查询过程中,首先查询1这一方的数据,然后根据1这一份的数据,查询多的一方的数据。

    当学生有N个的时候,总共查询次数N+1次。

    这个就称之为N+1问题

    当我们数据库的量不大的时候,N+1问题基本没有什么影响。如果当数据量很大的时候,查询数据库的次数,就很大了,这个就会影响数据库的性能。

    如何解决这个问题?

    可以通过JPQL来解决。

    @Test

    public void one2manybyOne(){

    //1、获取实体操作对象

    EntityManager manager = JPAUtils.getEntityManager();

    //JPQL是通过fetch这个关键词,在查询学生的信息的时候,一起将分数也查询出来

    //最终执行的sql就只有一条

    TypedQuery<Student> query = manager.createQuery("select distinct s from Student s inner join fetch s.scores", Student.class);

    List<Student> students = query.getResultList();

    for (Student student : students) {

    System.out.println("学生姓名:"+student.getStuName()+",学生id:"+student.getStuId());

    List<Score> scores = student.getScores();

    for (Score score : scores) {

    System.out.println("科目:"+score.getScoSubject()+",分数:"+score.getScoScore());

    }

    System.out.println("---------------------------------");

    }

    }

    执行结果:

     

    执行过程中,确实一条sql语句!!!

    解决了频繁查询数据库,带来的数据库性能损耗。

  • 相关阅读:
    卡常技巧
    Java经典习题3
    Java经典习题4
    VC++ MFC 文件处理unicode
    批处理更换ip地址
    C#实现系统托盘
    驱动打印
    c++ vs2010 GetWindowText GetWindowTextW
    VC++ MFC ListBox 复选框
    C# 获取本机ip地址
  • 原文地址:https://www.cnblogs.com/aknife/p/11291046.html
Copyright © 2020-2023  润新知