📜 ⬆️ ⬇️

Hibernate for the smallest and not only

Good all the time of day! When writing a program that will somehow interact with the database, they use various means. This and the good old jdbc are also used: EclipseLink , TopLink , iBatis (already MyBatis ), Spring Framework and of course the hero of our article - Hibernate . Of course, I did not list here all the tools for working with the database, but I tried to indicate the most common ones. This article will show how using Hibernate to call stored procedures, map both tables and class requests. As an experimental database we take Oracle.
Let's prepare everything necessary for experiments. Let's start with the database. To begin with, we will create 3 tablets, over which we will practice.
CREATE TABLE book ( id NUMBER NOT NULL, name VARCHAR2 (100 BYTE) NOT NULL, description VARCHAR2 (1000 BYTE) NOT NULL, CONSTRAINT pk$book_id PRIMARY KEY (id) ) CREATE TABLE student ( id NUMBER NOT NULL, name VARCHAR2 (100 BYTE) NOT NULL, CONSTRAINT pk$student_id PRIMARY KEY (id) ) CREATE TABLE catalog ( id_student NUMBER NOT NULL, id_book NUMBER NOT NULL ) 

Now create a function. which will return the name of the book by its id, an example is stupid, but it will show the principle of calling a function with an input numeric parameter and an output, a string one.
 CREATE OR REPLACE FUNCTION get_book_name_by_id (p_id IN NUMBER) RETURN VARCHAR2 IS v_name VARCHAR2 (100); BEGIN SELECT name INTO v_name FROM book WHERE id = p_id; RETURN v_name; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN '   !!'; END; 

And also, as an experiment, we will create a simple saving procedure in the database, which will have both input parameters and an output one.
 CREATE OR REPLACE PROCEDURE save_book (p_id IN OUT NUMBER, p_name IN VARCHAR2, p_descr IN VARCHAR2) IS BEGIN IF p_id > 0 THEN UPDATE book SET name = p_name, description = p_descr WHERE id = p_id; ELSE SELECT catalog_seq.NEXTVAL INTO p_id FROM DUAL; INSERT INTO book VALUES (p_id, p_name, p_descr); END IF; END; 

Now for the Java classes.
We display our 3 database tables in classes as follows:
 @Entity @Table public class Student implements Serializable { private static final long serialVersionUID = -5170875020617735653L; @Id @GeneratedValue(strategy = GenerationType.AUTO, generator = "my_entity_seq_gen") @SequenceGenerator(name = "my_entity_seq_gen", sequenceName = "catalog_seq") private long id; @Column private String name; @OneToMany(mappedBy = "student", fetch = FetchType.LAZY) private Set<Book> bookList; //     getter, setter, hashCode(), equals(), toString() } 

A bit of explanation on the code:
Mapping the following 2 DB tables will look like this:
 @Entity @Table public class Book implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name="ID") @GeneratedValue(strategy = GenerationType.AUTO, generator = "my_entity_seq_gen") @SequenceGenerator(name = "my_entity_seq_gen", sequenceName = "catalog_seq") private long id; @Column(name="NAME",unique = true, nullable = false, length = 100) private String name; @Column(name="DESCRIPTION",unique = true, nullable = false, length = 100) private String description; @ManyToOne(fetch = FetchType.LAZY,optional=true) @JoinTable(name = "CATALOG", joinColumns = @JoinColumn(name = "ID_BOOK"), inverseJoinColumns = @JoinColumn(name = "ID_STUDENT")) private Student student; //     getter, setter, hashCode(), equals(), toString() } 

Restrictions for fields can be set directly in the annotation, this is done with the following line @Column (name = "NAME", unique = true, nullable = false, length = 100). With the annotations @ManyToOne and @JoinTable (name = "CATALOG") we say that the Book table and the Student table have a many-to-many relationship through the Catalog table, therefore all changes to the Book and Student will be applied automatically to Catalog table.
Well, we are done with the mapping of tables, and now let's move on to working directly with the database.
Extraction of data while filling the collection can be done in different ways:
  1. Using HQL (Hibernate Query Language) queries
      List<Book> book = (List<Book>)session.createQuery("from Book order by name").list(); 
  2. using SQL queries
      List<Book> book = (List<Book>)session.createSQLQuery("select ID, DESCRIPTION, NAME from book order by NAME") .addScalar("id",Hibernate.LONG).addScalar("name").addScalar("description") .setResultTransformer(Transformers.aliasToBean(Book.class)).list(); 
  3. using Criteria
      List<Book> book=(List<Book>)session.createCriteria(Book.class).createAlias("student", "st").add(Restrictions.eq("st.name", "Maxim")).list(); 

Let's go to work with stored procedures. In order to call a function that by id will return the name of the book to us, we will perform the following actions:
 String bookName = (String)session.createSQLQuery("{? = call get_book_name_by_id (:id)}").setLong("id",1).uniqueResult(); 
Suppose we do not have a table with the name Student on the server, but there is only a function that returns a cursor:
 FUNCTION get_all_students RETURN SYS_REFCURSOR IS l_cur SYS_REFCURSOR; BEGIN OPEN l_cur FOR SELECT * FROM student ORDER BY 1; RETURN l_cur; END; 
then the mapping will be as follows, instead of the annotation @Table(name="STUDENT") we write
 @NamedNativeQuery(name="getAllStudent",query="{? = call get_all_students}", callable=true, resultClass=Student.class) 
And the call to this function will be as follows:
  List<Student> student = (List<Student>) session.getNamedQuery("entity").list(); 

Well, to call our save_book procedure, we do the following manipulations:
 CallableStatement st = session.connection().prepareCall("{call save_book(?,?,?)}"); st.setLong(1,0); st.setString(2, " ,   "); st.setString(3,"-   "); st.registerOutParameter(1, java.sql.Types.NUMERIC); st.execute(); System.out.println(st.getLong(1)); 
As you might have noticed, when writing commands to access the database and populate the collection, the word session was used. In our case, this word indicates the main interface between our Java application and the Hibernate framework, that is, org.hibernate.Session session. But first we need to use another fundamental and important interface - SessionFactory. SessionFactory is a global factory responsible for a specific database. To get this factory, we need to get an instance of the org.hibernate.cfg.Configuration class. This is done like this:
  SessionFactory sessions = new Configuration().configure().buildSessionFactory(); 
Where Configuration (). Configure (). BuildSessionFactory () is a parsit file named hibernate.cfg.xml, which is located next to the called program, of course, if no path is specified. Here is the configuration file, which shows the configuration of the connection to the database and the display of our tables:
  <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property> <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:port:baseName</property> <property name="hibernate.connection.username">username</property> <property name="hibernate.connection.password">password</property> <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property> <property name="show_sql">true</property> <mapping class="com.sample.javaHibernate.data.Book" /> <mapping class="com.sample.javaHibernate.data.Student" /> </session-factory> </hibernate-configuration> 
And now, when we have a factory in which there is all the necessary configuration (connection to the database through the pool, mapping / table mapping, etc.) we can work with Session
 Session session = sessions.openSession(); 
You can work with transactions like this: session.beginTransaction(); and accordingly session.getTransaction().commit();
It seems to be all. Of course, I couldn’t cover everything, but I think that would be enough for a quick start.

')

Source: https://habr.com/ru/post/132385/


All Articles