Hibernate学习总结

一、图解运行过程

在这里插入图片描述

二、核心代码

package com.entity;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.Service;
import org.hibernate.service.ServiceRegistry;

import java.util.Scanner;

public class InsertMain {
    public static void main(String[] args) {
        Scanner cin=new Scanner(System.in);
        SessionFactory sessionFactory=null;
        Session session=null;
        Transaction transaction=null;

        //创建Configuration对象,加载配置文件信息和对象关系映射信息
        Configuration configuration=new Configuration().configure();

        //Hibernate的任何配置和服务都需要在该对象中注册后才能使用
        ServiceRegistry serviceRegistry=new StandardServiceRegistryBuilder().
                applySettings(configuration.getProperties()).build();

        //创建一个SessionFactory对象
        sessionFactory=configuration.buildSessionFactory(serviceRegistry);

        //创建一个Session对象
        session=sessionFactory.openSession();
        System.out.println("请依次输入:姓名 性别 年龄");
        String name=cin.next();
        String sex=cin.next();
        int age=cin.nextInt();
        Person person=new Person(name,sex,age);
        
       //启动事务
        transaction=session.beginTransaction(); 
        //执行事务,保存对象         		
        session.save(person);
        //提交事务    
        transaction.commit();    
        session.close();
        sessionFactory.close();
        cin.close();


    }
}

Person.hbm.xml(与Person类在同一个包内)

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <!-- name:类的全路径:-->
    <!-- table:表的名称:(可以省略的.使用类的名称作为表名.)-->
    <class name="com.entity.Person" table="PERSON" >
        <!-- 主键-->
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <!--主键生成策略-->
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

        <property name="sex" type="java.lang.String">
            <column name="sex"></column>
        </property>
        <property name="age" type="int">
            <column name="age"></column>
        </property>
    </class>
</hibernate-mapping>

hibernate.cfg.xml(在src下)

以下2中任选其一,(大多数采用数据池,可以提高系统性能)

1、使用JDBC基本配置

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!--使用JDBC基本配置 --->
        <property name="connection.url">jdbc:mysql:///javaee</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">123456</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

        <!--hibernate 方言-->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <!--打印sql语句-->
        <property name="hibernate.show_sql">true</property>
        <!--格式化sql-->
        <property name="hibernate.format_sql">true</property>

        <!-- 加载映射文件 -->
        <mapping resource="com/entity/Person.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

2、使用 Hibernate 自带的连接池配置

先要导包,
在这里插入图片描述

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!--使用 Hibernate 自带的连接池配置-->
        <property name="connection.url">jdbc:mysql:///javaee</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">123456</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

        <!--hibernate 方言-->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <!--打印sql语句-->
        <property name="hibernate.show_sql">true</property>
        <!--格式化sql-->
        <property name="hibernate.format_sql">true</property>

        <!--设置连接对象的提供支持类        -->
        <property name="connection.provider_class">
           org.hibernate.c3p0.internal.C3P0ConnectionProvider
        </property>
        <!--连接池中JDBC中连接的最小数量,默认为1 -->
        <property name="hibernate.c3p0.min_size">2</property>
        <!-- 连接池中JDBC连接的最大数量,默认100       -->
        <property name="hibernate.c3p0.max_size">5</property>
        <!--何时从连接池中移除一个空闲的连接,默认为0,秒为单位        -->
        <property name="hibernate.c3p0.timeout">100</property>
        <!--被缓存的预编译语句数量,用来提升性能,默认为0,缓存不可用       -->
        <property name="hibernate.c3p0.max_statements">100</property>
        <!--一个连接被自动验证前的闲置时间以秒为单位,默认为0       -->
       <property name="hibernate.c3p0.idle_test_period">3000</property>
        <!-- 加载映射文件 -->
        <mapping resource="com/entity/Person.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

三、session方法

在这里插入图片描述
在这里插入图片描述


//利用get()方法,获取id为10的对象
Person person=(Person)sesstion.get(Person.class,10);

//利用save方法,保存对象
Person person=new Person("张三","男",20);
int n=(int)sesstion.save(person);

//利用update()方法,修改id为10的对象
Person person=(Person)sesstion.get(Person.class,10);
person.setAge(25);
sesstion.update(person);

//利用delete方法,删除id为20的对象
Person person=(Person)sesstion.get(Person.class,20);
sesstion.delete(person);

//createQuery()创建查询接口对象
Query query=sesstion.createQuery("HQL语句");

2、session缓存

2.1、 flush:
由session缓存中的对象更新数据库的记录。

