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

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

一.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();
  }


20190308141026922.png


二.四 测试插入


/*插入的测试*/
  @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();
  }


可以正确的插入进去.


2019030814150674.png


数据库存储的是:


2019030814153930.png


二.五 从数据库中读取


/*读取的测试*/
  @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();
  }


20190308141700194.png


在D盘上也显示了这张图片:


20190308142049618.png

打开后,也正常显示这个图片。


三. 对应关系


有一张对应关系的表。


20190308142312275.png


20190308142410290.png


要注意,这种对应关系并非是一对一再对一,即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. 这个表是没有主键的。 将对应关系放置到这个表里面了。 是无序的。


20190308144526433.png


读取的测试:


/*读取的测试*/
  @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());
    }
  }


20190308144850861.png


下面的,与其一样。


四.二 写入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顺序在后。


20190308145725902.png


是有顺序的。


/*读取的测试*/
  @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());
    }
  }


20190308145811266.png


四.三 写入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顺序在前。


20190308150849299.png


查询时:


/*读取的测试*/
  @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());
    }
  }


20190308150903874.png


四.四 写入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();
  }


运行生成后: 是无序的。


20190308151944643.png


查询:


@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());
    }
  }


20190308152041377.png


这是Hibernate对Set,List,idbag和Map的常见映射。


谢谢!!!

相关文章
|
1天前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
6 2
|
1天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
5天前
|
存储 Java
判断一个元素是否在 Java 中的 Set 集合中
【10月更文挑战第30天】使用`contains()`方法可以方便快捷地判断一个元素是否在Java中的`Set`集合中,但对于自定义对象,需要注意重写`equals()`方法以确保正确的判断结果,同时根据具体的性能需求选择合适的`Set`实现类。
|
3天前
|
SQL Java 数据库连接
从理论到实践:Hibernate与JPA在Java项目中的实际应用
本文介绍了Java持久层框架Hibernate和JPA的基本概念及其在具体项目中的应用。通过一个在线书店系统的实例,展示了如何使用@Entity注解定义实体类、通过Spring Data JPA定义仓库接口、在服务层调用方法进行数据库操作,以及使用JPQL编写自定义查询和管理事务。这些技术不仅简化了数据库操作,还显著提升了开发效率。
12 3
|
4天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
21 4
|
2天前
|
存储 消息中间件 NoSQL
使用Java操作Redis数据类型的详解指南
通过使用Jedis库,可以在Java中方便地操作Redis的各种数据类型。本文详细介绍了字符串、哈希、列表、集合和有序集合的基本操作及其对应的Java实现。这些示例展示了如何使用Java与Redis进行交互,为开发高效的Redis客户端应用程序提供了基础。希望本文的指南能帮助您更好地理解和使用Redis,提升应用程序的性能和可靠性。
9 1
|
5天前
|
存储 Java 开发者
在 Java 中,如何遍历一个 Set 集合?
【10月更文挑战第30天】开发者可以根据具体的需求和代码风格选择合适的遍历方式。增强for循环简洁直观,适用于大多数简单的遍历场景;迭代器则更加灵活,可在遍历过程中进行更多复杂的操作;而Lambda表达式和`forEach`方法则提供了一种更简洁的函数式编程风格的遍历方式。
|
5天前
|
Java 开发者
|
12天前
|
缓存 Java 数据库连接
Hibernate:Java持久层框架的高效应用
通过上述步骤,可以在Java项目中高效应用Hibernate框架,实现对关系数据库的透明持久化管理。Hibernate提供的强大功能和灵活配置,使得开发者能够专注于业务逻辑的实现,而不必过多关注底层数据库操作。
10 1
|
5天前
|
存储 Java 开发者
Java中的集合框架深入解析
【10月更文挑战第32天】本文旨在为读者揭开Java集合框架的神秘面纱,通过深入浅出的方式介绍其内部结构与运作机制。我们将从集合框架的设计哲学出发,探讨其如何影响我们的编程实践,并配以代码示例,展示如何在真实场景中应用这些知识。无论你是Java新手还是资深开发者,这篇文章都将为你提供新的视角和实用技巧。
7 0
下一篇
无影云桌面