Hibernate

1.     Hibernate简介

Hibernate 是非常优秀、成熟的、开放源代码的 O/R Mapping 框架。它提供了强大的对象和关系数据库映射以及查询功能。Hibernate提供了对关系型数据库增删改查操作。

 

1.1. Hibernate的好处

Hibernate对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码

Hibernate是一个基于jdbc的主流持久化框架,是一个优秀的orm实现,它很大程度的简化了dao层编码工作

Hibernate使用java的反射机制,而不是字节码增强程序类实现透明性

Hibernate的性能非常好,因为它是一个轻量级框架。映射的灵活性很出色。它支持很多关系型数据库,从一对一到多对多的各种复杂关系。

1.2. Hibernate解压包目录详解

 documentation  :Hibernate文档

lib             :Hibernate开发jar包

* bytecode   :操作字节码jar包.

* jpa        :Hibernate的实现jpa规范.

     *hibernate-jpa-2.0-api-1.0.1.Final.jar : JPA 接口开发包

* optional   :Hibernate的可选jar包.

* required   :Hibernate的必须的jar包.

* antlr-2.7.6.jar:一个语言转换工具,Hibernate利用它实现 HQL 到 SQL 的转换

* commons-collections-3.1.jar :collections Apache 的工具集,用来增强Java                                      对集合的处理能力

* dom4j-1.6.1.jar  :dom4j XML 解析器

* javassist-3.12.0.GA.jar :代码生成工具, Hibernate用它在运行时扩展 Java类

* jta-1.1.jar  : 标准的 JAVA 事务(跨数据库)处理接口

project         :Hibernate提供的工程

    hibernate3.jar   :hibernate的核心包

 

 

2.     Hibernate的入门案例

2.1. 创建普通java工程并导入jar包

Hibernate解压路径/hibernate3.jar