使数据表中的记录与session缓存中的对象状态保持一致,为了保持一致,hibernate可能会发送对应的sql语句。
在Transaction的commit()中,先调用session的flush方法,再提交事务。
flush方法可能会发送对应的sql语句,但不会提交事务。

        SessionFactory sessionFactory=null;
        Session session=null;
        Transaction transaction=null;

        //创建Configuration对象,加载配置文件信息和对象关系映射信息
        Configuration configuration=new Configuration().configure();

        //Hibernate的任何配置和服务都需要在该对象中注册后才能使用
        ServiceRegistry serviceRegistry=new StandardServiceRegistryBuilder().
                applySettings(configuration.getProperties()).build();

        //创建一个SessionFactory对象
        sessionFactory=configuration.buildSessionFactory(serviceRegistry);

        //创建一个Session对象
        session=sessionFactory.openSession();

        transaction=session.beginTransaction();  //启动事务
  
        //查找
       Person person1= (Person)session.get(Person.class,2);
        person1.setSex("男");
       
        transaction.commit();    //提交事务
        
        session.close();
        sessionFactory.close();

一开始。

在这里插入图片描述

提交事务后

在这里插入图片描述

何时会调用flush

  1. Transaction 的commit()方法中会自动调用flush操作。
  2. 显式调用session.flush。
  3. 执行HQL或QBC查询,会先进行flush操作,以便获得最新数据。

若记录的id有底层数据库使用自增方式生成,则在调用session.save(xxx)后立即发送sql语句(在提交事务之前发送)。

————————————————————————————————————————————————

2.2、refresh
由数据库里面的记录更新session缓存中的对象。

session.refresh(object);

无论是不是一致,都会强制性发送select语句。

————————————————————————————————————————————————
2.3、clear
直接清空session缓存

session.clear();

———————————————————————————————————————————————————

3、save()与persist()

 transaction=session.beginTransaction();  //启动事务
        Person person=new Person();
        person.setSex("女");
        person.setName("效应");
        person.setAge(25);
        System.out.println(person.toString());
//        保存
        session.save(person);
        System.out.println(person.toString());

在这里插入图片描述

  1. save()方法,使临时对象变成持久对象
  2. 在save()之前设置id,是无效的。
  3. 持久化对象的id是无法修改的。

save()与persist()的相同点

  1. 都可以执行insert语句

save()与persist()的区别

  1. 在persist()之前,若对象已经有id了,则不会执行insert,会抛出异常。

4、get()

Person person1= (Person)session.get(Person.class,1);

get()与load()方法的区别

  1. get()会立即加载对象。
  2. load()不会立即执行查询操作,而返回一个代理对象。
  3. 若数据表中没有对应记录,get()返回null,load抛出异常。
  4. 数据库断连接后,由load()获得的对象,在使用时会抛异常,由get()获得的,可以正常输出。

5、update()

  • 若更新一个持久化对象,不需要显示的调用update()方法
Person person1= (Person)session.get(Person.class,1);
person1,setName("熊傲雪");
  • 更新一个游离对象,需要显式调用
Person person1= (Person)session.get(Person.class,1);
		transaction.commit();    //提交事务
        
        session.close();
         session=sessionFactory.openSession();

        transaction=session.beginTransaction();  //启动事务
        person1,setName("熊傲雪");
        session.update(person1);

6、delete()

  • 只要数据库内有记录,就会删除,否则抛出异常
session.delete(person);
  • 删除对象后,该对象id置为null
<property name="use_identifier_rollback"></property >

7、evict()

  • 从session缓存中把指定的持久化对象移除
session.evict(person);//移除后,对person的操作无效

8、doWork(),可获得connection对象

session.doWork(new Work() {
            @Override
            public void execute(Connection connection) throws SQLException {
                
            }
        });

四、hibernate.cfg.xml(使用数据库连接池)

使用 Hibernate 自带的连接池配置

先要导包

