Hibernate与Java的数据类型转换和对数组,集合的扩充(十三)

版权声明:转载请注明出处(两个蝴蝶飞) https://blog.csdn.net/yjltx1234csdn/article/details/88352176

上一章简单介绍了Hibernte的多对多映射(十二),如果没有看过,请观看上一章

一.Hibernate的数据类型

Hibernate可以自动生成数据表. 在生成数据表的时候,应当保证一点,那就是数据的类型要保持一致。 在POJO中写得是Integer,那么在数据库生成的时候,是不能是varchar 类型的。 在POJO中写得是String ,那么在数据库生成的时候,是不能是int类型的。这就是如何将Java类型与数据库SQL 类型进行对应的问题。 如何对应呢? 是通过Hibernate进行对应的。 要有一个Hibernate的数据类型。 Hibernate是先将POJO即普通的java类型转换成Hibernate类型,然后将Hibernate类型转换成数据库SQL类型,这样就达到了Java类型转换成SQL类型的目的。这些类型对应关系,并非都是一对一的关系。 其他的框架,也是这个思路。

二.常用类型的生成测试

二.一 实体类

package com.yjl.pojo;

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

/**
 @author:两个蝴蝶飞
 @date: 2019年3月8日 上午10:33:16
 @Description 类型转换。
*/
public class Book {
	/**
	 * @param id 主键编号  是int 型
	 * @param name 书名  是varchar 型
	 * @param price 价钱  是number或者float型
	 * @param publishDate 出版日期   是timestamp 或者date 型
	 * @param author 作者  是varchar 型
	 * @param specialPrice 是否是降价  是boolean 型
	 * @param description 描述  是长字段 text型
	 * @param bookImage 图片  是Blod 型。  开发中存储的是地址
	 */
	private Integer id;
	private String name;
	private Double price;
	private Date publishDate;
	private String author;
	private Boolean specialPrice;
	private String description;
	private Blob bookImage;
	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 Double getPrice() {
		return price;
	}
	public void setPrice(Double price) {
		this.price = price;
	}
	public Date getPublishDate() {
		return publishDate;
	}
	public void setPublishDate(Date publishDate) {
		this.publishDate = publishDate;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public Boolean getSpecialPrice() {
		return specialPrice;
	}
	public void setSpecialPrice(Boolean specialPrice) {
		this.specialPrice = specialPrice;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public Blob getBookImage() {
		return bookImage;
	}
	public void setBookImage(Blob bookImage) {
		this.bookImage = bookImage;
	}
	@Override
	public String toString() {
		return "Book [id=" + id + ", name=" + name + ", price=" + price + ", publishDate=" + publishDate + ", author="
				+ author + ", specialPrice=" + specialPrice + ", description=" + description + "]";
	}
}

这里列举了常用的一些类型,如integer,double,string,date,blob,boolean类型。

二.二 Book.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.yjl.pojo">
	<class name="Book">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<!--后面的type 可以写java类型,也可以写hibernate类型。 但不能写sql类型。
		如果不写的话,会默认读取属性的类型,即java类型。-->
		<!-- 用的是java类型 -->
		<property name="name" column="name" type="java.lang.String"></property>
		<!-- 用的是java类型 -->
		<property name="price" column="price" type="java.lang.Double"></property>
		<!-- 用的是hibernate类型 -->
		<property name="publishDate" column="publishDate" type="timestamp"></property>
		<!-- 用hibernate类型 -->
		<property name="author" column="author" type="string"></property>
		<!-- 用的是java类型 -->
		<property name="specialPrice" column="specialPrice" type="java.lang.Boolean"></property>
		<!-- 用的是hibernate类型。  -->
		<property name="description" column="description" type="text"></property>
		<!-- 用的是java类型 -->
		<property name="bookImage" column="bookImage" type="java.sql.Blob"></property>
	</class>
</hibernate-mapping>

不要忘记,放入到hibernate.cfg.xml配置文件中。

二.三 测试生成文件

  /*测试创建表是否正确。*/
	@Test
	public void createTest(){
		Session session=HibernateUtil.getSession();
		session.close();
	}

在这里插入图片描述

二.四 测试插入

/*插入的测试*/
	@Test
	public void saveTest(){
		Session session=HibernateUtil.getSession();
		Transaction transaction=session.beginTransaction();
		/*创建对象。*/
		Book book=new Book();
		book.setName("蝴蝶飞往Java");
		book.setPrice(23.5D);
		book.setAuthor("两个蝴蝶飞");
		book.setPublishDate(new java.util.Date());
		book.setSpecialPrice(true); //是否是特价
		book.setDescription("也许,有的时候,就是那么一个人的存在,拯救了他的世界");
		File file=new File("D:"+File.separator+"java编程思想.jpg");
		InputStream input=null;
		try {
			input=new FileInputStream(file);
			//获取LobHelper接口
			LobHelper lobHelper=session.getLobHelper();  //可以创建Blob,也可以创建Clob. LobHelper
			Blob blob=lobHelper.createBlob(input,input.available());
			book.setBookImage(blob);
		} catch (Exception e) {
			e.printStackTrace();
		}
		session.save(book);
		transaction.commit();
		//要放在事务提交的后面。
		try {
			input.close();  //关闭input
		} catch (IOException e) {
			e.printStackTrace();
		}
		//关闭session
		session.close();
	}

可以正确的插入进去.
在这里插入图片描述
数据库存储的是:
在这里插入图片描述

二.五 从数据库中读取

/*读取的测试*/
	@Test
	public void readTest() throws Exception{
		Session session=HibernateUtil.getSession();
		Book book=session.get(Book.class,1);
		System.out.println(book.toString());
		//将图片的信息,存储到另外一个文件下。
		Blob blob=book.getBookImage();
		BufferedInputStream bis=null; 
		BufferedOutputStream bos=null;
		InputStream is=null;
		OutputStream os=null;
		is=blob.getBinaryStream();
		bis=new BufferedInputStream(is);
		os=new FileOutputStream("D:"+File.separator+"java编程思想数据库读取.jpg");
		bos=new BufferedOutputStream(os);
		int index=0;
		byte [] b=new byte[10240];
		while((index=is.read(b))!=-1){
			bos.write(b,0,index);
		}
		bis.close();
		bos.close();
		session.close();
	}

在这里插入图片描述
在D盘上也显示了这张图片:
在这里插入图片描述
打开后,也正常显示这个图片。

三. 对应关系

有一张对应关系的表。
在这里插入图片描述
在这里插入图片描述
要注意,这种对应关系并非是一对一再对一,即1-1-1的关系。 如java类型的String,即可以转换成varchar 类型,也可以是text类型。 这个时候,在Book.hbm.xml中 type就不要写Java类型了,要写成Hibernate类型。 还有一个Double注意区分,不要将Double与Float混了,两个是不能进行相互转换的。

四. Hibernate中写入其他的元素

四.一 写入Set <String >属性

这里用 学生的例子来说吧。 如一个学生有多张图片。 这些图片保存的都是String类型,即只保存图片的路径地址。 那么这个时候,实体类简化之后,应该是这样的:

public class Student {
	private Integer id;
	private String name;
	/*存入其他的类型*/
	private Set<String> images1;
	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 Set<String> getImages1() {
		return images1;
	}
	public void setImages1(Set<String> images1) {
		this.images1 = images1;
	}
}

相对应的xml配置文件是:

<hibernate-mapping package="com.yjl.pojo">
	<class name="Student">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<!-- 用的是java类型 -->
		<property name="name" column="name" type="java.lang.String"></property>
		<!-- 同样用set 标签来表示   table为要保存的表。-->
		<set name="images1" table="image">
			<key column="stuId"></key>
			<!-- 这里用element 元素来表示 -->
			<element column="imageName" type="string"></element>
		</set>
	</class>
</hibernate-mapping>

直接写生成的测试方法:

/*set 类型的测试*/
	@Test
	public void setTest(){
		Session session=HibernateUtil.getSession();
		Transaction transaction=session.beginTransaction();
		Set<String> imageSet=new HashSet<String>();
		imageSet.add("image1.png");
		imageSet.add("image2.png");
		imageSet.add("image3.png");
		imageSet.add("image3.png");
		Student s1=new Student();
		s1.setName("两个蝴蝶飞");
		s1.setImages1(imageSet);
		session.save(s1);
		transaction.commit();
	}

运行之后,会创建两张表。 一个表是student 表,里面只有 id,name 两个属性。 并没有任何关于图片的信息。 另外一个表是image,里面有两个属性,一个是stuId,另外一个是imageName. 这个表是没有主键的。 将对应关系放置到这个表里面了。 是无序的。
在这里插入图片描述
读取的测试:

/*读取的测试*/
	@Test
	public void setReadTest(){
		Session session=HibernateUtil.getSession();
		Student stu=session.get(Student.class,1);
		Set<String> imageSet=stu.getImages1();
		Iterator <String> images=imageSet.iterator();
		while(images.hasNext()){
			System.out.println(images.next());
		}
	}

在这里插入图片描述
下面的,与其一样。

四.二 写入List <String > 属性

如果是数组的话,将其转换成List的形式。

public class Student {
	private Integer id;
	private String name;
	/*存入其他的类型*/
	private List<String> hobby;
	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 List<String> getHobby() {
		return hobby;
	}
	public void setHobby(List<String> hobby) {
		this.hobby = hobby;
	}
}

配置文件:

<hibernate-mapping package="com.yjl.pojo">
	<class name="Student">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<!-- 用的是java类型 -->
		<property name="name" column="name" type="java.lang.String"></property>
		<!-- 用list 标签来表示 -->
		<list name="hobby" table="hobby">
			<key column="stuId"></key>
			<!-- 有顺序。 把顺序放置进来 -->
			<list-index column="hobbyIndex"></list-index>
			<!-- 这里用element 元素来表示 -->
			<element column="hobbyName" type="string"></element>
		</list>
	</class>
</hibernate-mapping>

测试:

@Test
	public void listTest(){
		Session session=HibernateUtil.getSession();
		Transaction transaction=session.beginTransaction();
		List<String> hobbyList=new ArrayList<String>();
		hobbyList.add("编程");
		hobbyList.add("五音不全的唱歌");
		hobbyList.add("打游戏");
		Student s1=new Student();
		s1.setName("两个蝴蝶飞");
		s1.setHobby(hobbyList);
		session.save(s1);
		transaction.commit();
	}

点击运行之后,会生成Student 和hobby 两个表. 同样没有主键。 id顺序在后。
在这里插入图片描述
是有顺序的。

/*读取的测试*/
	@Test
	public void listReadTest(){
		Session session=HibernateUtil.getSession();
		Student stu=session.get(Student.class,1);
		List<String> hobbyList=stu.getHobby();
		Iterator <String> images=hobbyList.iterator();
		while(images.hasNext()){
			System.out.println(images.next());
		}
	}

在这里插入图片描述

四.三 写入idbag<String > 属性

idbag,是映射,叫包。 是一个无序的,允许重复的集合。 没有具体的实现,只有定义。
可以用Collection,也可以用List. 这里用List进行相关的说明。 所以,实体Student.java 是不变的。 用List集合。

配置文件:

<hibernate-mapping package="com.yjl.pojo">
	<class name="Student">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<!-- 用的是java类型 -->
		<property name="name" column="name" type="java.lang.String"></property>
		<!-- 用idbag 包标签来表示 -->
		<idbag name="hobby" table="hobby">
			<collection-id type="long" column="hobbyId">
				<generator class="increment"></generator>
			</collection-id>
			<key column="stuId"></key>
			<!-- 这里用element 元素来表示 -->
			<element column="hobbyName" type="string"></element>
		</idbag>
	</class>
</hibernate-mapping>

保存测试:

/*栈 bag 类型的测试*/
	@Test
	public void bagTest(){
		Session session=HibernateUtil.getSession();
		Transaction transaction=session.beginTransaction();
		List<String> hobbyList=new ArrayList<String>();
		hobbyList.add("编程1");
		hobbyList.add("五音不全的唱歌1");
		hobbyList.add("打游戏1");
		Student s1=new Student();
		s1.setName("两个蝴蝶飞");
		s1.setHobby(hobbyList);
		session.save(s1);
		transaction.commit();
	}

会生成两个表。 id顺序在前。
在这里插入图片描述
查询时:

/*读取的测试*/
	@Test
	public void bagReadTest(){
		Session session=HibernateUtil.getSession();
		Student stu=session.get(Student.class,1);
		List<String> hobbyList=stu.getHobby();
		Iterator <String> images=hobbyList.iterator();
		while(images.hasNext()){
			System.out.println(images.next());
		}
	}

在这里插入图片描述

四.四 写入Map <String,String> 属性

实体类:

public class Student {
	private Integer id;
	private String name;
	/*存入其他的类型*/
	private Map<String,String> girls;
	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 Map<String, String> getGirls() {
		return girls;
	}
	public void setGirls(Map<String, String> girls) {
		this.girls = girls;
	}
}

配置文件:

<hibernate-mapping package="com.yjl.pojo">
	<class name="Student">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<!-- 用的是java类型 -->
		<property name="name" column="name" type="java.lang.String"></property>
		<!-- 用map 标签来表示 -->
		<map name="girls" table="girls">
			<key column="stuId"></key>
			<map-key column="girlId" type="string"></map-key>
			<!-- 这里用element 元素来表示 -->
			<element column="girlName" type="string"></element>
		</map>
	</class>
</hibernate-mapping>

保存测试:

@Test
	public void MapTest(){
		Session session=HibernateUtil.getSession();
		Transaction transaction=session.beginTransaction();
		Map<String,String> girlList=new HashMap<String,String>();
		girlList.put("Java","一个非常文静的女孩");
		girlList.put("Python","一个非常聪明的女孩");
		girlList.put("Go","听说很有钱的女孩");
		Student s1=new Student();
		s1.setName("两个蝴蝶飞");
		s1.setGirls(girlList);
		session.save(s1);
		transaction.commit();
	}

运行生成后: 是无序的。
在这里插入图片描述
查询:

@Test
	public void MapReadTest(){
		Session session=HibernateUtil.getSession();
		Student stu=session.get(Student.class,1);
		Map<String,String> girlList=stu.getGirls();
		for(Map.Entry<String,String> m:girlList.entrySet()){
			System.out.println(m.getKey()+"----"+m.getValue());
		}
	}

在这里插入图片描述
这是Hibernate对Set,List,idbag和Map的常见映射。
谢谢!!!

猜你喜欢

转载自blog.csdn.net/yjltx1234csdn/article/details/88352176