Hibernate解压路径/lib/required/*.jar

Hibernate解压路径/lib/jpa/hibernate-jpa-2.0-api-1.0.0.Final.jar

数据库对应的 JDBC 驱动

还可以加入日志文件相关的jar包(可选)

log4j-1.2.17.jar和slf4j-log4j12-1.7.12.jar

2.2. 编写实体类

2.3. 编写*.hbm.xml

命名规则:实体名.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.ys.entity.User"  table="hibernate_user">

         <!-- 配置属性与字段之间的关系 -->

         <!-- 主键 -->

         <!--

             name属性:实体的属性名

             column属性:数据库表的字段名

            -->

         <id name="id" column="user_id">

              <!-- 配置主键生成策略 -->

              <generator class="native"></generator>

         </id>

        

         <!-- 其他普通属性 -->

         <property name="username" column="user_name"></property>

         <property name="userpwd" column="user_pwd"></property>

    </class>   

</hibernate-mapping>

 

 

2.4. 编写hibernate配置文件

(hibernate.cfg.xml/hibernate.properties)

<?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 -->

    <session-factory>

        <!-- 配置连接数据库的四要素

               到:hibernate的解压路径/project/etc/hibernate.properties

        -->

        <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>

        <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>

        <property name="hibernate.connection.username">scott</property>

        <property name="hibernate.connection.password">123456</property>

   

        <!-- 方言 -->

        <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>

       

        <!-- 配置可选项 -->

        <!-- 显示sql语句 -->

        <property name="hibernate.show_sql">true</property>

        <!-- 格式化sql语句 -->

        <property name="hibernate.format_sql">true</property>

       

        <!-- 配置映射文件 -->

        <mapping resource="com/ys/entity/hbm/User.hbm.xml"/>

       

    </session-factory>

</hibernate-configuration>

 

 

2.5. 使用hibernate api操作数据库

编写步骤:

1) 获取 Configuration 对象。

2) 获取 SessionFactory 对象。

3) 获取 Session,打开事务。

4) 用面向对象的方式操作数据库。

5) 关闭事务,关闭 Session。

package com.ys.test;

 

import java.io.Serializable;

 

import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

import org.hibernate.cfg.Configuration;

import org.hibernate.classic.Session;

 

import com.ys.entity.User;

 

public class HibernateTest {

        

         public static void main(String[] args) {

                  

                   //1.读取配置文件的信息

                   //默认加载classpath下的hibernate.cfg.xml配置文件

                   Configuration configuration = new Configuration().configure();

                   //2.获取到SessionFactory

                   SessionFactory sessionFactory = configuration.buildSessionFactory();

                   //3.获取到与数据库的会话Session

                   Session session = sessionFactory.openSession();

                   //4.获取事务管理类

                   Transaction transaction = session.beginTransaction();

                   //5.操作数据库

                   User user = new User();

                   user.setId(1);

                   user.setUsername("xiaoming");

                   user.setUserpwd("123456789");

                   //保存数据到数据库

                   Serializable save = session.save(user);

                   System.out.println(save);

                   //事务提交

                   transaction.commit();

                   //关闭资源

                   session.close();

                   sessionFactory.close();

         }

}

 

 

2.6. Hibernate的运行流程

 

1) 应用程序先调用Configuration 类,该类读取 Hibernate 配置文件及映射文件中

的信息,并用这些信息生成一个SessionFactory 对象

2) 从SessionFactory 对象生成一个 Session 对象

3) 用 Session 对象生成Transaction 对象

4) 可 通 过 Session 对 象 的get(),load(),save(),update(),delete() 和

saveOrUpdate()等方法对 实体类进行加载、保存、更新、删除、等操作;

5) 在查询的情况下,可通过Session 对象生成一个 Query 对象,然后利用 Query 对

象执行查询操作;如果没有异常,Transaction对象将提交这些操作到数据库中。

3.     Hibernate实现对数据库的CRUD操作

3.1. 通过Id查询单条数据

//查询get()

    @Test

    publicvoid  testFind(){

        Session session = HibernateUtil.getSession();

        User user  = (User) session.get(User.class,1);

        System.out.println(user);

    }

//查询load()

    @Test

    publicvoid testFind02(){

        Session session = HibernateUtil.getSession();

    User user  = (User)

session.load(User.class,1);

        System.out.println(user);

    }

get与load的区别:

             查询时机的不同:

               load延时加载,当查询的内容使用时才发起查询

                get执行get方法就发起查询

             查询数据时,当数据不存在,返回值不同:

                get:返回null

                load:报ObjectNotFoundException异常

            实际返回的对象的不同:

                get:返回实际对象

          *    load:返回的代理对象

3.2. 新增数据

//新增

    @Test

    publicvoid testSave(){

        Session session = HibernateUtil.getSession();

        Transaction transaction = session.beginTransaction();

        User user = new User();

        user.setUsername("zhangsan");

        user.setUserpwd("123456");

        session.save(user);

        //提交事务

        transaction.commit();

    }

 

3.3. 修改数据

//修改

    @Test

    publicvoid testUpdate(){

        Session session = HibernateUtil.getSession();

        Transaction transaction = session.beginTransaction();

        User user = new User();

        user.setId(2);

        user.setUsername("春哥");

        session.update(user);

        //提交事务

        transaction.commit();

    }

 

3.4. 删除数据

//删除

    @Test

    publicvoid testDelete(){

        Session session = HibernateUtil.getSession();

        Transaction transaction = session.beginTransaction();

        User user = new User();

        user.setId(1);

        session.delete(user);

        //session.de

        transaction.commit();

    }

 

3.5. 查询多条数据

3.5.1.  HQL的方式

//查询多条数据(HQL的方式进行查询)

    @Test

    publicvoid  testFindList(){

        String hql = "from User";

        Session session = HibernateUtil.getSession();

        Query query = session.createQuery(hql);

        List list = query.list();

        System.out.println(list);

       

    }

   

    //带条件查询

    @Test

    publicvoid  testFindListByCondition(){

        String hql = "from User where username=?";

        Session session = HibernateUtil.getSession();

        Query query = session.createQuery(hql);

        query.setString(0, "xiaoming");

        List list = query.list();

        System.out.println(list);

    }

 

3.5.2.  SQL的方式

//查询列表数据使用sql

    @Test

    publicvoid testFindListInSql(){

        String sql = "select * from hibernate_user";

        Session session = HibernateUtil.getSession();

        SQLQuery sqlQuery = session.createSQLQuery(sql);

        //指定查询结果的类型

        sqlQuery.addEntity(User.class);

        List list = sqlQuery.list();

        System.out.println(list);

    }

 

3.5.3.  Criteria的方式

//条件查询

    @Test

    publicvoid testFindListByCriteria(){

        Session session = HibernateUtil.getSession();

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

        //设置查询条件

        criteria.add(Restrictions.eq("username", "xiaoming"));

        List list = criteria.list();

        System.out.println(list);

    }

   

 

4.     Hibernate 配置文件

Xml配置文件

  hibernate.cfg.xml

Properties的配置文件

 hibernate.properties

     无法配置映射文件

      注意事项:需要在编程阶段手动配置映射文件

      new  Configuration ();

   

4.1. 必须的配置:

连接数据库4个基本参数:

hibernate.connection.driver_class  连接数据库驱动程序

hibernate.connection.url   连接数据库URL

hibernate.connection.username  数据库用户名

hibernate.connection.password   数据库密码

 

 Hibernate的方言:

hibernate.dialect   操作数据库方言

 

4.2. 可选的配置:

hibernate.show_sql  true 在控制台上输出SQL语句

hibernate.format_sql  true  格式化控制台输出的SQL语句

hibernate.connection.autocommit  true 事务是否自动提交

hibernate.hbm2ddl.auto create/create-drop/update/validate

1.create   :每次执行的时候,创建一个新的表.(如果以前有该表,将该表删除重新创建.) 一般测试的时候的使用.

2.create-drop :每次执行的时候,创建一个新的表,程序执行结束后将这个表,删除掉了.       一般测试的时候使用.需要关闭sessionFactory

3.update :如果数据库中没有表,创建一个新的表,如果有了,直接使用这个表.可以更新表的结构.

4.validate:会使用原有的表.完成校验.校验映射文件与表中配置的字段是否一致.不一致报错.

 

注意事项:

MYSQL中使用该属性配置,需要使用MysqlDialect方言

使用create-drop时,需要关闭sessionFactory才能将创建的表删除

4.3. 映射的配置:

* 在核心配置文件中加载映射文件:

* <mapping resource="" />

4.4. C3P0 数据库连接池属性

4.4.1.  导入c3p0对应的jar包

 

4.4.2.  在核心配置文件中配置如下属性

hibernate.connection.provider_class 该类用来向Hibernate 提供 JDBC 连接

hibernate.c3p0.max_size 数据库连接池的最大连接数

hibernate.c3p0.min_size 数据库连接池的最小连接数

hibernate.c3p0.timeout 数据库连接池中连接对象在多长时间没有使

用过后,就应该被销毁

hibernate.c3p0.max_statements 缓存 Statement 对象的数量

hibernate.c3p0.validate 是否每次连接都验证连接是否可用

hibernate.c3p0.acquire_increment 当数据库连接池中的连接耗尽时, 同一时刻

获取多少个数据库连接

  <!-- 配置c3p0 -->

       <!-- 导入c3p0对应的jar包 -->

       <!-- 配置对应的属性 -->

       <!-- 配置连接提供者 -->

       <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>

       <!-- 据库连接池的最大连接数 -->

       <property name="hibernate.c3p0.max_size">300</property>

       <!-- 数据库连接池的最小连接数 -->

       <property name="hibernate.c3p0.min_size">20</property>

       <!-- 数据库连接池中连接对象在多长时间没有使用过后,就应该被销毁 -->

       <property name="hibernate.c3p0.timeout">30</property>

     

 

5.     配置log4j

5.1.  导入jar包

5.2. 在classpath下创建log4j.properties配置文件

输出到控制台

log4j.rootLogger=DEBUG,stdout

 

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

 

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

 

log4j.appender.stdout.layout.ConversionPattern=%-4r%-5p[%t]%37c%3x-%m%n

 

输出到本地日志文件

log4j.rootLogger=DEBUG,stdout

 

log4j.appender.stdout=org.apache.log4j.FileAppender

 

log4j.appender.stdout.File=D:/hibernate.log

 

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

 

log4j.appender.stdout.layout.ConversionPattern=%-4r%-5p[%t]%37c%3x-%m%n

 

同时把日志输出到控制台和本地日志文件

log4j.rootLogger=DEBUG,stdout,B

 

log4j.appender.stdout=org.apache.log4j.FileAppender

 

log4j.appender.stdout.File=D:/hibernate.log

 

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

 

log4j.appender.stdout.layout.ConversionPattern=%-4r%-5p[%t]%37c%3x-%m%n

 

 

#log2console

log4j.appender.B=org.apache.log4j.ConsoleAppender

 

log4j.appender.B.layout=org.apache.log4j.PatternLayout

 

log4j.appender.B.layout.ConversionPattern=%-4r%-5p[%t]%37c%3x-%m%n

 

 

6.     Hibernate的映射文件

主键生成策略

* increment     :自动增长.适合 short int long...不是使用数据库的自动增长机制.使用Hibernate框架提供的自动增长方式.

* select max(id) from 表; 在最大值的基础上+1.(多线程的问题.)在集群下不要使用

* identity          :自动增长.适合 short int long...采用数据库的自动增长机制.不适合于Oracle数据库.

* sequence       :序列.适用于 short int long ... 应用在Oracle上 .

* uuid                 :适用于字符串类型的主键.采用随机的字符串作为主键.

* native             :本地策略.底层数据库不同.自动选择适用identity 还是 sequence.

* assigned                 :Hibernate框架不维护主键,主键由程序自动生成.

* foreign           :主键的外来的.(应用在多表一对一的关系.)

在映射实体类的属性和数据库的表时,可以指定对应的类型和具体的长度

7.     Hibernate的核心API简介

Hibernate的参考资料:hibernate资源包的解压路径/documentation/manual/各种语言版本的使用手册。

7.1. Configuration

Configuration类负责管理 Hibernate 的配置信息

Configuration的作用:

加载核心配置文件

1.        属性文件

Configuration configuration = new Configuration();

 

2.        Xml文件

Configuration configuration = new Configuration().configure();--默认加载hibernate.cfg.xml

加载其他名字或者路径的配置文件的方式:

Configuration configuration = new Configuration().configure(‘配置文件的路径及文件名’);

 

加载映射文件

1.        addResource

Configuration.addResource(“映射文件的路径”);

例子:Configuration.addResource(“com/ys/entity/hbm/User.hbm.xml”);

 

2. addClass

   注意事项:映射文件和类必须在同一个包下

7.2. SessionFactory

Configuration 对 象 根 据 当 前 的 配 置 信 息 生 成 SessionFactory 对 象 。

SessionFactory 对象一旦构造完毕,即被赋予特定的配置信息(SessionFactory 对

象中保存了当前的数据库配置信息和所有映射关系以及预定义的 SQL 语句。同时,

SessionFactory 还负责维护 Hibernate 的二级缓存

说明:

1)SessionFactory 是线程安全的。

2) 构造SessionFactory 很消耗资源,一般情况下一个应用中只初始化一个

SessionFactory 对象。

3)SessionFactory是生成 Session 的工 厂。

Session session= sessionFactory.openSession()。

7.3. Session

Session 是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运

作的中心,所有持久化对象必须在 session 的管理下才可以进行持久化操作。此对象的

生命周期很短。Session中维护一级缓存,显式执行 flush()方法之前,所有的持久层操

作的数据都缓存在 session 对象处。(相当于 JDBC 中的 Connection)。一般一个

业务操作使用一个 Session。

 

说明:

1) 持久化类与 Session关联起来后就具有了持久化的能力。

2) Session 是线程不安全的,一般是一次业务操作使用一个Session。

7.3.1.  Session 常用方法

save()/persist()                  :添加.

update()                        :修改

saveOrUpdate()               :增加和修改对象

delete()                             :删除对象

get()/load()                 :根据主键查询

createQuery()                  :创建一个Query接口,编写HQL语句

createSQLQuery()       :创建一个SQLQuery接口,编写SQL语句数据库操作对象

createCriteria()          :返回一个Criteria接口.条件查询

 

 

(一)save(Object obj)

Session 的 save() 方法使一个临时对象转变为持久化对象。

(1) Session 的 save() 方法完成以下操作

1) 把 News 对象(临时对象)加入到 Session 缓存中, 使它进入持久化状态

2) 选用映射文件指定的标识符生成器, 为持久化对象分配唯一的 OID。在使用代理

主键的情况下, setId() 方法为对象设置 OID 是无效的。

3) 计划执行一条 insert语句,把持久化对象当前的属性值组装到 insert 语句中

(2) Hibernate 通过持久化对象的 OID 来维持它和数据库相关记录的对应关系. 当

News 对象处于持久化状态时, 不允许程序随意修改它的ID.

(二) update()

(1) Session 的 update() 方法使一个游离对象转变为持久化对象, 并且计划执行一

条 update 语句。

(2) 若希望 Session 仅当修改了 News 对象的属性时, 才执行 update() 语句, 可

以把映射文件中 <class> 元素的 select-before-update(更新之前先查询) 设

为 true. 该属性的默认值为 false

(3) 当 update() 方法关联一个游离对象时, 如果在 Session 的缓存中已经存在相同

OID 的持久化对象, 会抛出异常,原因是两个不同的对象拥有相同的 OID。

(4) 当 update() 方法关联一个游离对象时, 如果在数据库中不存在相应的记录, 也会

抛出异常

(三) saveOrUpdate()

该方法同时包含 save 和 update 方法,如果参数是临时对象就用 save 方法,如果是

游离对象就用 update 方法,如果是持久化对象就直接返回。判定对象为临时对象的标准:

1) Java 对象的 OID 为 null

2) 映射文件中为 <id> 设置了unsaved-value 属性, 并且 Java 对象的 OID 取

值与这个 unsaved-value 属性值匹配

(四) get(),load()

共同点:都可以根据给定的 OID 从数据库中加载一个持久化对象

区别:

1.查询的时机不同

load这个方法采用了一个技术.lazy延迟加载(懒加载).真正使用这个对象的数据的时 才进行查询

2.返回的对象

load方法返回的是代理对象. get方法返回的是真实的对象.

3.查询的数据不存在

查     询一个不存在的数据当 数 据 库 中 不 存 在 与 OID 对 应 的 记 录 时

load() 方 法 抛 出ObjectNotFoundException异常, 而 get() 方法返回 null

 

(五) delete()

Session 的 delete(obj)方法既可以删除一个游离对象, 也可以删除一个持久化象。如果参数是持久化对象,就执行一个 delete 语句,若为游离对象,先使游离对象被session 关联,使他变为持久化对象计划执行一条 delete 语句把对象从 Session 缓存中删除, 该对象进入删除状态.

7.4. Transaction

Transaction 接口是 Hibernate 的数据库事务接口,代表一次原子操作,它具有数

据库事务的概念,它对底层的事务接口做了封装,底层事务接口包括:

1) JDBC API

2) JTA(Java Transaction API)

3) CORBA(Common Object Request BrokerArchitecture) API

获得事务对象:Transaction tx = session.beginTransaction();

常用方法:

1) commit():提交相关联的session 实例

2) rollback():撤销事务操作

3) wasCommitted():检查事务是否提交

try{

    .....逻辑代码

      transaction.commit();

}catch(Exception e){

    transaction.rollback();

}

7.5. Query 和 Criteria 接口

Query 和 Criteria 接口是 Hibernate的查询接口,用于向数据库查询对象以及控

制执行查询的过程。Query 实例包装了一个 HQL(Hibernate Query Language)查询语句,HQL 查询语句与 SQL 查询语句有些相似,但HQL 查询语句是面向对象的,它引用类名及类的属性名,而不是表名及表的字段名。

Critieria 接口完全封装了基于字符串形式的查询语句,比Query 接口更加面向对

象,Criteria 接口擅长于执行动态查询

 

8.     Hibernate中的持久化类

8.1. 什么是持久化类

实体类和数据库建立的映射就叫做持久化类(实体类+映射文件)

8.2. 编写规范

1.     提供一个公共的无参数的构造方法:反射机制

2.     提供一个唯一标识,映射数据表主键字段

  Java区分两个对象是否是同一个使用地址,数据库区分两条数据是否一致使用主键

  Hibernate的区分持久化对象是否是同一个,根据唯一标识(OID)

3.        所有属性提供public访问控制符的 set  get 方法

4.        标识属性应尽量使用基本数据类型的包装类型

 userAge  0   

 userAge  null  0

5.        持久化类尽量不要使用final进行修饰

        不能被继承

6.实现可序列化接口(Serializable)

 

8.3. 持久化对象的唯一标识 OID

java按地址区分同一个类的不同对象.关系数据库用主键区分同一条记录

Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系

对象的OID和数据库的表的主键对应。为保证OID的唯一性,应该让Hibernate来为OID付值

9.     持久化类的三种状态

瞬时态 transient    :(临时态)

持久态 persistent  :

游离态 detached   :(离线态)

 

OID Session

 

9.1. 三种状态介绍

9.1.1.  Transient瞬时态(临时态):

特点:持久化对象没有唯一标识OID.没有纳入Session的管理.

9.1.2.  Persistent持久态:

特点:持久化对象有唯一标识OID.已经纳入到Session的管理.

***** 结论:持久化持久态对象有自动更新数据库的能力.

9.1.3.  Detached游离态:

特点:持久化对象有唯一标识OID,没有纳入到Session管理.

 

9.2. 三种状态的转换

瞬时态--->持久态save/saveOrUpdate

持久态--->游离态 evict(Object objet)/clear()/close();

游离态--->瞬时态   delete

持久态--->瞬时态   delete

9.3. 持久态对象有自动更新数据库的能力

自动更新数据库的能力依赖了Hibernate的一级缓存.

 

    //测试:10.3.持久态对象有自动更新数据库的能力

    @Test

    publicvoid test02(){

        Session session = HibernateUtil.getSession();

        Transaction transaction = session.beginTransaction();

         User user = (User)session.get(User.class,1);

         user.setUsername("asdfghjkl");

       //session.update(arg0);

         transaction.commit();

    }

 

10.Hibernate的一级缓存

10.1.  什么是缓存

缓存将数据库/硬盘上文件中数据,放入到缓存中(就是内存中一块空间).当再次使用的使用,可以直接从内存中获取.

10.2.  缓存的作用

提升程序运行的效率.缓存技术是Hibernate的一个优化的手段.

10.3.  Hibernate的缓存分类

一级缓存:Session级别的缓存.一级缓存与session的生命周期一致.自带的.不可卸载.

二级缓存:SessionFactory级别的缓存.不是自带的.

在 Session 接口的实现中包含一系列的 Java 集合, 这些 Java 集合构成了 Session 缓存. 只要 Session 实例没有结束生命周期, 存放在它缓存中的对象也不会结束生命周期.

10.4.  管理hibernate的一级缓存

一级缓存是与session的生命周期相关的.session生命周期结束,一级缓存销毁了.

 clear()/evict()/flush()/refresh()管理一级缓存.

* clear()                      :清空一级缓存中所有的对象.

* evict(Objectobj)   :清空一级缓存中某个对象.

* flush()                      :刷出缓存.

* refresh(Objectobj):将快照区的数据重新覆盖了一级缓存的数据.

 

11.Hibernate关联关系的映射

业务表与表之间的关系:

一对一,一对多,多对多

一对一例子:人和身份证,小公司和地址: 

公司表

指向地址表的外键

地址表

一对多:一个老师对应多个学生,一个部门对多个员工

   部门表

   员工表

      指向部门表的外键

多对多:项目与学生,学生与课程

学生

课程

中间表

11.1.  实体之间的关系

一对一,一对多,多对多

一对一的例子:一人一证

一对多的例子:一个老师对个多个学生,一个部门有多个员工

     在’多表’中使用’一表’的主键作为外键

多对多例子:老师与学生

     使用中间表建立联系

 

11.2.  Hibernate中一对多的配置

部门与员工

在一的一方配置添加多方的集合对象

 

1.     在一的实体类中添加多个的一方的集合属性

在一的一方的映射文件中配置如下代码

  <!-- 配置一对多关系 -->

       <!-- 使用set配置一对多关系

         name:为当前多的一方的属性名

         <key> 中的column:配置的关联的外键

         <one-to-many> class:配置是多的一方的类的全限定名

        -->

       <set name="emps">

          <!-- 配置外键 -->

          <key column="dno"></key>

          <one-to-many class="com.ys.entity.Emp"/>

       </set>

测试插入:如果插入数据时需要建立数据表中联系,必须给对应的实体建立关系

//建立一对多关系

         //一个部门对应多个员工

         //没有建立对应的关系时,插入的数据无关联

         @Test

         public void test02(){

                   Session session = HibernateUtil.getSession();

                   Transaction transaction = session.beginTransaction();

                  

                   Dept dept = new Dept();

             dept.setDname("开发部");

            

             Emp emp = new Emp();

             emp.setEname("张三");

            

             //建立部门与员工的关系

             dept.getEmps().add(emp);

            

             session.save(dept);

             session.save(emp);

             transaction.commit();

         }

 

11.3.  Hiberate中的多对一的配置

在多的一方添加对一的关联

配置<many-to-one>

 

在多的一方的实体类中建立与一的一方的关系

 

在映射文件中配置

 <!-- 配置多对一 -->

         <!--

           name:属性名

           class:关联类的全限定名

           column:外键关联字段

          -->

  <many-to-one name="dept" class="com.ys.entity.Dept" column="dno"></many-to-one>

 

 

11.4.  级联操作

当建立的双方关系是,操作某一方同时触发另外一方的操作

级联保存:cascade="save-update"

在<set>标签或者<many-to-one>中配置cascade属性

 <set name="emps" cascade="save-update">

 <many-to-one name="dept" class="com.ys.entity.Dept" column="dno" cascade="save-update"></many-to-one>

 

需要执行保存A就保存B,则在A上添加级联

 

级联删除:cascade="delete"

 

truncate和delete的区别

  1.truncate是数据定义语言(DDL),delete是数据操作语言(DML)

  2.truncate的效率高

11.4.1.          cascade的属性

none                            :不使用级联

save-update             :保存或更新的时候级联

delete                         :删除的时候级联

all                                 :除了孤儿删除以外的所有级联.

delete-orphan :孤儿删除(孤子删除).

* 仅限于一对多.只有一对多时候,才有父子存在.认为一的一方是父亲,多的一方是子方.

* 当一个客户与某个订单解除了关系.将外键置为null.订单没有了所属客户,相当于一个孩子没有了父亲.将这种记录就删除了.

all-delete-orphan     :包含了孤儿删除的所有的级联.

11.5.  双向维护产生多余的SQL

配置inverse=”true”:在那一端配置.那么那一端放弃了外键的维护权.

* 一般情况下,在一的一方去放弃.

 

    <!-- 映射文件中配置一个部门中有多个员工 -->

       <list name="empList" cascade="all" inverse="true">

           <key column="dno"></key>

           <index></index>

           <one-to-many  class="com.ys.entity.Emp"/>

       </list>

 //双向数据维护产生多余的SQL

    @Test

    publicvoid test07(){

        Session session = HibernateUtil.getSession();

        Transaction transaction = session.beginTransaction();

       

        //员工3掉到部门1

        Emp emp03 = (Emp)session.get(Emp.class, 3);

        Dept dept = (Dept) session.get(Dept.class, 1);

       

        //建立双向联系

        //持久化对象建立双向联系之后,都有维护外键的能力,产生多余的SQL

        //解决办法:其中一方放弃维护外键的内容(一的一方放弃维护外键能力)

        //inverse="true"

       

        emp03.setDept(dept);

        dept.getEmpList().add(emp03);

       

        transaction.commit();

    }

   

 

 

cascade:操作关联对象.

inverse:控制外键的维护.。

11.6.  Hibernate中多对多的配置

<many-to-many></many-to-many>

Student:

映射文件中多对多的配置: 

<set name="teachers" table="tb_st">

          <key column="sno"></key>

          <many-to-many class="Teacher" column="tno"></many-to-many>

     </set>

 

Teacher:

映射文件中多对多的配置:

 <!-- 配置多对多 -->

       <!--

              name:实体类映射的属性名

              table:中间表

        -->

       <set name="students" table="tb_st" inverse="true">

         <!-- 当前类在中间表的外键字段名 -->

          <key column="tno"></key>

          <!--

            class:关联的类的全限定名

            column:关联表在中间表的外键字段名

           -->

          <many-to-many class="Student" column="sno"></many-to-many>

       </set>

      

 

问题:

//建立老师与学生的双向联系

    /*会出现的问题:

     * 双方都具有维护中间表的能力,导致在插入中间表时,主键重复。导致数据无法插入

     * 解决办法:让其中一方放弃对中间表的维护

    */

    @Test

    publicvoid test03(){

        Session session = HibernateUtil.getSession();

        Transaction transaction = session.beginTransaction();

        //新增一个老师

        Teacher teacher01 = new Teacher();

        teacher01.setTname("老师1");

        Teacher teacher02 = new Teacher();

        teacher02.setTname("老师2");

        //新增两个学生

        Student stu01 = new Student();

        stu01.setSname("学生1");

        Student stu02 = new Student();

        stu02.setSname("学生2");

       

        //建立老师--->学生

        teacher01.getStudents().add(stu01);

        teacher01.getStudents().add(stu02);

        teacher02.getStudents().add(stu01);

        teacher02.getStudents().add(stu02);

        //学生--->老师

        stu01.getTeachers().add(teacher01);

        stu01.getTeachers().add(teacher02);

        stu02.getTeachers().add(teacher01);

        stu02.getTeachers().add(teacher02);

       

        session.save(teacher01);

        session.save(teacher02);

        session.save(stu01);

        session.save(stu02);

       

        transaction.commit();

    }

 

