Hibernate Advanced Application

One-way N-1 association

One-way N-1 relationship, for example, multiple people correspond to one address, only the corresponding address entity can be found from the person entity side, and there is no need to relate all the households of a certain address. A unidirectional N-1 association requires only one end of 1 to be accessible from one end of N.

domain model

The many-to-one one-way association from Order to Customer needs to define a Customer property in the Order class, and there is no need to define a collection property that stores the Order object in the Customer class. That is, one customer can correspond to multiple orders.

relational data model       

The CUSTOMER_ID in the ORDERS table refers to the primary key of the CUSTOMER table.


Configure the relationship mapping file (Order.hbm.xml)

many-to-one specifies the foreign key, and will find the class to establish a many-to-one relationship with ORDER according to the reflection mechanism. By default, the column can be empty.

<many-to-one name="customer" column="CUSTOMER_ID" class="mypacker.entity.Customer"></many-to-one>

 To map many-to-one relationships, use many-to-one to map many
  - to
  - one relationships                                                                                                                         The name of the foreign key in the data table corresponding to the multi-end is
  the type of department

Configure persistence class:

public class Order {
	private Integer orderId;
	private String orderName;
	private Customer customer;	
	//One-way many-to-one (if that class also has a one-to-many to this class, this is a two-way many-to-one)

save() method

public void testMany2OneSave(){
		Customer customer = new Customer();
		customer.setCustomerName("AA"); ////Create a CustomerName=AA data in the Customer table, the ID is automatically generated
		Order order1 = new Order();
		order1.setOrderName("Order-1");//Create Order-1 and Order-2 data in the Order table, the ID is also automatically generated, the foreign key Customer_ID is equal to the ID of the AA data above
		Order order2 = new Order();
		order2.setOrderName("Order-2");
		//Set the relationship
		//Add a Customer object information to the two Order objects
		order1.setCustomer(customer);
		order2.setCustomer(customer);
		//Execute the save operation: it is recommended to insert one end of 1 first, and then insert one end of n
		//If you insert Order first, then insert Customer, 3 INSERTs and 2 UPDATEs will be generated
		//Because the foreign key value of one end of 1 cannot be determined when inserting more ends, we can only wait for one end of 1 to be inserted, and then send an additional UPDATE statement
		session.save(customer);
		session.save(order1);
		session.save(order2);
		transaction.commit();
	}
Hibernate:
	    insert
	    into
	        CUSTOMERS
	        (CUSTOMER_NAME)
	    values
	        ('AA')	##CUSTOMER_ID为1##
	Hibernate:
	    insert
	    into
	        ORDERS
	        (ORDER_NAME, CUSTOMER_ID)
	    values
	        (Order-1, 1)
	Hibernate:
	    insert
	    into
	        ORDERS
	        (ORDER_NAME, CUSTOMER_ID)
	    values
	        (Order-2, 1)


get() method

public void testMany2OneGet(){
		//1. If you query the objects at the more end, by default, only the objects at the more end are queried, and the objects at the one end of the associated one are not queried.
		//When getting an Order object, by default, its associated Customer object is a proxy object
		Order order = (Order) session.get(Order.class,5);
		System.out.println(order.getOrderName());
		//session.close();
		//2. Only send the corresponding SQL query statement when the properties of the associated object need to be used
		Customer customer = new Customer();
		System.out.println(customer.toString());
		
		//3. When querying the Customer object, when navigating from one end to one end, if the session has been closed at this time, a lazy loading exception will occur
	}

The console prints out the SQL statement:

/*
	Hibernate:
	    select
	        order0_.ORDER_ID as ORDER1_1_0_,
	        order0_.ORDER_NAME as ORDER2_1_0_,
	        order0_.CUSTOMER_ID as CUSTOMER3_1_0_
	    from
	        ORDERS order0_
	    where
	        order0_.ORDER_ID=?
	*/


update() method

public void testMany2OneUpdate(){
		Order order = (Order) session.get(Order.class,5);
		order.getCustomer().setCustomerName("AAA");
		//Get the corresponding customer through the record with orderId=5, and the id=3 of the customer in the database, so the name of the record with id=3 in the costumer table is changed to AAA
		session.update(order);
		transaction.commit();
	}

The console prints out the SQL statement:

Hibernate:
    select
        order0_.ORDER_ID as ORDER1_1_0_,
        order0_.ORDER_NAME as ORDER2_1_0_,
        order0_.CUSTOMER_ID as CUSTOMER3_1_0_
    from
        ORDERS order0_
    where
        order0_.ORDER_ID=5
Hibernate:
    select
        customer0_.CUSTOMER_ID as CUSTOMER1_0_0_,
        customer0_.CUSTOMER_NAME as CUSTOMER2_0_0_
    from
        CUSTOMERS customer0_
    where
        customer0_.CUSTOMER_ID=?
Hibernate:
    update
        CUSTOMERS
    set
        CUSTOMER_NAME=?
    where
        CUSTOMER_ID=?

delete() method

public void testMany2OneDelete(){
		Customer customer = (Customer) session.get(Customer.class,3);
		//In the case where the association relationship is not set, and the object on the 1 end is referenced by the n object, the object on the 1 end cannot be directly deleted
		//That is to say, the primary key data in the CUSTOMER table has corresponding foreign key data in the ORDER table. If the record with the primary key = 1 of CUSTOMER is deleted, the record with the foreign key = 1 in the ORDER table will not work. It corresponds to the main table, so there will be an error. You must first delete the record with foreign key = 1 in the ORDER table before deleting the record with CUSTOMER's primary key = 1
		//org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
		session.delete(customer);
		transaction.commit();
	}


Bidirectional 1-N association

For 1-N associations, Hibernate recommends using bidirectional associations, and do not let one end of 1 control the association relationship, and use the end of N to control the association relationship. Bidirectional N-1 associations are exactly the same as 1-N associations. Both ends need to add access to the associated attributes. One end of N adds attributes that refer to the associated entity, and one end of 1 increases the collection attribute, and the collection element is the associated entity.  

domain model 

The many-to-one bidirectional association from Order to Customer needs to define a Customer property in the Order class, and a collection property that stores the Order object needs to be defined in the Customer class.

relational data model

The CUSTOMER_ID in the ORDERS table refers to the primary key of the CUSTOMER table.     

Configure Relationship Mapping File

<set name="orders" inverse="true" cascade="delete" order-by="ORDER_NAME DESC">
			<key column="CUSTOMER_ID"></key> <!-- key specifies the foreign key in the ORDER table -->
			<one-to-many class="mypacker.entity.Order"></one-to-many><!-- one-to-many specifies which class to perform one-to-many mapping with -->
			</set>
name: the name of the attribute at the one end associated with the multiple end
column: the name of the foreign key in the data table corresponding to the one end at the multiple end
class: the class name corresponding to the attribute at the one end


3 properties of Hibernate_set

① The inverse attribute of the <set> element determines which side of the bidirectional association maintains the relationship between the table and the table by setting the inverse attribute in Hibernate. Inverse=false is the active side, and inverse=true is passive. The active party is responsible for maintaining the association relationship. In the absence of inverse=true, the parent-child relationship is maintained on both sides.    

②<set>, <many-to-one>, and <one-to-many> all have a cascade attribute, which is used to set cascade operations. It is not recommended to set this attribute during development. Commonly used values ​​include: save-update: When the current object is saved or updated through the save(), update(), saveOrUpdate() methods of the Session, all associated newly created temporary objects are saved in cascade, and all new temporary objects are cascaded to update The associated detached object. delete: When the current object is deleted through the delete() method of the Session, all associated objects will be deleted in cascade. delete-orphan: Delete all objects that are in contact with the current object.      

③ The order-by attribute of the <set> element, if this attribute is set, when Hibernate retrieves the collection object from the database through the select statement, it uses the order by clause to sort. SQL functions can also be added to the order-by attribute. The table field name is used in order-by, not the property name of the persistent class.


Configure persistent classes

public class Customer {
	private Integer customerId;
	private String customerName;
	//Need to initialize the collection to prevent null pointer exception
	//When declaring the collection type, you need to use the interface type, because when Hibernate gets the collection type, it returns the Hibernate built-in collection type, not a standard collection implementation in JavaSE
	private Set<Order> orders = new HashSet<Order>(); //Bidirectional one-to-many


save() method

public void testOne2ManySave(){
		Customer customer = new Customer();
		customer.setCustomerName("GG"); //Create a data with CustomerName=GG in the Customer table, and the ID is automatically generated
		Order order1 = new Order();
		order1.setOrderName("Order-3"); //Create Order-3 and Order-4 data in the Order table, the ID is also automatically generated, the foreign key Customer_ID is equal to the ID of the GG data above
		Order order2 = new Order();
		order2.setOrderName("Order-4");
		//Set the relationship
		order1.setCustomer(customer);
		order2.setCustomer(customer);
		//Add two Order information to the current Customer object
		customer.getOrders().add(order1);
		customer.getOrders().add(order2);
		//Execute the save operation: insert Customer first, then insert Order, 3 INSERT statements, 2 UPDATE statements
		//Because one end of 1 and one end of n both maintain the association relationship, there will be more UPDATEs
		//You can specify inverse=true at the set node at one end of 1 to make one end of 1 give up maintaining the association relationship
		//It is recommended to set the inverse=true of the set. It is recommended to insert one end of 1 first, and then insert the more end, the advantage is that there will be no more UPDATE statements
		session.save(customer);
		session.save(order1);
		session.save(order2);
		transaction.commit();
	}

get() method

public void testOne2ManyGet(){
		//Use lazy loading for the collection at one end of n, which is initialized when the elements in the collection are used, so a lazy loading exception may also be thrown
		Customer customer = (Customer) session.get(Customer.class,1);
		//The collection of the returned end is the built-in collection type of Hibernate, which has the function of lazy loading and storing proxy objects
		System.out.println(customer.getCustomerName());
	}

update() method

public void testOne2ManyUpdate(){
		Customer customer = (Customer) session.get(Customer.class,4);
		customer.getOrders().iterator().next().setOrderName("GGG");	
		//Change the ORDER_NAME corresponding to the data of the foreign key CUSTOMER_ID=4 to GGG, but only the first one has been changed
		session.save(customer);
		transaction.commit();
	}

delete() method

public void testOne2ManyDelete(){
		Customer customer = (Customer) session.get(Customer.class,4);
		//Similar to many-to-one, if the association relationship is not set, and the object at the end of 1 is referenced by the object of n, the object at the end of 1 cannot be directly deleted
		//That is to say, the primary key data in the CUSTOMER table has corresponding foreign key data in the ORDER table. If the record with the primary key = 1 of CUSTOMER is deleted, the record with the foreign key = 1 in the ORDER table will not work. It corresponds to the main table, so there will be an error. You must first delete the record with foreign key = 1 in the ORDER table before deleting the record with CUSTOMER's primary key = 1
		session.delete(customer);
	}


HQL: Hibernate Query Language

HQL (Hibernate Query Language) is an object-oriented query language, which is somewhat similar to the SQL query language. Among the various retrieval methods provided by Hibernate, HQL is the most widely used retrieval method.

The HQL query consists of the following steps:

1. Get the Hibernate Session object. 2. Write HQL statements. 3. With the HQL statement as a parameter, call the createQuery method of the Session to create a query object. 4. If the HQL statement contains parameters, call the setXxx method of Query to assign values ​​to the parameters. 5. Call the list() or uniqueResult() method of the Query object to return a list of query results. 

public class UserTest {  
    Session session;  
      
