zoukankan      html  css  js  c++  java
  • hibernate学习系列-----(7)hibernate对集合属性的操作之List集合篇

    今天要写的内容其实不多,本打算将hibernate对集合的操作的内容直接归结为一篇的,但想一想,还是分开写的比较好,毕竟前面的已经发布出去来了,废话不多说,开始吧!


    依旧新建一个StudentList.java实体类,其他的属性不变,只是将hobby属性由Set集合类型变为List集合类型,还是把代码贴出来吧,希望不要嫌烦

    package com.joe.entity;
    
    import java.util.List;
    
    public class StudentList {
        
        private int id;
        private String name;
        private int age;
        
        private List<String> hobby;
    
        /**
         * 无参构造函数
         */
        public StudentList(){
            
        }
        
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public List<String> getHobby() {
            return hobby;
        }
    
        public void setHobby(List<String> hobby) {
            this.hobby = hobby;
        }
        
    
    }

    接下来,大家都知道的,就是配置StudentList.hbm.xml对象关系映射文件了,先说说<list>标签吧,<list>元素用来映射java.util.List类型的属性,常用的属性和子元素有:

    1. name属性
    2. table属性
    3. <key>子元素
    4. <list-index>子元素
    5. <element>子元素

    照样贴上代码:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE hibernate-mapping SYSTEM "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
    <hibernate-mapping>
        <!-- 一个class标签对应一个实体类,name属性指定实体类名称,table属性指定关联的数据库表 -->
        <class name="com.joe.entity.StudentList" table="stu_list_tab">
            <!-- 主键 -->
            <id name="id" column="stu_id">
                <!-- 提供ID自增的策略  native会根据数据库自行判断 -->
                <generator class="native"></generator>
            </id>
            <!-- 其他属性,name对应实体类的属性,column对应关系型数据库表的列 -->
            <property name="name" column="stu_name"></property>
            <property name="age" column="stu_age"></property>
            
            <list name="hobby" table="hobby_list_tab">
                <key column="student_id"></key>
                <list-index column="position"></list-index>
                <element type="string" column="hobby"></element>
            </list>
            
        </class>
    </hibernate-mapping>

    来解读一下list标签吧,<key>子元素和<element>子元素就不多讲了,主要是<list-index>子元素,我查了一下资料,也可以使用<index>,因List集合是个有序可重复的集合,所以要使用<index-index column="position"/></list-index>(或者使用<index column="position"></index>) 来标明其顺序。(position为hobby_list_tab表中附加字段),因此在插入更新时便需要维护position字段,否则索引设置错误,取出的数据就会出现空值情况。

    如果<list>标签配置了inverse="true"属性, 则list的index则不会主动赋值,index列会产生空值,如果index列数据库设置可以为空,则可以正常保存数据. 而用hibernate再去查询对象数据时,会抛出null index column for collection: 此类错误.也就是说配置inverse为true的list,需要手动维护index列.感觉还是挺复杂的,有点儿搅。

    当然,还可以使用<bag>(结合了List与Set)标签来配置list集合属性,可以重复且没有顺序的一种集合,是Hibernate提供的。HIbernate使用jdk的List模拟Bag。其配置与Hibernate映射list时基本相同。这里就不再讨论来,毕竟这是是冲着list来的。

    依旧建立一个StudentListTest.java测试类,先写一个创建表结构的方法:

    @Test
        public void createTable() {
            Configuration cfg = new Configuration().configure();
            SchemaExport se = new SchemaExport(cfg);
            se.create(true, true);
        }

    执行该方法,看看hibernate的执行结果:

    QQ截图20150809105449

    在创建hobby_list_tab表的时候,可以看到position字段配置来not null 属性,这也体现来前面的list标签的配置,更多的信息可以在其官方文档了解,这里提供一个快捷通道:点击这里

    add()方法的测试:

    /**
         * 添加的方法
         */
        @Test
        public void add(){
            Transaction tx=null;
            Session session=null;
            try{
                session=HibernateUtils.getSession();
                tx=session.beginTransaction();
                StudentList student=new StudentList();
                student.setName("zhangsan");
                student.setAge(20);
                
                List<String> list=new ArrayList<String>();
                list.add("basketball");
                list.add("swimming");
                
                student.setHobby(list);
                
                session.save(student);
                
                
                tx.commit();
            }catch(HibernateException he){
                if(tx!=null){
                    tx.rollback();
                }
                he.printStackTrace();
            }finally{
                HibernateUtils.closeSession(session);
            }
        }

    执行该方法,看看控制台的输出信息:

    QQ截图20150809110500

    只有一点需要说明的,就是我在程序中并没有为position肤质,那position字段中是否有值,如果有,为何值?打开mysql数据库,一看便知:

    QQ截图20150809110912

    哎,有值,这是hibernate提供的一种机制,它自动维护,只要你配置正确。还有一个问题需要注意,就是为什么是从0开始的而不是其他的值开始的呢?这就和我们的List集合相关联,List的底层是一个动态的数组,所以添加元素时,下标是从0开始的。

    findAll()方法的测试:

    @Test
        public void findAll(){
            Transaction tx=null;
            Session session=null;
            try{
                session=HibernateUtils.getSession();
                tx=session.beginTransaction();
                
                StudentList stu=(StudentList)session.get(StudentList.class, 1);
                System.out.println(stu.getId()+stu.getName()+stu.getAge());
                
                
                
                tx.commit();
            }catch(HibernateException he){
                if(tx!=null){
                    tx.rollback();
                }
                he.printStackTrace();
            }finally{
                HibernateUtils.closeSession(session);
            }
        }

    和以前测试差不多,先只访问基本属性,我想hibernate的执行动作大家都知道了,只会有一条select语句,不会去访问hobby_list_tab表的,还是贴上图吧:

    QQ截图20150809112027

    接下来,添加访问hobby属性的代码:

    //访问hobby属性
                List<String> hobby=stu.getHobby();
                for(String str:hobby){
                    System.out.println(str);
                }

    相信结果大家还是知道的,依旧贴图:

    QQ截图20150809112301

    其实自我感觉这篇文章和上一篇文章有点重复,但是还不至于无聊致死,毕竟知识是一步一步学来的,接下来的一两篇,节奏大概还是这样的吧,各位看官,不要嫌我啰嗦哟。

  • 相关阅读:
    AI零基础入门之人工智能开启新时代—下篇
    AI零基础入门之人工智能开启新时代—上篇
    Markdown 快速入门
    Linux GCC/G++ 基础(1) 之
    解决 Ubuntu 下使用 sublime text 3 无法输入中文
    WPF:界面布局之- TaiChi
    常用命令之- touch
    微软net平台是不是快完了?看了一天智联招聘,现在连传统的网站或系统平台都不怎么用net了
    蓝牙Ble开发(支持API18<Android 4.3 Jelly>及以上)
    Android系统休眠对程序的影响以及处理
  • 原文地址:https://www.cnblogs.com/doctorJoe/p/4714831.html
Copyright © 2011-2022 走看看