12.hibernate与spring的整合

12.1.  导入jar包

hibernate开发必须的包

 

数据库驱动包

mysql-connector-java-5.1.18-bin.jar

数据源c3p0的包

spring的核心包

spring-core

spring-beans

spring-context

spring-aop

spring-expression

spring-tx

spring-jdbc

spring整合hibernate的包

spring-orm

12.2.  编写hibernate与spring整合的配置文件

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:tx="http://www.springframework.org/schema/tx"

    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd

        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

  

   <!-- 引入外部属性文件 -->

   <context:property-placeholder location="classpath:database.properties"/>

  

   <!-- 配置扫描包 -->

   <context:component-scan base-package="com.ys.dao"></context:component-scan>

   <context:component-scan base-package="com.ys.service"></context:component-scan>

  

  <!-- 配置数据源 -->

  <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">

     <!-- 连接数据库的四个基本参数 -->

     <property name="driverClass" value="${jdbc.driver}"></property>

     <property name="jdbcUrl" value="${jdbc.url}"></property>

     <property name="user" value="${jdbc.username}"></property>

     <property name="password" value="${jdbc.password}"></property>

  </bean>

 

  <!-- 配置SessionFactory

    使用spring.orm 中的LocalSessionFactoryBean来管理SessionFactory

   -->

  <bean id="sessionFactoty" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

     <!-- 配置数据源 -->

     <property name="dataSource" ref="dataSource"></property>

     <!-- 配置hibernate核心配置文件 -->

     <property name="configLocations" value="classpath:hibernate.cfg.xml"></property>

     <!-- 配置映射文件 -->

     <property name="mappingLocations" value="classpath:com/ys/entity/hbm/*.hbm.xml"></property>

  </bean>

 

  <!-- 配置事务管理器

       spring-orm :HibernateTransactionManager

     配置事务管理器时:sessionFactory是必须的

   -->

  <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">

     <!-- 配置SessionFactory -->

     <property name="sessionFactory" ref="sessionFactoty"></property>

  </bean>

 

  <!-- 配置注解的事务 -->

  <tx:annotation-driven/>

 

