Hibernate--CirclesOfImage应用

本次目的:

需求是为一幅图像寻找里边的所有圆,并将这些圆保存到数据库中。

所以数据库的设计为,对于一幅图像,

  • 保存它的图片名(图片统一保存在某个目录下,所以只需要保存图片名)
  • 保存它里边的所有圆的信息,因为每幅图像中圆个数未知,所以采用List保存所有圆
  • 圆为自定义类型,包括圆心(x,y)以及半径radius

自定义类型Circle

如下图所示,我将Circle存在包c里边。

圆里边有变量x,y记录圆心,radius记录半径,还有一个String变量strCircle记录圆信息,为什么使用它,在接下来会提到。

补充好它们的get和set方法!

存储用类型CirclesOfImage

设计的存储类型如下:

int类型的id号

String类型的imageUrl

List<String>类型的circles

这个类保存在hibernate包中。

hibernate.cfg.xml

在src里边新建这个文件就好了,在这里设置的具体数据库映射文件为在包hibernate中的Circles.hdb.xml。

Circles.hdb.xml

我把它创建在包hibernate里边,主键为id,有一个imageUrl列,以及一个存储List的列,List为另外的一张表,在这里用外键引用。

Test.java测试类

    package hibernate;
    import java.util.ArrayList;
    import java.util.List;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.Transaction;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.service.ServiceRegistry;
    import org.hibernate.service.ServiceRegistryBuilder;
    import c.Circle;

    public class Test {

        /**
         * @param args
         */
        private SessionFactory sessionFactory;
        private Configuration configuration;
        private ServiceRegistry serviceRegistry;
        private Transaction transaction;
        private Session session;
        public Test(){
            sessionFactory = null;
            configuration = new Configuration().configure();
            serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
            session = sessionFactory.openSession();
            transaction = session.beginTransaction();
        }
        public void destroy(){
            transaction.commit();
            session.close();
            sessionFactory.close();
        }
        public void test(){
            CirclesOfImage circlesOfImage = new CirclesOfImage();
            circlesOfImage.setImageUrl("abc.jpg");
            List<String> circles = new ArrayList<String>();
            for (int i = 0; i < 10; i++){
                Circle c = new Circle(i, i+1, i+2);
                circles.add(c.getStrCircle());
            }
            circlesOfImage.setCircles(circles);
            session.save(circlesOfImage);
        }
        public void get(){
            CirclesOfImage circlesOfImage = (CirclesOfImage)session.get(CirclesOfImage.class, 1);
            System.out.println(circlesOfImage.toString());
        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Test t = new Test();
            t.test();
            t.get();
            t.destroy();

        }

    }

这里有三个问题:

  1. 为什么用List<String> 而不是ArrayList<String>来记录circles?

    2.为什么用String记录Circle而不是用直接用Circle类型呢?

  2. 在mysql中List<String>类型该怎么存储呢?

第一个问题

如果我采用了ArrayList<String>的话,也就是写成

ArrayList<String> circles = new ArrayList<String>();

那么会报这个错误:

Expected type: java.util.List, actual value: org.hibernate.collection.internal.PersistentSetup

