Hibernate(5)session的方法

 1. Session缓存  Session缓存(Hibernate一级缓存),在 Session 接口的实现中包含一系列的 Java 集合, 这些 Java 集合构成了 Session 缓存。只要 Session 实例没有结束生命周期, 且没有清理缓存,则存放在它缓存中的对象也不会结束生命周期。
Session 缓存可减少 Hibernate 应用程序访问数据库的频率。
两次获取同一个对象:
 ①第一次获取Users对象时会去数据库中查找,找到之后把Users对象的引用赋给user引用变量,同时还会把Users对象的引用给到Session缓存中,
 ②若再次查找同一个Users变量,首先会去Session中找有没有,若缓存中有就不去查询数据库,直接从缓存中获取
    /**
     * Session缓存(Hibernate一级缓存),在 Session 接口的实现中包含一系列的 Java 集合, 
     *这些 Java 集合构成了 Session 缓存。
     *只要 Session 实例没有结束生命周期, 且没有清理缓存,则存放在它缓存中的对象也不会结束生命周期
     *Session 缓存可减少 Hibernate 应用程序访问数据库的频率。
     * 两次获取同一个对象:
     * ①第一次获取Users对象时会去数据库中查找,找到之后把Users对象的引用赋给user引用变量,
     *  同时还会把Users对象的引用给到Session缓存中,
     * ②若再次查找同一个Users变量,首先会去Session中找有没有,若缓存中有就不去查询数据库,直接从缓存中获取
     */
    @Test
    public void testSessionCache(){
        Users user = (Users) session.get(Users.class, 8);
        System.out.println(user);

        Users user2 = (Users) session.get(Users.class, 8);
        System.out.println(user2);

    }
2. flush方法:使数据表中的记录和Session缓存中的对象的状态保持一致,为保持一致,则可能会发送对应的SQL语句
 * 提下情况会调用该方法:
 *  1.在Transaction的commit方法中,先调用session的Flush方法,在提交事务
 *  2.显式的调用flush()方法可能会发送SQL语句,但不会提交事务
 *  3.注意:在未提交事务或显式的调用session.flush()方法之前,也有可能进行flush()操作。
 *   ①.执行HQL或QBC查询,会先进行flush()操作,以得到数据表的最新的记录
 *   ②.若记录的ID是由底层数据库使用自增的方式生成的则在调用save()方法后,就会立即发送INSERT语句,因为save方法后
 * 必须保证对象的ID是存在的