</beans>

 

 

 

spring负责管理SessionFactory

 

12.3.  测试

//hibernatespring整合

    @Test

    publicvoid test01(){

        //加载spring的配置文件

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-hibernate.xml");

        //获取到UserService

        UserService userService = applicationContext.getBean(UserService.class);

       

        User user = userService.findById(1);

        System.out.println(user);

    }

 

 

 

13.Hibernate检索方式

导航对象图检索方式:  根据已经加载的对象导航到其他对象

Dept dept = (Dept)session.get(Dept.class,1);

Set<Emp> emps = dept.getEmps();

OID 检索方式:  按照对象的 OID 来检索对象(get()/load())

HQL 检索方式: 使用面向对象的 HQL 查询语言

QBC 检索方式: 使用 QBC(QueryBy Criteria) API 来检索对象. 这种 API 封装了基于字符串形式的查询语句, 提供了更加面向对象的查询接口.

本地 SQL 检索方式: 使用本地数据库的 SQL 查询语句

 

13.1.  HQL

13.1.1.          什么是HQL(hibernate query language)

面向对象的查询语言, 它和 SQL 查询语言有些相似. 在 Hibernate 提供的各种检索方式中, HQL 是使用最广的一种检索方式。

 

13.1.2.          HQL的作用

在查询语句中设定各种查询条件