    //junit test, first execute before, after content, and finally execute after, which reduces the amount of repetitive code  
    @Before  
    public void before(){  
        Configuration configuration = new Configuration().configure();  
        SessionFactory sessionFactory = configuration.buildSessionFactory(  
                new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build());  
        session = sessionFactory.getCurrentSession();  //sessionFactory.openSession()  
        session.beginTransaction();  
    }  
      
    @After  
    public void after(){  
        session.getTransaction().commit();  
    }  
      
    @Test  
    public void testAddUser() {  
        User user = new User(1,"张三","abcd",new Date());  
        session.save(user);  
    }  
      
    @Test  
    public void testSelectUserById(){  
//      User user = (User) session.get(User.class, 1);  
        User user = (User) session.load(User.class, 1);  
        System.out.println(user);  
    }  
    @Test  
    public void testUpdate(){  
//      User user = new User(1,"李四1","123",new Date());  
//      session.update(user);  
          
        User user = (User) session.get(User.class, 1);  
        user.setUserName("王二");  
          
        session.update(user);  
    }  
      
    @Test  
    public void testDelete(){  
//      User user = new User(1,"李四1","123",new Date());  
//      session.delete(user);  
          
        User user = (User)session.get(User.class, 2);  
        session.delete(user);  
    }  
      