在这里插入图片描述

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
<!--        配置连接数据库的基本信息-->
        <property name="hibernate.connection.url"> jdbc:mysql:///javaee</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">123456</property>

        <!-- DB schema will be updated if needed -->
         <property name="hibernate.hbm2ddl.auto">update</property>

    <!--        配置hibernate的基本信息-->

        <!--hibernate 方言-->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <!--是否在控制台,打印sql语句-->
        <property name="hibernate.show_sql">true</property>
        <!--格式化sql-->
        <property name="hibernate.format_sql">true</property>

      
        <!--设置连接对象的提供支持类        -->
        <property name="connection.provider_class">
            org.hibernate.c3p0.internal.C3P0ConnectionProvider
        </property>
        <!--连接池中JDBC中连接的最小数量,默认为1 -->
        <property name="hibernate.c3p0.min_size">2</property>
        <!-- 连接池中JDBC连接的最大数量,默认100       -->
        <property name="hibernate.c3p0.max_size">5</property>
        <!--何时从连接池中移除一个空闲的连接,默认为0,秒为单位        -->
        <property name="hibernate.c3p0.timeout">100</property>
        <!--被缓存的预编译语句数量,用来提升性能,默认为0,缓存不可用       -->
        <property name="hibernate.c3p0.max_statements">100</property>
        <!--一个连接被自动验证前的闲置时间以秒为单位,默认为0       -->
        <property name="hibernate.c3p0.idle_test_period">3000</property>
      

  <!-- 加载映射文件 -->
        <mapping resource="com/entity/Person.hbm.xml"/>
        
    </session-factory>
</hibernate-configuration>

五、*.hbm.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <!-- name:类的全路径:-->
    <!-- table:表的名称:(可以省略的.使用类的名称作为表名.)-->
    <class name="com.entity.Person" table="PERSON" >
        <!-- 主键-->
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <!--主键生成策略-->
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

        <property name="sex" type="java.lang.String">
            <column name="sex"></column>
        </property>
        <property name="age" type="int">
            <column name="age"></column>
        </property>
    </class>
</hibernate-mapping>

动态更新

 <class name="com.entity.Person" table="PERSON" dynamic-update="true">
<!--   只更新自己修改的属性值---->

2、 java时间和日期类型的映射

1、
java: java.util.Date, java.util.Calender
标准SQL:DATA表示日期,TIME表示时间,TIMESTAMP表示时间戳,日期+时间
JDBC:java.sql.Date, java.sql.Time ,java.sql.Timestamp

2、如何映射
java.util.Date是java.sql.Date, java.sql.Time ,java.sql.Timestamp的父类,所以设置持久化类时,时间类型设置成java.util.Date类型。

3、如何Date与标准SQL类型映射

通过property的type进行映射。

		<property name="age," type="date">
            
        </property>
        
        <property name="age," type="time">

        </property>
        
        <property name="age," type="timestamp">

        </property>

3、映射类的组合关系

在这里插入图片描述

		 <component name="" class="">
            <parent name=""/>
            <property name="">

            </property>
        </component>