支持投影查询, 即仅检索出对象的部分属性

支持分页查询,支持连接查询

支持分组查询, 允许使用 HAVING 和 GROUP BY 关键字

提供内置聚集函数, 如 sum(), min() 和 max()

能够调用用户定义的 SQL 函数或标准的 SQL 函数 concat()

支持子查询,支持动态绑定参数

 

13.1.3.          HQL与SQL的区别

1.HQL 查询语句是面向对象的, Hibernate负责解析 HQL 查询语句, 然后根据对象-关系映射文件中的映射信息(hbm的映射文件), 把 HQL 查询语句翻译成相应的 SQL 语句. HQL 查询语句中的主体是域模型中的类及类的属性

2.SQL 查询语句是与关系数据库绑定在一起的.SQL 查询语句中的主体是数据库表及表的字段.

13.1.4.          HQL的使用

1.     查询所有记录

    from User;

2.     查询使用别名

   from User [as] u;

3.     排序

   from User order by id [asc/desc];

4.     分页查询   limit 1,2

     setFirstResult()  --设置起始下标(从0开始) (pageIndex-1)*pageSize

     setMaxResults()  --设置每页显示数据的最大数量(pageSize)

5.     单个对象查询

       uniqueResult()--确定返回的结果为一条数据或者返回结果为空时使用。

   返回集合类型

       query.list();  query.iterator();