/**
     * flush方法:使数据表中的记录和Session缓存中的对象的状态保持一致,为保持一致,则可能会发送对应的SQL语句
     *提下情况会调用该方法:
     *  1.在Transaction的commit方法中,先调用session的Flush方法,在提交事务
     *  2.显式的调用flush()方法可能会发送SQL语句,但不会提交事务
     *  3.注意:在未提交事务或显式的调用session.flush()方法之前,也有可能进行flush()操作。
     *   ①.执行HQL或QBC查询,会先进行flush()操作,以得到数据表的最新的记录
     *   ②.若记录的ID是由底层数据库使用自增的方式生成的则在调用save()方法后,就会立即发送INSERT语句,因为save方法后
     *必须保证对象的ID是存在的
     */
    @Test
    public void testSessionFlush(){
        Users users = (Users) session.get(Users.class, 8);
        users.setLoginName("Jack");

        //session.flush();
        //System.out.println("flush()");

        //HQL查询
        Users user2 = (Users) session.createCriteria(Users.class).uniqueResult();
        System.out.println(user2);
    }
    //使用save()方法,会立即执行SQL语句,而不用等到事务提交,其他方法需要等到事务提交之后到能执行SQL语句
    @Test
    public void testSessionFlush2(){
        Users user = new Users("mengqi", "123", "孟奇", "河南省郑州市", "19843244908", "163@.com", new Date());
        session.save(user);
    }
 3. reflush():获取数据表中最新的记录,该方法会强制执行查询,
 * 手动修改表中的记录,使用reflush(),再次打印user时,打印的记录就会和之前打印的不一致,此时打印的是手动修改后的记录,即最新是记录,若打印的不是最新的则是MYSQL数据库的隔离级别问题,MYSQL默认的隔离级别为REPEATABLE READ(可重复读),需要改成READ COMMITED(读已提交)。
 * 在Hibernate的配置文件中,可以显示的设置隔离级别,每一个隔离级别都对应一个数字
 * 1对应READ UNCOMMITED
 * 2对应READ COMMITED
 * 4对应REPEATABLE READ
 * 8对应SERIALIZEABLE
 *Hibernate通过Hibernate配置文件指定,Hibernate.connection.isolation属性设置事务的隔离级别
    /**
     * reflush():获取数据表中最新的记录,该方法会强制执行查询,
     * 手动修改表中的记录,使用reflush(),再次打印user时,打印的记录就会和之前打印的不一致,此时打印
     * 的是手动修改后的记录,即最新是记录,若打印的不是最新的则是MYSQL数据库的隔离级别问题,
     * MYSQL默认的隔离级别为REPEATABLE READ(可重复读),需要改成READ COMMITED(读已提交)
     * 在Hibernate的配置文件中,可以显示的设置隔离级别,每一个隔离级别都对应一个数字
     * 1对应READ UNCOMMITED
     * 2对应READ COMMITED
     * 4对应REPEATABLE READ
     * 8对应SERIALIZEABLE
     *Hibernate通过Hibernate配置文件指定,Hibernate.connection.isolation属性设置事务的隔离级别
     */
    @Test
    public void testReFlush(){
        Users user = (Users) session.get(Users.class, 8);
        System.out.println(user);

        //在此打印断点,打印出的user与上一个打印的user没有什么不同
        System.out.println(user);

        //此时手动修改了表中的记录,使用reflush(),再次打印user时,打印的记录就会和之前打印的不一致,此时打印
        //的是手动修改后的记录,即最新是记录,若打印的不是最新的则是MYSQL数据库的隔离级别问题,
        //MYSQL默认的隔离级别为REPEATABLE READ(可重复读),需要改成
        session.refresh(user);
        System.out.println(user);
    }
 4. claer():清理缓存,两次查询同一条记录,中间使用clear()清理之后,第二条查询也会发送一条记录
    /**
     * claer():清理缓存,两次查询同一条记录,中间使用clear()清理之后,第二条查询也会发送一条记录
     */
    @Test
    public void testClear(){
        Users users = (Users) session.get(Users.class, 8);
        session.clear();
        Users users2 = (Users) session.get(Users.class, 8);
    }
 5. save()   
 *  ①把对象加入到Session缓存中,使一个临时对象变为持久化对象
 *  ②选用映射文件指定的标识符生成器,为对象分配ID
 *  ③在flush()缓存时会发送一条INSERT语句
 *  ④在save()方法之前设置ID属性值是无效的,但不抛出异常
 *  ⑤持久化对象的ID是不能被修改的
    /**
     * save():
     *  ①把对象加入到Session缓存中,使一个临时对象变为持久化对象
     *  ②选用映射文件指定的标识符生成器,为对象分配ID
     *  ③在flush()缓存时会发送一条INSERT语句
     *  ④在save()方法之前设置ID属性值是无效的,但不抛出异常
     *  ⑤持久化对象的ID是不能被修改的
     */
    @Test
    public void testSave(){
        Users user = new Users("wangqiang", "123", "王强", "河南省", "18292389876", "163@qq.com", new Date());
        //save()方法前后的对象区别在于save()之后会给对象分配ID
        System.out.println("user:"+user);
        session.save(user);
        System.out.println("user:"+user);

        //在save()方法前修改ID是无效的
        Users user2 = new Users("wangqiang", "1234", "王强", "河南省", "18292389876", "163@qq.com", new Date());
        user2.setId(100);
        session.save(user2);
        System.out.println("user2:"+user2);//为id赋值失败
        user2.setId(100);
    }
 6. Persist():也会执行INSERT操作,作用与save()一致