解决办法我是在[http://blog.csdn.net/hollboy/article/details/9006043]看到的。(http://blog.csdn.net/hollboy/article/details/9006043)

**里边是这样分析:Hibernate为了方便对集合懒加载操作,在顶层对所有的jdk中的集合进行了改写,所以只要以保存之后再取出来,hibernate已经对数据类型进行转换

所以domain定义时属性不能定义成具体的类,而是定义成接口(如定义成Set而不是HashSet), 否则在hibernate中运行会报类型异常。**

第二个问题

如果我写成

ArrayList<Circle> circles = new ArrayList<Circle>();

那么会报这个错哦:

org.hibernate.MappingException: Could not determine type for: c.Circle

我映射文件是这么写的

<list name = "circles" table = "circles">

<key>

<column name = "circle_id"></column>

</key>

<list-index>

<column name="list_order"></column>

</list-index>

<element type = "c.Circle">

<column name="circle_info"></column>

</element>

</list>

似乎映射是写对了,我的类是在c.Circle中,但是呢,type是写给hibernate看的,hibernate有一些支持的类型,也就是它可以识别的,可以用来存储的类别,而其他的自定义类别它肯定是识别不了的嘛,也许有方式,不过我这里就简单地用String来存储Circle不就解决问题了嘛!

关于hibernate中可用的映射类型可以查看

http://www.cnblogs.com/aijava/archive/2008/06/04/2191859.html

第三个问题

我是看

[http://blog.sina.com.cn/s/blog_86f4502c0101fmkp.html]解决的。(http://blog.sina.com.cn/s/blog_86f4502c0101fmkp.html)

按照我上面的方式来做也就可以了,也就是再建张表来存储啦,确实可以存储可变长,很神奇。

实验结果

在数据库中确实多了两个表哦。

来分别看一下它们的具体存储

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 07-06

Hibernate--CirclesOfImage应用的相关文章

Hibernate - HHH000352: Unable to release batch statement

这是hibernate的一个bug,具体看https://hibernate.atlassian.net/browse/HHH-11732?attachmentViewMode=list When using stateless session with jdbc batch size we get an HHH000352: Unable to release batch statement.. error in session.close() after rollback: Code:Con

Hibernate简述及入门实例

一.Hibernate简述 总的概括,Hibernate是一个ORM的轻量级持久层框架,解决了对象和关系数据库中表的不匹配问题(阻抗不匹配)以及拥有开发代码不用去继承hibernate类或接口的优势(无侵入性).hibernate框架实现使得开发人员可以避免反复地编写javajdbc部分代码,应用面向对象的思维操作关系型数据库. 二.使用myeclipse创建hibernate实例两种方法(以hibernate3.5.2及mysql为例) a)手动编写hibernate.cfg.xml及*.hb

对象序列化和反序列--Hibernate的查询和新增极其相似

Hibernate几个关键字持久化,ORM(关系对象映射)(数据库中关系称作是一张表) 应用在项目中,刘一从写的查询代码,每次都挂掉,想要弄出测试数据,自己想着把查询出来的复杂数据弄到文件里自己要是去造那些复杂数据很麻烦public class Object1 { public static void main(String args[]){ HashMap<String, Object> obj=new HashMap<String,Object>(); obj.put(&quo

Hibernate的七种映射关系之七种关联映射(二)

继续上篇博客 七.Hibernate双向一对多关联映射:让多的一端来维护关系. 主要是解决一对多单向关联的缺陷,而不是需求驱动的. 1.在Student.java实体类里添加Classes引用.private Classes classes; 2.Student.hbm.xml里添加many-to-one标签:<many-to-one name="classes" column="classesid"/>.Classes.hbm.xml在例子(六)里的那

Hibernate的七种映射关系之七种关联映射(一)

关联映射就是将关联关系映射到数据库里,在对象模型中就是一个或多个引用. 一.Hibernate多对一关联映射:就是在"多"的一端加外键,指向"一"的一端. 比如多个学生对应一个班级,多个用户对应一个级别等等,都是多对一关系. 1."多"端实体加入引用"一"端实体的变量及getter,setter方法. 比如说多个学生对应一个班级,在学生实体类加入:private Grade grade; 2."多"端配置文

mybatis与hibernate的区别

本文转载自:http://blog.csdn.net/wangpeng047/article/details/17038659 以前没怎么用过mybatis,只知道与hibernate一样是个orm数据库框架.随着使用熟练度的增加,发现它与hibernate区别是非常大的,结合至今为止的经验,总结出以下几点: 1. hibernate是全自动,而mybatis是半自动. hibernate完全可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成sql

hibernate载入持久化对象的两种方式——get、load

一.get与load对照 在hibernate中get和load方法是依据id取得持久化对象的两种方法.但在实际使用的过程中总会把两者混淆,不知道什么情况下使用get好,什么时候使用load方法效率更高.下边具体说一下get和load的不同,有些时候为了对照也会把find加进来. 1.从返回结果上对照: load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常 get方法检索不到的话会返回null 2.从检索运行机制上对照: get方法和fin

org.hibernate.NonUniqueObjectException:a different object with the same identifier value was alread

转自: http://blog.csdn.net/zzzz3621/article/details/9776539 看异常提示意思已经很明显了,是说主键不唯一,在事务的最后执行SQL时,session缓存里面有多个(>1)主键一样的对象. 了解过hibernate的都知道它有一个一级缓存,即session级别的缓存,在一个事务的执行过程中可以管理持久化对象,在事务最后执行SQL,可以减少数据库的操作. 报这个异常就得仔细看看你的代码,一定有地方引用的对象已经不同了. 下面就是一个典型的例子: [

谈谈你对Hibernate的理解

答: 1. 面向对象设计的软件内部运行过程可以理解成就是在不断创建各种新对象.建立对象之间的关系,调用对象的方法来改变各个对象的状态和对象消亡的过程,不管程序运行的过程和操作怎么样,本质上都是要得到一个结果,程序上一个时刻和下一个时刻的运行结果的差异就表现在内存中的对象状态发生了变化. 2.为了在关机和内存空间不够的状况下,保持程序的运行状态,需要将内存中的对象状态保存到持久化设备和从持久化设备中恢复出对象的状态,通常都是保存到关系数据库来保存大量对象信息.从Java程序的运行功能上来讲,保存对

Hibernate session缓存

一级缓存(执行代码时查看console台上的sql语句)  清空缓存 @Test public void demo03(){ //清空缓存 Session session=factory.openSession(); session.beginTransaction(); //1.查询 User user = (User)session.get(User.class, 1); System.out.println(user); //session.evitc(user) //将执行对象从一级缓存