6.     参数绑定

 6.1.问号绑定

          ?赋值下标从0开始

          参数类型不确定时使用setParameter();设置对应的参数

 6.2.使用名称的方式绑定

     =:name    setParameter(“name”,”参数”);

     setEntity();//设置实体作为查询条件

     setProperties();//参数用名字绑定,可以把参数封装成实体类

7.        模糊查询

    hql: from User where username like :name;

    setParameter(“name”,”%值%”);

        hql: from User where username likeconcat(‘%’,?,’%’);

    setParameter(“name”,”值”);

 

8.        投影操作

   查询持久化类中的部分属性

   1.返回单列数据    List<Object>

   2.返回多列数据    List<Object[]>

   3.返回具体的对象  List<User>

select new User(userName,userPwd) from User

     注意:User必须有具体的构造方法才行

13.2.  HQL的其他使用

13.2.1.          连接查询

内连接

隐式内连接

*迫切内连接

左外连接

*迫切左外连接

右外连接

 

内连接与迫切内连接的区别:

 fecth

 1.查询两个表的交集部分

  2.内连接返回的为数组类型,迫切内连接返回的是具体的对象

13.2.2.          聚合函数

count(),sum(),min(),max(),avg()

    //使用聚合函数(返回的类型是Long类型)

    @Test

    publicvoid test(){

       Session session = HibernateUtil.getSession();

       String hql = "select count(*) from User";

       Query query = session.createQuery(hql);

       Long count = (Long) query.uniqueResult();

       System.out.println(count);

    }

   

    //获取年龄的平均值(返回的类型是Double)

    @Test

    publicvoid test02(){

       Session session = HibernateUtil.getSession();

       String hql = "select avg(age) from User";

       Query query = session.createQuery(hql);

       Double age = (Double) query.uniqueResult();

       System.out.println(age);

    }

   

 

 