与save的主要内容区别:
persist把一个瞬态的实例持久化,但是并"不保证"标识符(identifier主键对应的属性)被立刻填入到持久化实例中,标识符的填入可能被推迟到flush的时候。
save, 把一个瞬态的实例持久化标识符,及时的产生,它要返回标识符,所以它会立即执行Sql insert
    /**
     * Persist():也会执行INSERT操作,作用与save()一致,与save的主要内容区别:
    persist把一个瞬态的实例持久化,但是并"不保证"标识符(identifier主键对应的属性)被立刻填入到持久化实例中,标识符的填入可能被推迟到flush的时候。
    save, 把一个瞬态的实例持久化标识符,及时的产生,它要返回标识符,所以它会立即执行Sql insert
     *:
     */
    @Test
    public void testPersist(){
        Users user = new Users("wangwei", "123", "王伟", "河南省", "19483928495", "163@qq.com", new Date());
        user.setId(100);
        session.persist(user);
    }
 7. GET()和Load()的区别
 * 1.get方法会立即加载该对象,立即执行查询
 *   load方法,若不使用该对象,则不会立即加载,而返回一个代理对象,不会立即执行查询操作
 * 2.若数据表中没有对应的记录get返回null,load会抛出异常
 * 3.load方法可能会抛出懒加载异常,因为load方法是在使用对象的时候再执行查询操作,
 * 假如在使用对象之前把session关闭,即需要初始化代理对象之前已经关闭了Session,同时又在使用加载的对象,
 * 就会出现懒加载异常,若不使用加载的对象,则没有问题
 * get在使用对象之前关闭session则没有问题。
     * GET()和Load()的区别
     * 1.get方法会立即加载该对象,立即执行查询
     *   load方法,若不使用该对象,则不会立即加载,而返回一个代理对象,不会立即执行查询操作
     * 2.若数据表中没有对应的记录get返回nullload会抛出异常
     * 3.load方法可能会抛出懒加载异常,因为load方法是在使用对象的时候再执行查询操作,
     * 假如在使用对象之前把session关闭,即需要初始化代理对象之前已经关闭了Session,同时又在使用加载的对象,
     * 就会出现懒加载异常,若不使用加载的对象,则没有问题
     * get在使用对象之前关闭session则没有问题。
     * 
     */
    @Test
    public void testGet(){
        Users user = (Users) session.get(Users.class, 5);
        session.close();
        System.out.println(user);
    }
    @Test
    public void testLoad(){
        Users user = (Users) session.load(Users.class, 5);
        session.close();//使用对象前关闭session,出现懒加载异常org.hibernate.LazyInitializationException,不使用则没有问题
        System.out.println(user);
    }
 8. Update()     
* 1.若更新一个持久化对象,不需要显示的调用update()方法,因为在调用Transaction的commit方法时,会先执行
 *Session的flush()方法
 * 2.更新一个游离对象时,需要显式的调用Session的update方法,可以把一个游离对象变为一个持久化对象
 *注意:
 *  ①.若显式的调用Session的update方法,则无论游离的对象中属性有没有变化,都会发送update语句
 *可以使用Xxx.hbm.xml文件的class节点设置select-before-update=true(默认为false),
 *但通常并不设置此属性
 *  ②.若数据表中没有对应的记录,但还调用了update方法,会抛出异常
 *  ③.当 update() 方法关联一个游离对象时, 如果在 Session 的缓存中已经存在相同 OID 的持久化对象,
 * 会抛出异常
