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 )
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;
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;
@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() }
Set<Book> bookList
we will load data only on demand. @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() }
List<Book> book = (List<Book>)session.createQuery("from Book order by name").list();
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();
List<Book> book=(List<Book>)session.createCriteria(Book.class).createAlias("student", "st").add(Restrictions.eq("st.name", "Maxim")).list();
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();
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();
Source: https://habr.com/ru/post/132385/
All Articles