Hibernate框架基础——映射普通属性
来源:互联网 发布:安卓网络嗅探器怎么用 编辑:程序博客网 时间:2024/04/30 00:58
持久化对象与OID
对持久化对象的要求
- 提供一个无参的构造器。使Hibernate可以使用Constructor.newInstance()来实例化持久化类。
- 提供一个标识属性(identifier property)。通常映射为数据库表的主键字段。如果没有该属性,一些功能将不起作用,如:Session.saveOrUpdate()。
- 为类的持久化字段声明访问方法(get/set)。Hibernate对JavaBean风格的属性实行持久化。
- 使用非final类。在运行时生成代理是Hibernate的一个重要的功能。如果持久化类没有实现任何接口,Hibnernate使用CGLIB生成代理。如果使用的是final类,则无法生成CGLIB代理。
- 重写eqauls()和hashCode()方法。如果需要把持久化类的实例放到Set中(当需要进行关联映射时),则应该重写这两个方法。
例,我们可在cn.itcast.c_hbm_property包下创建这样一个持久化类——User.java。
/** * 实体 */public class User { private int id; private String name; 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; } @Override public String toString() { return "[User: id=" + id + ", name=" + name + "]"; }}
OID
为了在系统中能够找到所需对象,需要为每一个对象分配一个唯一的标识号。在关系数据库中称之为主键,而在对象术语中,则叫做对象标识(Object identifier-OID)。
对象/关系数据库映射文件(hbm.xml)
Hibernate采用XML格式的文件来指定对象和关系数据之间的映射。在运行时Hibernate将根据这个映射文件来生成各种SQL语句。映射文件的扩展名为”.hbm.xml”。
映射文件示例:
持久化类的属性及属性映射(普通属性)
对应于cn.itcast.c_hbm_property包下的持久化类——User.java,我们应在该包下创建出对象/关系数据库映射文件——User.hbm.xml。
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="cn.itcast.c_hbm_property"> <!-- name属性:哪个类 table属性:对应哪个表,如果不写,默认的表名就是类的简单名称 --> <class name="User" table="t_user"> <id name="id" type="int" column="id"> <generator class="native"/> </id> <property name="name" type="string" column="name" length="20" not-null="true" /> </class></hibernate-mapping>
映射配置:
<property name="name" type="string" column="name" length="20" not-null="true" />
即为映射的普通属性,普通属性指数据库中的基本类型,如字符串、日期、数字等。下面我们就来详解<property ... />
元素中的各个属性:
- name属性:对象中的属性名,必须要有。
- type属性:类型,如果不写,Hibernate会自动检测。可以写java中类的全名或是写hibernate类型。
- column属性:对应表中的列名,如果没写,默认为属性名。
- length属性:长度,不是所有的类型都有长度属性,比如varchar有,但int没有,如果不写默认为255。
- not-null属性:非空约束,默认为false。
所以上面的映射配置,直接写成这样干巴巴的配置:
<property name="name" />
也是可以的。
单单是编写上面这样一个映射文件——User.hbm.xml,涉及到的知识点还是蛮多的,下面我们一一讲解。
Hibernate的映射类型
内置映射类型
java时间和日期类性
大对象类型的映射
JDK自带的个别java类的映射类型
设置类的包名
如果在一个映射文件中包含多个类,并且这些类位于同一个包中,可以设置<hibernate-mapping>
元素的package属性,以避免为每个类提供完整的类名。
指定类的全限定名:
在<hibernate-mapping>
元素中指定package属性,就只需指定简单类名了:
处理sql引用表示符
在实际开发中,我们要编写的持久化类不会这么简单,也就是说User类不会只有
private int id;private String name;
这两个字段。通常它含有的字段挺多的,例如:
/** * 实体 */public class User { private int id; private String name; private Integer age; private Date birthday; // 生日 private String desc; // 一大段说明 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 Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } @Override public String toString() { return "[User: id=" + id + ", name=" + name + "]"; }}
我们接下来就要修改映射文件——User.hbm.xml了。
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="cn.itcast.c_hbm_property"> <!-- name属性:哪个类 table属性:对应哪个表,如果不写,默认的表名就是类的简单名称 --> <class name="User" table="t_user"> <id name="id" type="int" column="id"> <generator class="native"/> </id> <property name="name" type="string" column="name" length="20" not-null="true" /> <property name="age" type="int" column="age_" /> <property name="birthday" type="date" column="birthday_" /> <!-- 指定使用text类型时,最好再指定length,以确定生成的SQL类型是能够存放指定数量的字符的。 --> <property name="desc" type="text" length="5000" column="`desc`"/> </class></hibernate-mapping>
我们从中可以看到User持久化类的属性desc的映射配置为:
<property name="desc" type="text" length="5000" column="`desc`"/>
思考一个问题:column属性为何要写成column=”`desc`”?可参考下面这段话:
在SQL语法中,表示符是指用于数据库表、视图、字段或索引等名字的字符串,常规表示符不包括空格,也不包含特殊字符,因此无需使用引用符号。如果数据库表名或列名包含特殊字符,可以使用引用表示符(键盘~下面的字符)。
用更通俗易懂的话说就是:当列名与关键字冲突时,可以通过column属性指定一个其他的列名,或是使用反引号包围起来(不建议使用)。
现在我们编写单元测试来进行测试,在cn.itcast.c_hbm_property包下编写一个单元测试类——App.java。
public class App { private static SessionFactory sessionFactory; static { sessionFactory = new Configuration() // .configure() // 读取配置文件 .addClass(User.class) // .buildSessionFactory(); } @Test public void testSave() throws Exception { // 创建对象实例 User user = new User(); user.setName("张三"); user.setAge(20); user.setBirthday(new Date()); user.setDesc("一大段的说明,此处省略5000字..."); // 保存 Session session = sessionFactory.openSession(); // 打开一个新的Session Transaction tx = session.beginTransaction(); // 开启事务 session.save(user); tx.commit(); // 提交事务 session.close(); // 关闭Session,释放资源 } @Test public void testGet() throws Exception { Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); User user = (User) session.get(User.class, 1); // 获取? System.out.println(user.getId()); System.out.println(user.getName()); System.out.println(user.getDesc()); tx.commit(); session.close(); }}
运行testSave()方法,再去查看t_user表结构:
发现t_user表desc列的数据类型是longtext,而若是一定要让desc列的数据类型是text,也是有法子的,可以将
<property name="desc" type="text" length="5000" column="`desc`"/>
修改为:
<property name="desc"> <column name="desc_" length="5000" sql-type="text"></column></property>
这时再次运行testSave()方法,再去查看t_user表结构:
发现t_user表desc列的数据类型是text了,我们的目的达到了。虽说可以这样写,但是一般不建议这样写。
最后,我们在持久化类——User.java中加入一个字段:
private byte[] photo; // 头像图片(二进制内容)
映射文件中增加:
<!-- 头像,二进制类型,最好指定长度 --><property name="photo" type="binary" length="102400"></property>
这时我们修改单元测试类——App.java的代码为:
public class App { private static SessionFactory sessionFactory; static { sessionFactory = new Configuration() // .configure() // 读取配置文件 .addClass(User.class) // .buildSessionFactory(); } @Test public void testSave() throws Exception { // 读取图片文件 InputStream in = new FileInputStream("c:/1.jpg"); byte[] photo = new byte[in.available()]; in.read(photo); in.close(); // 创建对象实例 User user = new User(); user.setName("张三"); user.setAge(20); user.setBirthday(new Date()); user.setDesc("一大段的说明,此处省略5000字..."); user.setPhoto(photo); // 保存 Session session = sessionFactory.openSession(); // 打开一个新的Session Transaction tx = session.beginTransaction(); // 开启事务 session.save(user); tx.commit(); // 提交事务 session.close(); // 关闭Session,释放资源 } @Test public void testGet() throws Exception { Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); User user = (User) session.get(User.class, 1); // 获取? System.out.println(user.getId()); System.out.println(user.getName()); System.out.println(user.getDesc()); System.out.println(user.getPhoto()); OutputStream out = new FileOutputStream("c:/copy.png"); out.write(user.getPhoto()); out.close(); tx.commit(); session.close(); }}
测试,通过,大发!!!
- Hibernate框架基础——映射普通属性
- Hibernate框架基础——映射主键属性
- Hibernate框架基础——映射集合属性
- hibernate普通属性映射
- Hibernate框架基础——cascade属性
- Hibernate框架基础——一对多关联关系映射
- 基础:Hibernate映射引用属性
- Hibernate映射普通属性、Hibernate中的各种类型
- Hibernate基础 ( 2 ) 集合属性映射
- Hibernate基础 ( 3 ) 组件属性映射
- Hibernate框架基础——多对多关联关系映射
- Hibernate框架基础——Hibernate入门
- Hibernate——映射关系中的属性详解
- Hibernate(三)——框架中的关系映射
- Hibernate(三)——框架中的关系映射
- SSH框架之Hibernate(1)——映射关系
- Hibernate(三)——框架中的关系映射
- Hibernate(三)——框架中的关系映射
- 进林科大ACM的考核(3个程序设计)
- 设计模式之策略模式
- linux之一个简单的shell程序
- C语言的不足
- RecyclerView实现瀑布流布局
- Hibernate框架基础——映射普通属性
- 关于程序的边界检查
- 每天一点小姿势——异常死机怎么办(1)
- 梯度下降法 gradient descent
- effective stl 第45条:正确区分count/find/binary_search/lower_bound/upper_bound/equal_range
- settimeout()和setinterval区别
- SwipeRefreshLayout嵌套ScrollView包裹复杂头布局和RecyclerView
- Ranges
- 海量数据查找一个数是否存在