本次目的:
需求是为一幅图像寻找里边的所有圆,并将这些圆保存到数据库中。
所以数据库的设计为,对于一幅图像,
- 保存它的图片名(图片统一保存在某个目录下,所以只需要保存图片名)
- 保存它里边的所有圆的信息,因为每幅图像中圆个数未知,所以采用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();
}
}
这里有三个问题:
- 为什么用
List<String>
而不是ArrayList<String>
来记录circles?2.为什么用String记录Circle而不是用直接用Circle类型呢?
- 在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)
按照我上面的方式来做也就可以了,也就是再建张表来存储啦,确实可以存储可变长,很神奇。
实验结果
在数据库中确实多了两个表哦。
来分别看一下它们的具体存储
版权声明:本文为博主原创文章,未经博主允许不得转载。