    @Test  
    public void testSelectAllUser(){  
        String hql = "FROM User ORDER BY id DESC ";  
          
        Query query = session.createQuery(hql);  
        List<User> userLists = query.list();  
        for(User user:userLists){  
            System.out.println(user);  
        }  
    }  
      
    @Test  
    public void testSelectUserName(){  
        String hql = "SELECT u.userName FROM User AS u";  
          
        Query query = session.createQuery(hql);  
        List<String> userLists = query.list();  
        for(String user:userLists){  
            System.out.println(user);  
        }  
    }  
    @Test  
    public void testSelectdUserByUsername(){  
        String hql = "FROM User WHERE userName = :name AND passWord = :psw";  
        Query query = session.createQuery(hql);  
        query.setParameter("name", "张三");  
        query.setParameter("psw", "abcd");  
        User user = (User) query.uniqueResult();  
        System.out.println(user);  
    }  
      
    @Test  
    public void testUpdateUsers(){  
        String hql = "UPDATE User SET userName=:name WHERE passWord=:psw";  
        Query query = session.createQuery(hql);  
        query.setParameter("name", "麻子");  
        query.setParameter("psw", "123");  
        int order = query.executeUpdate();  
        System.out.println("order :"+order);  
    }  
      
    @Test  
    public void testDeleteUserByUserName(){  
        String hql = "DELETE User WHERE userName = :name";  
        Query query = session.createQuery(hql);  
        query.setParameter("name", "张三");  
        query.executeUpdate();  
          
    }  
      
}



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325763752&siteId=291194637