/**
     * Update()
     * 1.若更新一个持久化对象,不需要显示的调用update()方法,因为在调用Transaction的commit方法时,会先执行
     *Session的flush()方法
     * 2.更新一个游离对象时,需要显式的调用Session的update方法,可以把一个游离对象变为一个持久化对象
     *注意:
     *  ①.若显式的调用Session的update方法,则无论游离的对象中属性有没有变化,都会发送update语句
     *可以使用Xxx.hbm.xml文件的class节点设置select-before-update=true(默认为false),
     *但通常并不设置此属性
     *  ②.若数据表中没有对应的记录,但还调用了update方法,会抛出异常
     *  ③.当 update() 方法关联一个游离对象时, 如果在 Session 的缓存中已经存在相同 OID 的持久化对象,
     * 会抛出异常
     */
    @Test
    public void testUpdate(){
        Users user = (Users) session.get(Users.class, 8);
        //1.
        transaction.commit();
        //关闭session,user对象成为游离对象
        session.close();

        //②更改游离对象的id,使update方法更新一个数据库中不存在的记录,结果是抛出异常
        //user.setId(100);

        //虽然又开启了一个Session,但是这个Session与上一个Session并没有联系。
        session = sessionFactory.openSession();
        transaction = session.beginTransaction();

        //③虽然这只是一个简单的查询,但是执行查询会在session缓存中关联ID为8的一个持久化对象,
        //当显式执行下面的update方法时,会把id为8的游离对象也关联到session缓存中,但是Session缓存中不能有
        //两个相同ID的对象
        Users users = (Users) session.get(Users.class, 8);

        user.setLoginName("Nick");
        //2.只有显式的调用session的update方法才能让设置的LoginName属性生效
        session.update(user);
    }
 9. SaveOrUpdate():若是一个临时对象则执行save,游离对象执行update
 * 注意:
 * 1.若OID不为null,但数据表中没有与之对应的记录则会抛出异常,因为虽然OID不为空,也是一个游离对象,
 *但是数据表中没有对应的记录无法执行update语句。
 * 2.了解:OID值等于id的unsaved-value属性值的对象,也被认为是一个游离对象,unsave-value是映射文件中id子节点的属性
    /**
     * SaveOrUpdate():若是一个临时对象则执行save,游离对象执行update
     * 注意:
     * 1.若OID不为null,但数据表中没有与之对应的记录则会抛出异常,因为虽然OID不为空,也是一个游离对象,
     *但是数据表中没有对应的记录无法执行update语句。
     * 2.了解:OID值等于id的unsaved-value属性值的对象,也被认为是一个游离对象,unsave-value是映射文件中id子节点的属性
     */
    @Test
    public void testSaveOrUpdate(){
        //临时对象,调用saveOrUpdate()方法,执行insert语句
        Users user = new Users("wangmei", "123", "王梅", "河南省", "19483928495", "163@qq.com", new Date());
        //设置id为8对应数据库表中存在的记录,调用saveOrUpdate()方法,执行update语句
        user.setId(8);

        //该值等于映射文件中id子节点的unsave-value属性值,所以可以调用saveOrUpdate()方法,执行insert语句
        user.setId(100);
        session.saveOrUpdate(user);
    }
 10. Delete():Session的delete()方法既可以删除一个游离对象,又可以删除一个持久化对象,
 * ①只要OID和数据表中一条记录对应,就会准备执行Delete操作,若OID在数据表中没有对应的记录,则会抛出异常。
 * ②可以通过设置Hibernate配置文件中的一个hibernate.use_identifier_rollback 属性
 *来把持久化对象或游离对象的 OID 设置为 null, 使它们变为临时对象
/**
     * Delete():Session的delete()方法既可以删除一个游离对象,又可以删除一个持久化对象,
     * ①只要OID和数据表中一条记录对应,就会准备执行Delete操作,若OID在数据表中没有对应的记录,则会抛出异常。
     * ②可以通过设置Hibernate配置文件中的一个hibernate.use_identifier_rollback 属性
     *来把持久化对象或游离对象的 OID 设置为 null, 使它们变为临时对象
     */
    @Test
    public void testDelete(){
        //因为数据表中id为8的记录已经被删除了,所以该对象是游离对象 
//      Users user = new Users();
//      user.setId(8);

        //持久化对象也可以删除
        Users user = (Users) session.get(Users.class, 7);

        session.delete(user);

        //执行完delete之后,该对象还是有ID值的,若之后想要对该对象执行saveOrUpdate方法,则会强制发送update语句
        //但是,数据表中已经没有这条记录,就会抛异常
        System.out.println(user);
    }
 11. Evict():从Session中把指定的持久化对象移除
/**
     * Evict():从Session中把指定的持久化对象移除
     * 
     */
    @Test
    public void testEvict(){
        Users user = (Users) session.get(Users.class, 4);
        Users user2 = (Users) session.get(Users.class, 5);

        user.setLoginName("Lucy");
        user2.setLoginName("Jack");

        //虽然更新了两个对象的值,但是由于user对象从session中移除,所以只对user2执行了update
        session.evict(user);
    }
 12.  doWork():调用存储过程,需要获取Connection
