【Hibernate】(3)Hibernate单表操作

来源:互联网 发布:张成泽犬决 知乎 编辑:程序博客网 时间:2024/04/30 23:28

1. 单一主键

这个是在我们生成的Student.hbm.xml中配置的:

<hibernate-mapping><class name="com.thr.bean.Student" table="STUDENT"><id name="id" type="int"><column name="ID" /><generator class="assigned" /></id>

我们将hbm2ddl.auto配置为update

<property name="hbm2ddl.auto">update</property>
(1). assigned:由Java应用程序负责生成(手工赋值)

手工赋值就是我们之前所写的那种方式:

Student s = new Student();s.setName("李四");s.setGender("男");s.setBirthday(new Date());s.setAddress("北京");session.save(s); // 保存对象进入数据库

这个方法执行第一次的时候是成功的,id自动给值0,但是执行第二次的时候就报错了,应为id默认还是0,就会主键冲突。

(2). native:由底层数据库自动生成标识符,如果是MySQL就是increment,如果是Oracle就是sequence,等等

使用native的,如果不置顶id的话它默认会按照从1开始的自动增涨下去,所以当执行添加两次数据后,不会报错,并且id是1、2、3这样子排列下去的。即使你手工指定了id的值,也是不起作用的,插入到数据库中的值也是按照原来的递增顺序添加的。


2. 基本类型



Student.hbm.xml文件中

<property name="birthday" type="java.util.Date"><column name="BIRTHDAY" /></property>

java.util.Date是Java中的格式,是包括年月日时分秒的。

type类型如果是date就是只有年月日的格式。

type类型如果是time就是只有时分秒的格式。

type类型如果是timestamp就是包含年月日时分秒的格式。

date、time和timestamp这里是hibernate的数据类型。

3. 对象类型


MySQL不支持标准SQL的CLOB类型,在MySQL中,用TEXT、MEDIUMTEXT和LONGTEXT类型来表示长度超过255的长文本数据。

给之前的Student类添加一个新的属性:

private Blob picture;

注意,这里需要导入的是java.sql.Blob类

然后需要删除我们之前的Student.hbm.xml文件,重新生成一遍,然后编写方法写入数据库:

@Testpublic void testWriteBlob() throws Exception {Student s = new Student(1, "张三", "男", new Date(), "西安");// 先获取照片文件File f = new File("F:" + File.separator + "qtww.jpg");InputStream is = new FileInputStream(f);Blob image = Hibernate.getLobCreator(session).createBlob(is,is.available());s.setPicture(image);session.save(s);}
再写一个读取图片文件到本地的方法:

@Testpublic void testReadBlob() throws Exception {// 这里第二个参数是学生的主键Student s = (Student) session.get(Student.class, 1);Blob image = s.getPicture();InputStream is = image.getBinaryStream();File f = new File("D:/head.jpg");f.createNewFile();OutputStream os = new FileOutputStream(f);byte[] buff = new byte[is.available()];is.read(buff);os.write(buff);is.close();os.close();}

4. 组件属性

实体类中的某个属性属于用户自定义的类的对象。

增加新的Address实体类:

public class Address {private String postcode;private String phone;private String address;}
生成构造方法、get和set方法

修改Student类,加入这一个属性。

修改Student.hbm.xml文件,删除原来的address属性,在<class>标签内增加:

<component name="address" class="com.thr.bean.Address"><property name="postcode" column="POSTCODE"></property><property name="phone" column="PHONE"></property><property name="address" column="ADDRESS"></property></component>
修改测试代码:

@Testpublic void testSaveStudent() {// 生成学生对象// Student s = new Student(1, "张三", "男", new Date(), "西安");Student s = new Student();s.setId(1000);s.setName("李四");s.setGender("男");s.setBirthday(new Date());// s.setAddress("北京");Address address = new Address("710065", "0298856445", "西安市");s.setAddress(address);session.save(s); // 保存对象进入数据库}
运行后,我们发现在数据库中,新增了3个varchar字段存放我们刚才新建的那个实体类Address。


5. 单表CRUP操作实例

首先要修改策略为update。

@Testpublic void testGetStudent() {Student s = (Student) session.get(Student.class, 1000);System.out.println(s);}@Testpublic void testLoadStudent() {Student s = (Student) session.load(Student.class, 1000);System.out.println(s);}@Testpublic void testUpdateStudent() {Student s = (Student) session.get(Student.class, 1000);s.setGender("女");System.out.println(s);}@Testpublic void testDeleteStudent() {Student s = (Student) session.get(Student.class, 1000);session.delete(s);System.out.println(s);}
get和load的区别:

(1). 在不考虑缓存的情况下,get方法会在调用之后立即向数据库发出sql语句,返回持久化对象。而load方法会在调用后返回一个代理对象,该代理对象只保存了实体对象的id,直到使用对象的非主键属性时才会发出sql语句。

(2). 查询数据库中不存在的数据时,get方法返回null,load方法抛出异常org.hibernate.ObjectNotFoundException。


0 0