Главная страница
Навигация по странице:

  • Кэш первого уровня (First Level Cache) Кэш первого уровня – это кэш Сессии (Session)

  • Кэш запросов (Query Cache)

  • Руководство по Hibernate. Руководство по Hibernate


    Скачать 186.74 Kb.
    НазваниеРуководство по Hibernate
    Дата25.11.2021
    Размер186.74 Kb.
    Формат файлаdocx
    Имя файлаРуководство по Hibernate.docx
    ТипРуководство
    #282046
    страница6 из 7
    1   2   3   4   5   6   7

    Нативный SQL.


    Для того, чтобы формировать запросы для базы данных (далее – БД), при этом испольуя все возможности БД, мы можем использовать нативный SQL.

    Таким обращом наше приложение создаст нативный SQL – запрос, испоьзуя метод createSQLQuery() интерфейса Session, который выглядит следующим образом:
    public SQLQuery createSQLQuery (String sqlString) throws HibernateException;
    После того, как мы передаём методу createSQLQuery() строку (String), содержащую SQL – запрос, мы можем связать результат этого запроса с сохраняемым объектом (persistent object).

    Для понимания того, как это работате на практике, рассмотрим пример простого приложения.

    Пример:
    Шаг 1. Создадим таблицу в нашей БД

    HIBRNATE_DEVELOPERS
    CREATE TABLE HIBERNATE_DEVELOPERS (

    id INT NOT NULL auto_increment,

    FIRST_NAME VARCHAR(50) default NULL,

    LAST_NAME VARCHAR(50) default NULL,

    SPECIALTY VARCHAR(50) default NULL,

    EXPERIENCE INT default NULL,

    SALARY INT default NULL,

    PRIMARY KEY (id)

    );
    Шаг 2. Создадим POJO – класс

    Developer.java
    package net.proselyte.hibernate.criteria;
    public class Developer {

    private int id;

    private String firstName;

    private String lastName;

    private String specialty;

    private int experience;

    private int salary;
    /**

    * Default Constructor

    */

    public Developer() {

    }
    /**

    * Plain constructor

    */

    public Developer(String firstName, String lastName, String specialty, int experience, int salary) {

    this.firstName = firstName;

    this.lastName = lastName;

    this.specialty = specialty;

    this.experience = experience;

    this.salary = salary;

    }
    /**

    * Getters and Setters

    */

    public int getId() {

    return id;

    }
    public void setId(int id) {

    this.id = id;

    }
    public String getFirstName() {

    return firstName;

    }
    public void setFirstName(String firstName) {

    this.firstName = firstName;

    }
    public String getLastName() {

    return lastName;

    }
    public void setLastName(String lastName) {

    this.lastName = lastName;

    }
    public String getSpecialty() {

    return specialty;

    }
    public void setSpecialty(String specialty) {

    this.specialty = specialty;

    }
    public int getExperience() {

    return experience;

    }
    public void setExperience(int experience) {

    this.experience = experience;

    }
    public int getSalary() {

    return salary;

    }
    public void setSalary(int salary) {

    this.salary = salary;

    }
    /**

    * toString method (optional)

    */

    @Override

    public String toString() {

    return "id: " + id +

    "\nFirst Name: " + firstName +

    "\nLast Name: " + lastName +

    "\nSpecialty: " + specialty +

    "\nExperience: " + experience +

    "\nSalary: " + salary + "\n";

    }

    }

    Шаг 3. Создаём конфигурационные файлы

    hibernate.cfg.xml


    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">





    org.hibernate.dialect.MySQLDialect

    com.mysql.jdbc.Driver


    jdbc:mysql://localhost/ИМЯ_ВАШЕЙ_БД

    ВАШЕ_ИМЯ_ПОЛЬЗОВАТЕЛЯ

    ВАШ_ПАРОЛЬ





    Developer.hbm.xml


    "-//Hibernate/Hibernate Mapping DTD//EN"

    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">






    This class contains developer details.












    Шаг 4. Создаём класс DeveloperRunner.java
    DeveloperRunner.java
    package net.proselyte.hibernate.nativesql;
    import org.hibernate.*;

    import org.hibernate.cfg.Configuration;

    import org.hibernate.criterion.Projections;
    import java.util.List;

    import java.util.Map;
    public class DeveloperRunner {

    private static SessionFactory sessionFactory;
    public static void main(String[] args) {

    sessionFactory = new Configuration().configure().buildSessionFactory();

    DeveloperRunner developerRunner = new DeveloperRunner();
    System.out.println("Adding developer's records to the database...");

    Integer developerId1 = developerRunner.addDeveloper("Proselyte", "Developer", "Java Developer", 3, 2000);

    Integer developerId2 = developerRunner.addDeveloper("First", "Developer", "C++ Developer", 10, 5000);

    Integer developerId3 = developerRunner.addDeveloper("Second", "Developer", "C# Developer", 5, 4000);

    Integer developerId4 = developerRunner.addDeveloper("Third", "Developer", "PHP Developer", 1, 1000);
    System.out.println("List of Developers using Entity Query:");

    developerRunner.listDevelopers();
    System.out.println("List of Developers using Scalar Query:");

    developerRunner.listDevelopersScalar();

    sessionFactory.close();

    }
    public Integer addDeveloper(String firstName, String lastName, String specialty, int experience, int salary) {

    Session session = sessionFactory.openSession();

    Transaction transaction = null;

    Integer developerId = null;
    transaction = session.beginTransaction();

    Developer developer = new Developer(firstName, lastName, specialty, experience, salary);

    developerId = (Integer) session.save(developer);

    transaction.commit();

    session.close();

    return developerId;

    }
    public void listDevelopers() {

    Session session = sessionFactory.openSession();

    Transaction transaction = null;
    transaction = session.beginTransaction();

    SQLQuery sqlQuery = session.createSQLQuery("SELECT * FROM HIBERNATE_DEVELOPERS");

    sqlQuery.addEntity(Developer.class);

    List developers = sqlQuery.list();
    for (Developer developer : developers) {

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

    System.out.println(developer);

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

    }

    transaction.commit();

    session.close();

    }
    public void listDevelopersScalar() {

    Session session = sessionFactory.openSession();

    Transaction transaction = null;
    transaction = session.beginTransaction();

    SQLQuery sqlQuery = session.createSQLQuery("SELECT * FROM HIBERNATE_DEVELOPERS");

    sqlQuery.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);

    List developers = sqlQuery.list();

    for (Object developer : developers) {

    Map row = (Map) developer;

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

    System.out.println("id: " + row.get("id"));

    System.out.println("First Name: " + row.get("FIRST_NAME"));

    System.out.println("Last Name: " + row.get("LAST_NAME"));

    System.out.println("Specialty: " + row.get("SPECIALTY"));

    System.out.println("Experience: " + row.get("EXPERIENCE"));

    System.out.println("Salary: " + row.get("SALARY"));

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

    }

    transaction.commit();

    session.close();

    }
    public void totalSalary() {

    Session session = sessionFactory.openSession();

    Transaction transaction = null;
    transaction = session.beginTransaction();

    Criteria criteria = session.createCriteria(Developer.class);

    criteria.setProjection(Projections.sum("salary"));
    List totalSalary = criteria.list();

    System.out.println("Total salary of all developers: " + totalSalary.get(0));

    transaction.commit();

    session.close();

    }

    }
    Если всё было сделано правильно, в результате работы программы мы получим, примерно, следующий результат:
    /usr/lib/jvm/java-8-oracle/bin/java -Didea.launcher.port=7541 -Didea.launcher.bin.path=/home/proselyte/Programming/Soft/IntellijIdea/bin -Dfile.encoding=UTF-8 -classpath /usr/lib/jvm/java-8-oracle/jre/lib/management-agent.jar:/usr/lib/jvm/java-8-oracle/jre/lib/plugin.jar:/usr/lib/jvm/java-8-oracle/jre/lib/rt.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jsse.jar:/usr/lib/jvm/java-8-oracle/jre/lib/charsets.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jce.jar:/usr/lib/jvm/java-8-oracle/jre/lib/resources.jar:/usr/lib/jvm/java-8-oracle/jre/lib/deploy.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jfxswt.jar:/usr/lib/jvm/java-8-oracle/jre/lib/javaws.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jfr.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/dnsns.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/sunpkcs11.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/sunec.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/jaccess.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/nashorn.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/localedata.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/zipfs.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/cldrdata.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/jfxrt.jar:/home/proselyte/Programming/IdeaProjects/ProselyteTutorials/Hibernate/target/classes:/home/proselyte/.m2/repository/org/springframework/spring-core/4.1.1.RELEASE/spring-core-4.1.1.RELEASE.jar:/home/proselyte/.m2/repository/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar:/home/proselyte/.m2/repository/org/springframework/spring-web/4.1.1.RELEASE/spring-web-4.1.1.RELEASE.jar:/home/proselyte/.m2/repository/org/springframework/spring-aop/4.1.1.RELEASE/spring-aop-4.1.1.RELEASE.jar:/home/proselyte/.m2/repository/aopalliance/aopalliance/1.0/aopalliance-1.0.jar:/home/proselyte/.m2/repository/org/springframework/spring-beans/4.1.1.RELEASE/spring-beans-4.1.1.RELEASE.jar:/home/proselyte/.m2/repository/org/springframework/spring-context/4.1.1.RELEASE/spring-context-4.1.1.RELEASE.jar:/home/proselyte/.m2/repository/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar:/home/proselyte/.m2/repository/org/springframework/spring-webmvc/4.1.1.RELEASE/spring-webmvc-4.1.1.RELEASE.jar:/home/proselyte/.m2/repository/org/springframework/spring-expression/4.1.1.RELEASE/spring-expression-4.1.1.RELEASE.jar:/home/proselyte/.m2/repository/org/springframework/integration/spring-integration-file/4.2.1.RELEASE/spring-integration-file-4.2.1.RELEASE.jar:/home/proselyte/.m2/repository/org/springframework/integration/spring-integration-core/4.2.1.RELEASE/spring-integration-core-4.2.1.RELEASE.jar:/home/proselyte/.m2/repository/org/springframework/spring-messaging/4.2.2.RELEASE/spring-messaging-4.2.2.RELEASE.jar:/home/proselyte/.m2/repository/org/springframework/retry/spring-retry/1.1.2.RELEASE/spring-retry-1.1.2.RELEASE.jar:/home/proselyte/.m2/repository/org/springframework/spring-tx/4.2.2.RELEASE/spring-tx-4.2.2.RELEASE.jar:/home/proselyte/.m2/repository/commons-io/commons-io/2.4/commons-io-2.4.jar:/home/proselyte/.m2/repository/org/hibernate/hibernate-core/5.1.0.Final/hibernate-core-5.1.0.Final.jar:/home/proselyte/.m2/repository/org/jboss/logging/jboss-logging/3.3.0.Final/jboss-logging-3.3.0.Final.jar:/home/proselyte/.m2/repository/org/hibernate/javax/persistence/hibernate-jpa-2.1-api/1.0.0.Final/hibernate-jpa-2.1-api-1.0.0.Final.jar:/home/proselyte/.m2/repository/org/javassist/javassist/3.20.0-GA/javassist-3.20.0-GA.jar:/home/proselyte/.m2/repository/antlr/antlr/2.7.7/antlr-2.7.7.jar:/home/proselyte/.m2/repository/org/apache/geronimo/specs/geronimo-jta_1.1_spec/1.1.1/geronimo-jta_1.1_spec-1.1.1.jar:/home/proselyte/.m2/repository/org/jboss/jandex/2.0.0.Final/jandex-2.0.0.Final.jar:/home/proselyte/.m2/repository/com/fasterxml/classmate/1.3.0/classmate-1.3.0.jar:/home/proselyte/.m2/repository/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar:/home/proselyte/.m2/repository/xml-apis/xml-apis/1.0.b2/xml-apis-1.0.b2.jar:/home/proselyte/.m2/repository/org/hibernate/common/hibernate-commons-annotations/5.0.1.Final/hibernate-commons-annotations-5.0.1.Final.jar:/home/proselyte/.m2/repository/javassist/javassist/3.12.1.GA/javassist-3.12.1.GA.jar:/home/proselyte/.m2/repository/mysql/mysql-connector-java/5.1.38/mysql-connector-java-5.1.38.jar:/home/proselyte/Programming/Soft/IntellijIdea/lib/idea_rt.jar com.intellij.rt.execution.application.AppMain net.proselyte.hibernate.nativesql.DeveloperRunner

    Feb 23, 2016 9:44:03 PM org.hibernate.Version logVersion

    INFO: HHH000412: Hibernate Core {5.1.0.Final}

    Feb 23, 2016 9:44:03 PM org.hibernate.cfg.Environment

    INFO: HHH000206: hibernate.properties not found

    Feb 23, 2016 9:44:03 PM org.hibernate.cfg.Environment buildBytecodeProvider

    INFO: HHH000021: Bytecode provider name : javassist

    Feb 23, 2016 9:44:04 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager

    INFO: HCANN000001: Hibernate Commons Annotations {5.0.1.Final}

    Feb 23, 2016 9:44:05 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure

    WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)

    Feb 23, 2016 9:44:05 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator

    INFO: HHH10001005: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost/PROSELYTE_TUTORIAL]

    Feb 23, 2016 9:44:05 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator

    INFO: HHH10001001: Connection properties: {user=root, password=****}

    Feb 23, 2016 9:44:05 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator

    INFO: HHH10001003: Autocommit mode: false

    Feb 23, 2016 9:44:05 PM org.hibernate.engine.jdbc.connections.internal.PooledConnections

    INFO: HHH000115: Hibernate connection pool size: 20 (min=1)

    Tue Feb 23 21:44:05 EET 2016 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.

    Feb 23, 2016 9:44:05 PM org.hibernate.dialect.Dialect

    INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect

    Adding developer's records to the database...

    List of Developers using Entity Query:

    =======================

    id: 69

    First Name: Proselyte

    Last Name: Developer

    Specialty: Java Developer

    Experience: 3

    Salary: 2000
    =======================

    =======================

    id: 70

    First Name: First

    Last Name: Developer

    Specialty: C++ Developer

    Experience: 10

    Salary: 5000
    =======================

    =======================

    id: 71

    First Name: Second

    Last Name: Developer

    Specialty: C# Developer

    Experience: 5

    Salary: 4000
    =======================

    =======================

    id: 72

    First Name: Third

    Last Name: Developer

    Specialty: PHP Developer

    Experience: 1

    Salary: 1000
    =======================

    List of Developers using Scalar Query:

    =======================

    id: 69

    First Name: Proselyte

    Last Name: Developer

    Specialty: Java Developer

    Experience: 3

    Salary: 2000

    =======================

    =======================

    id: 70

    First Name: First

    Last Name: Developer

    Specialty: C++ Developer

    Experience: 10

    Salary: 5000

    =======================

    =======================

    id: 71

    First Name: Second

    Last Name: Developer

    Specialty: C# Developer

    Experience: 5

    Salary: 4000

    =======================

    =======================

    id: 72

    First Name: Third

    Last Name: Developer

    Specialty: PHP Developer

    Experience: 1

    Salary: 1000

    =======================

    Feb 23, 2016 9:44:06 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop

    INFO: HHH10001008: Cleaning up connection pool [jdbc:mysql://localhost/PROSELYTE_TUTORIAL]

    Наша таблица HIBERNATE_DEVELOPERS будет иметь такой вид:
    +----+------------+-----------+----------------+------------+--------+

    | id | FIRST_NAME | LAST_NAME | SPECIALTY | EXPERIENCE | SALARY |

    +----+------------+-----------+----------------+------------+--------+

    | 65 | Proselyte | Developer | Java Developer | 3 | 2000 |

    | 66 | First | Developer | C++ Developer | 10 | 5000 |

    | 67 | Second | Developer | C# Developer | 5 | 4000 |

    | 68 | Third | Developer | PHP Developer | 1 | 1000 |

    +----+------------+-----------+----------------+------------+--------+

    В этой статье мы изучили основы использования нативного SQL и рассмотрели пример простого приложения.

    Кеширование.

    Кеширование является одним из способов оптимизации работы приложения, ключевой задачей которого является уменьшить количество прямых обращений к базе данных (далее – БД).

    Если речь идёт о Hibernate, то схематически кэширование можно представить в виде следующего рисунка:



    Кэш первого уровня (First Level Cache)

    Кэш первого уровня – это кэш Сессии (Session), который является обязательным. Через него проходят все запросы. Перед тем, как отправить объект в БД, сессия хранит объект за счёт своих ресурсов.

    В том случае, если мы выполняем несколько обновлений объекта, Hibernate старается отсрочить (насколько это возможно) обновление для того, чтобы сократить количество выполненных запросов. Если мы закроем сессию, то все объекты, находящиеся в кэше теряются, а далее – либо сохраняются, либо обновляются.

    Кэш второго уровня (Second level Cache)

    Кэш второго уровня является необязательным (опциональным) и изначально Hibernate будет искать необходимый объект в кэше первого уровня. В основном, кэширование второго уровня отвечает за кэширование объектов

    Кэш запросов (Query Cache)

    В Hibernate предусмотрен кэш для запросов и он интегрирован с кэшем второго уровня. Это требует двух дополнительных физических мест для хранения кэшированных запросов и временных меток для обновления таблицы БД. Этот вид кэширования эффективен только для часто используемых запросов с одинаковыми параметрами.

    Рассмотрим, как это выглядит на практике.

    Developer.hbm.xml


    "-//Hibernate/Hibernate Mapping DTD//EN"

    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">






    This class contains developer details.













    hibenrate.cfg.xml


    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">





    org.hibernate.dialect.MySQLDialect

    com.mysql.jdbc.Driver


    jdbc:mysql://localhost/ИМЯ_ВАШЕЙ_БАЗЫ_ДАННЫХ

    ВАШЕ_ИМЯ_ПОЛЬЗОВАТЕЛЯ

    ВАШ_ПАРОЛЬ






    Два предыдущих фала нам уже знакомы, а теперь нам необходимо создать файл ehcache.xml

    ehcache.xml



    maxElementsInMemory="500"

    eternal="false"

    timeToIdleSeconds="60"

    timeToLiveSeconds="60"

    overflowToDisk="true"

    />

    maxElementsInMemory="200"

    eternal="true"

    timeToIdleSeconds="0"

    timeToLiveSeconds="0"

    overflowToDisk="false"

    />

    Для того, что кэширование стало доступным для нашего приложения мы должны активировать его следующим образом:




    Session session = sessionFactory.openSession();

    Query query = session.createQuery("FROM HIBERNATE_DEVELOPERS");

    query.setCacheable(true);

    query.setCacheRegion("developer");

    List developers = query.list();

    sessionFactory.close();

    В этой статье мы рассмотрели основы кэширования в Hibernate.
    1   2   3   4   5   6   7


    написать администратору сайта