/**
     * doWork():调用存储过程,需要获取Connection
     */
    @Test
    public void testDoWork(){
        session.doWork(new Work() {

            @Override
            public void execute(Connection conn) throws SQLException {
                //没有配置C3P0数据源时连接是从数据库中获取的:com.mysql.jdbc.JDBC4Connection@42f92dbc
                //配置C3P0数据源之后从连接池中获取连接:com.mchange.v2.c3p0.impl.NewProxyConnection@66ee2542
                System.out.println(conn);

                //调用存储过程
            }
        });
    }
 13. dynamic-update:class节点的属性不设置的话执行更新操作的话,会更新全部的属性值,设置之后仅更新修改后的属性值
 *好处:减少数据库的操作
    /**
     * dynamic-update:class节点的属性,不设置的话执行更新操作的话,会更新全部的属性值,设置之后仅更新修改后的属性值
     *好处:减少数据库的操作
     */
    @Test
    public void testdynamicUpdate(){
        Users user = (Users) session.get(Users.class, 4);
        user.setLoginPwd("1234");
    }
 14. 主键生成策略:increment主键生成器时会出现并发的问题,连续执行两次该方法,模仿两个线程同时访问同一个数据表
 * 由于是自增,但是是两个线程,所以会造成两个线程的id自增之后,id值重复,无法执行SQL语句
    /**
     * 主键生成策略:increment主键生成器时会出现并发的问题,连续执行两次该方法,模仿两个线程同时访问同一个数据表
     * 由于是自增,但是是两个线程,所以会造成两个线程的id自增之后,id值重复,无法执行SQL语句
     * @throws InterruptedException
     */
    @Test
    public void testIdGenerator() throws InterruptedException{
        Users user = new Users("wangwei", "123", "王伟", "河南省", "19483928495", "163@qq.com", new Date());
        session.save(user);

        //Thread.sleep(5000);
    }
 15.  ①派生属性②Java 时间和日期类型的 Hibernate 映射
/**
     * ①派生属性
     * ②Java 时间和日期类型的 Hibernate 映射
     */
    @Test
    public void testPropertyUpdate(){
        Users user = (Users) session.get(Users.class, 1);
        user.setLoginName("AAA");
        System.out.println(user.getDesc());

        System.out.println(user.getDate().getClass());
    }
 16. 大文件属性映射
    /**
     * 大文件属性映射数据库
     * @throws Exception 
     */
    @Test
    public void testBlob() throws Exception{
        Users user = new Users("wangwei", "123", "王伟", "河南省", "19483928495", "163@qq.com", new Date());
        user.setContent("CONTENT");

        //文件的输入流
        InputStream inputStream = new FileInputStream("1.jpg");
        Blob image = Hibernate.getLobCreator(session).createBlob(inputStream, inputStream.available());
        user.setImage(image);
        session.save(user);

        Users user2 = (Users) session.get(Users.class, 1);
        Blob image2 = user2.getImage();

        //输出流输出文件
        InputStream inputStream2 = image2.getBinaryStream();
        //仅显示文件的大小
        System.out.println("图片大小:" + inputStream2.available());
    }
 17.映射组成关系:即一个没有id的自定义类是另一个自定义类中的属性,那么这个属性可以使用映射组成关系来映射
/**
     * 映射组成关系:即一个没有id的自定义类是另一个自定义类中的属性,那么这个属性可以使用映射组成关系来映射
     */
    @Test
    public void testComponent(){
        Worker worker = new Worker();
        Pay pay = new Pay();
        pay.setMonthlyPay(1000);
        pay.setYearPay(12000);
        pay.setVocationWithPay(5);

        worker.setName("ABC");
        worker.setPay(pay);
        session.save(worker);
    }

以上方法的需要的 实体类
Users.java

package com.test.withXml.entity;

import java.io.Serializable;
import java.sql.Blob;
import java.util.Date;


public class Users implements Serializable {

    private static final long serialVersionUID = 1L;
    private Integer id;
    private String loginName;
    private String loginPwd;
    private String name;
    private String address;
    private String phone;
    private String mail;
    //日期格式
    private Date date;
    //派生的属性
    private String Desc;
    //大文本属性
    private String content;
    //二进制文件
    private Blob image;

    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public Blob getImage() {
        return image;
    }
    public void setImage(Blob image) {
        this.image = image;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getLoginName() {
        return loginName;
    }
    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }
    public String getLoginPwd() {
        return loginPwd;
    }
    public void setLoginPwd(String loginPwd) {
        this.loginPwd = loginPwd;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public String getMail() {
        return mail;
    }
    public void setMail(String mail) {
        this.mail = mail;
    }
    public String getDesc() {
        return Desc;
    }
    public void setDesc(String desc) {
        Desc = desc;
    }
    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }
    //1.
    public Users(String loginName, String loginPwd, String name,
            String address, String phone, String mail, Date date) {
        super();
        this.loginName = loginName;
        this.loginPwd = loginPwd;
        this.name = name;
        this.address = address;
        this.phone = phone;
        this.mail = mail;
        this.date = date;
    }
    //2.
    public Users() {
    }
    @Override
    public String toString() {
        return "Users [loginName=" + loginName + ", loginPwd=" + loginPwd
                + ", name=" + name + ", address=" + address + ", phone="
                + phone + ", mail=" + mail + ", date=" + date + "]";
    }   
}