在这里插入图片描述
在这里插入图片描述
![(https://img-blog.csdnimg.cn/86283053f8c141d0a88dda63c0b2d0e4.png)
在这里插入图片描述
在这里插入图片描述

4、映射一对多关系

package com.manyToOne;

public class Customer {
    private Integer id;
    private String name;
    忽略set,get方法
}

package com.manyToOne;

public class Order {
    private Integer id;
    private String name;
    private Customer customer;
   忽略set,get方法
}

Customer.hbm.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <!-- name:类的全路径:-->
    <!-- table:表的名称:(可以省略的.使用类的名称作为表名.)-->
    <class name="com.manyToOne.Customer" table="Customer" >
        <!-- 主键-->
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <!--主键生成策略-->
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>
        
    </class>
</hibernate-mapping>

Order.hbm.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.manyToOne">
    <!-- name:类的全路径:-->
    <!-- table:表的名称:(可以省略的.使用类的名称作为表名.)-->
    <class name="com.manyToOne.Order" table="Order" >
        <!-- 主键-->
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <!--主键生成策略-->
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

<!--        映射1对多关系-->
<!--        name是order类的属性名
            class是这个属性的类
            column是产生外键的名字
-->
        <many-to-one name="customer" class="Customer" column="CUSTOMER_ID">
        </many-to-one>

    </class>
</hibernate-mapping>

hibernate.cfg.xml

 <mapping resource="com/manyToOne/Customer.hbm.xml"/>
 <mapping resource="com/manyToOne/Order.hbm.xml"/>

在这里插入图片描述主类

1、save

Customer customer=new Customer();
sustomer.setName("AA");

Order order=new Order();
order.setName("Order");
order.setCustomer(customer);

//先插入customer,再插入Order
session.save(customer);
session.save(order);

//先插入order,再插入customer,会多出2局update语句,更新order表

2、get


//若查询多的一端,只会查询多的一端,不会查询1的一端
Order order=(order)session.get(Order.class,1);

//当使用那个关联对象时,才会发送sql语句查询1的一端
Customer customer=order.getCustomer();
System.out.println(customer.getName());

3、update

//会正常更新
Order order=(Order)session.get(Order.class,1);
order.getCustomer().setCustomerName=("AAA");

4、delete

//在不设定级联关系的情况下,不能直接删除一这端的对象
Customer customer=(Customer)session.get(Customer.class,1);
session.delete(customer);

5、双向一对多关系映射

package com.manyToOne;

public class Customer {
    private Integer id;
    private String name;
    //初始化,防止出现空指针异常
    private Set<Order> orders=new HashSet<>();
    忽略set,get方法
}
package com.manyToOne;

public class Order {
    private Integer id;
    private String name;
    private Customer customer;
   忽略set,get方法
}

Customer.hbm.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <!-- name:类的全路径:-->
    <!-- table:表的名称:(可以省略的.使用类的名称作为表名.)-->
    <class name="com.manyToOne.Customer" table="Customer" >
        <!-- 主键-->
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <!--主键生成策略-->
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>
        
        <!-- 映射1对多的映射
         table:set中的元素对应的记录放在哪一个数据表中
         key :执行多的表中的外键列的名字
         one-to-many :指定映射类型
         
         cascade:设置级联操作,不建议使用级联
         delete:级联删除
         save-update:级联保存

		order by:在查询时按什么排序
		
		--->
        <set name="orders" table="ORDER" inverse="true" cascade=delete“”>
        <key column="CUSTOMER_ID"></key>
        <one-to-many class="Order"/>
        </set>
    </class>
</hibernate-mapping>

Order.hbm.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.manyToOne">
    <!-- name:类的全路径:-->
    <!-- table:表的名称:(可以省略的.使用类的名称作为表名.)-->
    <class name="com.manyToOne.Order" table="Order" >
        <!-- 主键-->
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <!--主键生成策略-->
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

<!--        映射1对多关系-->
<!--        name是order类的属性名
            class是这个属性的类
            column是产生外键的名字
-->
        <many-to-one name="customer" class="Customer" column="CUSTOMER_ID">


        </many-to-one>

    </class>
</hibernate-mapping>

hibernate.cfg.xml

 <mapping resource="com/manyToOne/Customer.hbm.xml"/>
 <mapping resource="com/manyToOne/Order.hbm.xml"/>

主类

1、save

Customer customer=new Customer();
sustomer.setName("AA");

Order order=new Order();
order.setName("Order");
order.setCustomer(customer);

customer.getOrders.add(order);
session.save(customer);
session.save(order);

  • 可以在1的一端set结点设置inverse=true,来使1的一端放弃维护关联关系。
  • 建议设定setinverse=true,先插入1的一端,后插入多的一端。

2、get


//若查询多的一端,只会查询多的一端,不会查询1的一端
//当使用那个关联对象时,才会发送sql语句查询1的一端
Customer customer=(Customer )session.get(Customer .class,1);
System.out.println(customer.getName());

3、update

  • 会正常更新

4、delete

  • 在不设定级联关系的情况下,不能直接删除一这端的对象

6、一对一关系映射

6.1、基于外键的映射

  • 外键可以存放到任意一边,在需要存放外键的一端,使用many-to-one元素。为many-to-one元素增加unique=“true”属性表示1-1关联
  • 另一端使用one-to-one元素,使用property-ref属性指定使用被关联实体主键以外的字段作为关联字段
public class Manager {
    private Integer id;
    private String name;
    private Department department;
   忽略get,set方法
    
}
public class Department {
    private Integer id;
    private String name;
    private Manager manager;
     忽略get,set方法
}

Department .hbm.xml

 <class name="com.manyToOne.Order" table="DEPARTMENT" >
        <!-- 主键-->
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <!--主键生成策略-->
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>
    <!--
     
		
		--->
        <many-to-one name="manager" class="Manager" column="Manager_ID" unique="true">
        </many-to-one>

    </class>

Manager.hbm.xml

 <class name="com.manyToOne.Order" table="MANAGER" >
        <!-- 主键-->
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <!--主键生成策略-->
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

   <!--
		映射1-1的关联关系,在对应的表中已经有外键了
		没有外键的一端,需要指定 property-ref=“外键的列名”来进行映射
	-->
        <one-to-one name="department" class="Department" property-ref=“manager” >
        </one-to-one>

    </class>

save

  • 建议先保存没有外键的,再保存有外键的

get

  • 懒加载,用到时才会发送sql语句

6.2、基于主键的映射

  • 自己的主键由对方的主键生成,而自己的主键作为对方的外键存在。

Department .hbm.xml

 <class name="com.manyToOne.Order" table="DEPARTMENT" >
        <!-- 主键-->
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <!--主键生成策略-->
            <generator class="foreign">
            <param name="property">manager</param>
		</generator>
        </id>
      
      <one-to-one name="manager" class="Manager" constrained="true">
      </one-to-one>
    </class>

Manager.hbm.xml

 <class name="com.manyToOne.Order" table="MANAGER" >
        <!-- 主键-->
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <!--主键生成策略-->
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

   <!--
		映射1-1的关联关系,在对应的表中已经有外键了
		没有外键的一端,需要指定 property-ref=“外键的列名”来进行映射
	-->
        <one-to-one name="department" class="Department">
        </one-to-one>

    </class>

7、多对多关系映射

使用中间表,作为中转

public class Item {
    private String name;
    private Integer id;
    忽略set,get
}
public class Categoty {
    private Integer id;
    private String name;
    private Set<Item>set=new HashSet<>();
     忽略set,get
}

Item .hbm.xml

 <class name="com.manyToOne.Item " table="Item " >
        <!-- 主键-->
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <!--主键生成策略-->
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>
    </class>

Categoty .hbm.xml

 <class name="com.manyToOne.Categoty " table="Categoty " >
        <!-- 主键-->
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <!--主键生成策略-->
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>
        <!--
        table:指定中间表
        many-to-many指定多对多关联关系
        column执行set集合中的持久化类在中间表的外键列的名称
        -->
		<set name="item" table="CATEGOTY_TITEM">
			<key>
				<column name="C_ID"/>
			</key>
		<many-to-many class="Item" column="I_ID"></many-to-many>
    </class>

8、继承映射

1、subclass

  • 父类和子类使用同一张表。
  • 需要在表内增加一列,来区分是父类还是子类
  • 使用class或者subclass的discriminator-value属性来指定辨别者列的值
  • 所有子类定义的字段都不能有非空约束
    在这里插入图片描述

Person.hbm.xml

<!--配置辨别者列-->
<discriminator column="TYPE"type="string" ></discriminator >
<!--映射子类Student-->
<subclass name="Student" discriminator-value="STUDENT">
<!--自己独有的属性--->
<property name="school" type="string" column="SCHOOL" >
</property>
</subclass>

在这里插入图片描述
在这里插入图片描述

缺点

  • 使用了辨别者列
  • 子类独有的字段不能添加非空约束
  • 继承者多,表的字段就会多

2、joined-subclass

  • 每个子类一张表。
  • 子类和父类共同的属性会放到父类表中,子类表只保存子类独有的属性。
  • 子类使用key元素映射共有主键。

在这里插入图片描述
Person.hbm.xml

<!--
key来映射共有主键
 -->
<joined-subclass name="Student" table="STUDENTS">
<key column="STUDENT_id"></key>
<!--自己独有的属性--->
<property name="school" type="string" column="SCHOOL" >
</property>
</joined-subclass>

3、union-subclass

  • 每个类都映射一张表

在这里插入图片描述
Person.hbm.xml

<union-subclass name="Student" table="STUDENTS">

<!--自己独有的属性--->
<property name="school" type="string" column="SCHOOL" >
</property>

</union-subclass>

六、检索数据(查询数据)

1、 类级别的检索

默认为延迟检索

  • 立即检索:立即加载检索方法指定对象
  • 延迟检索:使用具体属性时,再进行加载

类级别的检索策略可以通过< class>元素的 lazy 属性进行设置。

2、1-n,n-n,的检索策略

可以通过修改set的 lazy 属性来改变检索策略。默认为true,并不建议设置false

七、HQL语言和Query

在这里插入图片描述

1、form

//查询所有人的全部信息
String hql="from Person";
Query query=sesstion.createQuery(hql);
List list=query.list();

2、where子句

格式:
from 类名 where 查询条件

String hql="from Person where age=?";
Query query=session.createQuery(hql);
query.setParameter(0,18);
List<Person> list= query.list();
 for (Person person:list
       ) {
       System.out.println(person.toString());
        }

3、设置分页显示

//若页号为pageNo,页大小为pageSize

String hql="from Person";
Query query=sesstion.creatQuery(hql);

<!-- 设定从哪个对象开始检索--->
query.setFirstResult(pageNo-1)*pageSize);
<!-- 设定一次最多检索出的对象数目-->
query.setMaxResults(pageSize);
List<Person> list= query.list();

4、select(投影查询)

格式:
select 属性1,属性2,…from 类名;

//查询所有人的名字
String hql="select name from Person";
Query query=sesstion.createQuery(hql);
List list=query.list();

//将查询到的内容封装到对象中
String hql="select new Student(s.id,s.name) from Student s"; 

5、报表查询

//查询最大年龄与最小年龄
String hql="select min(s.age),max(s.age) from student";
Query query=sesstion.createQuery(hql);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值