13.2.3.          分组查询

  select ...  from 实体where...  group by .. having...orderby....

//获取到部门的平均工资

         @Test

         public void test02(){

                   Session session = HibernateUtil.getSession();

                   String hql = "select avg(sal) from Emp group by deptno";

                   Query query = session.createQuery(hql);

                   List<Double> list = query.list();

                   System.out.println(list);

         }

        

 

13.2.4.          子查询

--查询大于平均工资的员工信息

SQL:select * from tb_emp where emp_sal>(select avg(emp_sal) from tb_emp);

HQL:from Emp where sal>(select avg(sal) from Emp)

//查询大于平均工资的员工信息

                   @Test

                   public void test03(){

                            Session session = HibernateUtil.getSession();

                            String hql = "from Emp where sal>(select avg(sal) from Emp)";

                            Query query = session.createQuery(hql);

                            List list = query.list();

                            System.out.println(list);

                   }

        

 

子查询关键字

all    子查询语句返回的所有记录

any   子查询语句返回的任意记录

some  与”any”意义相同

in     与”=any”意义相同

exists  子查询语句至少返回一条记录

 

 

 

13.3.  Criteria

13.3.1.          什么是Criteria

使用 QBC(Query By Criteria) API 来检索对象. 这种 API 封装了基于字符串形式的查询语句, 提供了更加面向对象的查询接口.

 

13.3.2.          Criteria的使用

 

查询所有

排序

分页

获取单个对象

模糊查询

 

13.4.  HQL和QBC支持的各种运算

 

 

14.hibernate的检索策略和抓取策略

14.1.  检索策略

立即检索与延迟检索

立即检索:当执行某行代码的时候,马上发出SQL语句进行查询.get()

延迟检索:当执行某行代码的时候,不会马上发出SQL语句进行查询.当真正使用这个对象的时候才会发送SQL语句.load()

 

14.2.  抓取策略

连接抓取(使用外连接)

查询抓取(单表查询)

子查询抓取(单表查询)

批量抓取(使用外键批量获取关联表的数据)

 

14.3.  类级别检索和关联级别检索

14.3.1.          类级别的检索

<class>标签上配置lazy

如果程序加载一个对象的目的是为了访问它的属性, 可以采取立即检索. 如果程序加载一个持久化对象的目的是仅仅为了获得它的引用, 可以采用延迟检索

 

1.无论 <class> 元素的 lazy 属性是 true 还是 false,Session 的 get() 方法及 Query 的 list() 方法在类级别总是使用立即检索策略

2.若 <class> 元素的 lazy 属性为 true 或取默认值,Session 的 load() 方法不会执行查询数据表的 SELECT 语句, 仅返回代理类对象的实例, 该代理类实例有如下特征:

由 Hibernate 在运行时采用 javassist 工具动态生成Hibernate 创建代理类实例时, 仅初始化其 OID 属性在应用程序第一次访问代理类实例的非 OID 属性时, Hibernate 会初始化代理类实例

 

14.3.2.          关联级别的检索

<set>/<many-to-one>上面的lazy和fetch

1.在映射文件中, 用 <set>元素来配置一对多关联及多对多关联关系. <set> 元素有 lazy 和 fetch 属性

2.lazy: 主要决定 orders 集合被初始化的时机. 即到底是在加载Customer 对象时就被初始化, 还是在程序访问 orders 集合时被初始化

3.fetch: 取值为 “select” 或 “subselect” 时, 决定初始化 orders 的查询语句的形式;  若取值为”join”, 则决定 orders 集合被初始化的时机

若把 fetch 设置为“join”, lazy 属性将被忽略

 

一对多和多对多关联的检索策略(set): <set> 元素的 lazy 和 fetch 属性

 

<many-to-one> 元素也有一个 lazy 属性和 fetch 属性

 

14.4.  三种检索策略的比较

 

检索策略

优点

缺点

优先考虑使用的场合

立即检索

对应用程序完全透明,不管对象处于持久化状态还是游离状态,应用程序都可以从一个对象导航到关联的对象

(1)select语句多

(2)可能会加载应用程序不需要访问的对象,浪费许多内存空间。

(1)类级别

(2)应用程序需要立即访问的对象

(3)使用了二级缓存

延迟检索

由应用程序决定需要加载哪些对象,可以避免执行多余的select语句,以及避免加载应用程序不需要访问的对象。因此能提高检索性能,并节省内存空间。

应用程序如果希望访问游离状态的代理类实例,必须保证她在持久化状态时已经被初始化。

(1)一对多或者多对多关联

(2)应用程序不需要立即访问或者根本不会访问的对象

迫切左外连接检索

(1)对应用程序完全透明,不管对象处于持久化状态还是游离状态,都可从一个对象导航到另一个对象。

(2)使用了外连接,select语句少

(1)可能会加载应用程序不需要访问的对象,浪费内存。

(2)复杂的数据库表连接也会影响检索性能。

(1)多对一或一对一关联

(2)需要立即访问的对象

(3)数据库有良好的表连接性能。

15.二级缓存

15.1.  Hibernate中提供了两个级别的缓存

1.  第一级别的缓存是Session 级别的缓存,它是属于事务范围的缓存。这一级别的缓存由 hibernate 管理的,一般情况下无需进行干预

     管理一级缓存:

        clear/evict/flush/close

2.第二级别的缓存是 SessionFactory级别的缓存,它是属于进程范围的缓存

 

15.2.  sessionFactory的缓存可以分为两类