Worker.java

package com.test.withXml.entity;
/**
 * @author 
 * @version: 1.0
 * @Created on: 2018-1-17 下午10:03:14
 * 类说明:工人
 */
public class Worker {

    private Integer id;
    private String name;
    private Pay pay;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Pay getPay() {
        return pay;
    }
    public void setPay(Pay pay) {
        this.pay = pay;
    }

}

映射文件User.hbm.xml

<!-- 映射文件 -->

<hibernate-mapping>
    <!-- class节点中的name属性对应实体类的名字,table属性对应数据表的名字,catalog对应数据库的名字 -->
    <class name="com.test.withXml.entity.Users" table="users" 
        catalog="hibernate_xml" dynamic-update="true">
        <!-- class节点下必须有一个<id>节点,用于定义实体类的标识属性(对应数据表中的主键),
            id节点的name属性对应实体类的属性,type对应该属性的Java类型
         -->
        <id name="id" type="java.lang.Integer" unsaved-value="100">
            <!-- column用于指定数据库表的列名 -->
            <column name="Id"></column>
            <!-- generator用于指定主键的生成器策略 ,使用native表示让底层数据库主键自增的方式生成,使用这种方式
            产生的ID会在执行Session的save()方法的时候,先执行SQL语句,在提交事务的意外情况。
            hilo表示使用Hibernate高低算法生成ID,使用该算法时,要在数据库中建立一张额外的表,
            默认表名为hibernate_unique_key,默认字段为integer类型,名称是next_hi,并设置初始值-->
            <generator class="native"></generator>
        </id>
        <!-- properties节点与id类似,用于映射普通属性 -->
        <property name="loginName" type="java.lang.String">
            <column name="LoginName" length="50"></column>
        </property>
        <property name="loginPwd" type="java.lang.String">
            <column name="LoginPwd" length="16"></column>
        </property>
        <property name="name" type="java.lang.String">
            <column name="Name" length="16"></column>
        </property>
        <property name="address" type="java.lang.String">
            <column name="Address" length="16"></column>
        </property>
        <property name="phone" type="java.lang.String">
            <column name="Phone" length="16"></column>
        </property>
        <property name="mail" type="java.lang.String">
            <column name="Mail" length="20"></column>
        </property>

        <!-- 映射派生属性,即对象中需要一个属性但是数据表中不需要再添加一个字段,使用派生属性即可 -->
        <property name="desc" formula="(SELECT concat(LoginName, ': ', LoginPwd) FROM users n WHERE n.id = id)"></property>

        <!-- 映射date(日期)、time(时间)、timestamp(时间戳),此时映射的是时间 -->
        <property name="date" type="date">
            <column name="Date" length="20"></column>
        </property>

        <!-- 映射大文本属性 -->
        <property name="content">
            <column name="Content" sql-type="mediumtext"></column>
        </property>
        <property name="image">
            <column name="Image" sql-type="mediumblob"></column>
        </property>

    </class>
</hibernate-mapping>

Worker.hbm.xml

<hibernate-mapping package="com.test.withXml.entity">
    <class name="Worker" table="WORKER">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <!-- 映射组成关系,即该属性不是一个基本数据类型,而是一个自定义的类,的引用类型 -->
        <component name="pay" class="Pay">
            <!-- 指定组成关系的组件属性 -->
            <property name="monthlyPay" column="MonthlyPay"></property>
            <property name="yearPay" column="YearPay"></property>
            <property name="vocationWithPay" column="VocationWithPay"></property>
        </component>
    </class>
</hibernate-mapping>
原文地址:https://www.cnblogs.com/tengpengfei/p/10453959.html