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


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


二.四 测试插入


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


可以正确的插入进去.


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


数据库存储的是:


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


二.五 从数据库中读取


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


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


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


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

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


三. 对应关系


有一张对应关系的表。


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


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


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


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


读取的测试:


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


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


下面的,与其一样。


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


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


是有顺序的。


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


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


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


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


查询时:


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


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


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


运行生成后: 是无序的。


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


查询:


@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与Java的数据类型转换和对数组,集合的扩充(十三)


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


谢谢!!!

上一篇:教育行业优质解决方案分享【教育数据中台解决方案】


下一篇:hell脚本分享:DebianLNMP一键安装服务器套件