内置缓存: Hibernate 自带的, 不可卸载. 通常在 Hibernate 的初始化阶段, Hibernate 会把映射元数据和预定义的 SQL 语句放到 SessionFactory 的缓存中, 映射元数据是映射文件中数据的复制, 而预定义 SQL 语句时 Hibernate 根据映射元数据推到出来的. 该内置缓存是只读的.

外置缓存(二级缓存): 一个可配置的缓存插件. 在默认情况下,SessionFactory 不会启用这个缓存插件. 外置缓存中的数据是数据库数据的复制, 外置缓存的物理介质可以是内存或硬盘.

 

15.3.  二级缓存并发访问策略

 

transactional(事务型)

仅在受管理的环境中适用

提供Repeatable Read事务隔离级别适用经常被读,很少修改的数据可以防止脏读和不可重复读的并发问题缓存支持事务,发生异常的时候,缓存也能够回滚

 

read-write(读写型)

提供Read Committed事务隔离级别

在非集群的环境中适用适用经常被读,很少修改的数据可以防止脏读更新缓存的时候会锁定缓存中的数据

 

nonstrict-read-write

(非严格读写型)

适用极少被修改,偶尔允许脏读的数据(两个事务同时修改数据的情况很少见)

不保证缓存和数据库中数据的一致性为缓存数据设置很短的过期时间,从而尽量避免脏读不锁定缓存中的数据

 

read-only

(只读型)

 

适用从来不会被修改的数据(如参考数据)

在此模式下,如果对数据进行更新操作,会有异常事务隔离级别低,并发性能高在集群环境中也能完美运作

 

15.4.  二级缓存使用时机

1.适合放入二级缓存中的数据:

很少被修改

不是很重要的数据, 允许出现偶尔的并发问题

2.不适合放入二级缓存中的数据:

经常被修改

财务数据, 绝对不允许出现并发问题

与其他应用数据共享的数据

15.5.  缓存提供的供应商

hibernate 的二级缓存是进程或集群范围内的缓存, 缓存中存放的是对象的散装数据

二级缓存是可配置的的插件, Hibernate 允许选用以下类型的缓存插件:

EHCache: 可作为进程范围内的缓存, 存放数据的物理介质可以是内存或硬盘, 对 Hibernate 的查询缓存提供了支持

OpenSymphony `:可作为进程范围内的缓存, 存放数据的物理介质可以是内存或硬盘, 提供了丰富的缓存数据过期策略, 对 Hibernate 的查询缓存提供了支持

SwarmCache: 可作为集群范围内的缓存, 但不支持Hibernate 的查询缓存

JBossCache:可作为集群范围内的缓存, 支持 Hibernate 的查询缓存

 

15.6.  配置ehcache缓存

1.     导入jar包

ehcache-2.10.0.jar

2.在hibernate的核心配置文件中配置

2,.1开启二级缓存

 <propertyname="hibernate.cache.use_second_level_cache">true</property>

2.2指定缓存的提供商

<propertyname="hibernate.cache.provider_class">

             org.hibernate.cache.EhCacheProvider</property>

2.        指定使用二级缓存的类

  4.1、在使用类的*.hbm.xml配置

选择需要使用二级缓存的持久化类, 设置它的二级缓存的并发访问策略, <class> 元素的 cache 子元素表明 Hibernate 会缓存对象的简单属性, 但不会缓存集合属性, 若希望缓存集合属性中的元素, 必须在 <set> 元素中加入 <cache> 子元素

4.2、在hibernate.cfg.xml文件中配置(建议)

<!-- 指定使用二级缓存的类 放在mapping下面 -->

      <!-- 配置类级别的二级缓存 -->

      <class-cache class="com.ys.entity.User" usage="read-write"/>

      <class-cache class="类" usage="read-write"/>

       <!-- 配置集合级别的二级缓存 -->

       <collection-cache  collection="com.ys.entity.User.courses" usage="read-write"/>

 

3.        配置ehcache默认的配置文件ehcache.xml(名字固定)(放在类路径下)

<?xml version="1.0" encoding="UTF-8"?>

<ehcache>

<diskStore path="D:\cache" />

 <defaultCache

            maxElementsInMemory="10000"

            eternal="false"

            timeToIdleSeconds="120"

            timeToLiveSeconds="120"

            overflowToDisk="true"

            maxElementsOnDisk="10000000"

            diskPersistent="false"

            diskExpiryThreadIntervalSeconds="120"

            memoryStoreEvictionPolicy="LRU"

            />

</ehcache>

 

16.hibernate注解

配置持久化类

 

配置关联关系

 

 

配置实体类

package com.ys.entity;

 

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

import javax.persistence.Table;

import javax.persistence.Transient;

 

 

 

 

@Entity//声明为持久化类

@Table(name="tb_annotaion_user")

public class User {

        

         /**

          * AUTO  -----> native

          * IDENTITY  ----->主键自增长

          * SEQUENCE----->使用序列

          *

          */

         @Id//声明为唯一标识

         @GeneratedValue(strategy=GenerationType.IDENTITY)//主键的生成策略(数据库自增长的策略)

         //属性与字段对应

         @Column(name="user_id")

         private Integer id;

        

         @Column(name="user_name")

         private String username;

        

         @Column(name="user_pwd")

         private String password;

        

         @Transient//忽略该字段

         private Integer age;

        

        

         public Integer getId() {

                   return id;

         }

         public void setId(Integer id) {

                   this.id = id;

         }

         public String getUsername() {

                   return username;

         }

         public void setUsername(String username) {

                   this.username = username;

         }

         public String getPassword() {

                   return password;

         }

         public void setPassword(String password) {

                   this.password = password;

         }

         public Integer getAge() {

                   return age;

         }

         public void setAge(Integer age) {

                   this.age = age;

         }

}

 

引入映射类(在hibernate.cfg.xml):

       <!-- 配置映射文件 -->

       <mapping  class="com.ys.entity.User"/>

 

 

 

 

考试题目分析:

多对一以及一对多关系配置时,column属性配置的是多表的外键

多对多关系配置时,<key>中的column属性配置的是当前映射文件对应表主键在中间表的外键是什么

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值