终于考完试了,全过,不错!!!接下来我们继续学习hibernate框架,上次我们初识了hibernate框架,并学习了其基本的一些配置类,那么这次我们继续学习,之前写的文章大都有些长,所以博主之后会将这些知识点拆成不同的部分来写
hibernate中的实体规则
1.实体类创建的注意事项:
前面了解到我们的hibernate框架是类与数据库表间映射而成的,类即表,表即类,hibernate框架可以根据类来在数据库中创建相对应的表,也可以将数据库中的表与程序中的类相对应,我们将这样的与数据库中表建立了映射关系的类称之为持久化类,其实你可以简单的理解为持久化类就是一个Java类有了一个映射文件与数据库的表建立了关系。那么我们在编写持久化类的的时候应该注意那些呢
- 持久化类提供无参数构造:因为在hibernate的底层需要使用反射来生成类的实例化(即调用无参构造来实例化,可以去看看Java中反射机制)
- 成员变量私有,提供共有get/set方法访问.需提供属性:这个不需要我解释了吧(因为hibernate底层会将查询到的数据进行封装)
- 持久化类中的属性,应尽量使用包装类型:因为包装类和基本类型的默认值不同,包装类的类型语义表述更清晰而基本数据类型不容易描述。举个例子:
假设表中有学生考试的期末成绩,倘若使用double类型,那么如果这个学生忘记考试即缺考,那么系统会将默认值0存入数据库中,如果这个学生真的是考了0分(这nm也是天才),那么也会向系统存入0,那么这个0就有了多重含义,而如果使用包装类类型就会避免以上情况,如果使用的是Double类型,缺考的学生成绩就会存入null,而考了0分的学生成绩就是0.
- 持久化类需要提供oid.与数据库中的主键列对应:因为 Hibernate 中需要通过这个唯一标识OID区分在内存中是否是同一个持久化类。在Java中通过地址区分是否是同一个对象的,在关系型数据库的表中是通过主键区分是否为同一条记录。那么hibernate就是通过这个OID来进行区分的。hibernate是不允许在内存中出现两个OID相同的持久化对象的。
- 不要用final修饰class:hibernate使用cglib代理生成代理对象.代理对象是继承被代理对象.如果被final修饰.将无法生成代理.
2.Hibernate主键
自然主键(少见):表的业务列中,有某业务列符合,必须有,并且不重复的特征时,该列可以作为主键使用.
例如在 customer 表中, 如果把 name 字段作为主键,其前提条件必须是:每个客户的姓名不允许为 null, 不允许客户重名, 并且不允许修改客户姓名。 尽管这也是可行的, 但是不能满足不断变化的业务需求,一旦出现了允许客户重名的业务需求, 就必须修改数据模型, 重新定义表的主键, 这给数据库的维护增加了难度。
代理主键(常见):表的业务列中,没有某业务列符合,必须有,并且不重复的特征时,创建一个没有业务意义的列作为主键
3.主键生成策略
代理主键:
identity : 主键自增.由数据库来维护主键值.录入时不需要指定主键.
sequence: Oracle中的主键生成策略.
increment(了解): 主键自增.由hibernate来维护.每次插入前会先查询表中id最大值.+1作为新主键值.
hilo(了解): 高低位算法.主键自增.由hibernate来维护.开发时不使用.
native:hilo+sequence+identity 自动三选一策略.
uuid: 产生随机字符串作为主键. 主键类型必须为string 类型.
自然主键:
assigned:自然主键生成策略. hibernate不会管理主键值.由开发人员自己录入.
4.测试主键生成策略
来看看我这个Customer对象的映射文件
<?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="yp.itcast.domain">
<class name="Customer" table="cst_customer">
<id name="cust_id" column="cust_id">
<!-- generator:主键生成策略 ,就是每条记录录入时,主键的生成策略(7个)
identity:主键自增.由数据库来维护主键值,录入时不需要指定主键
increment(了解):主键自增,由hibernate来维护,每次插入前会先查询表中id最大值。+1作为新主键值.
注意:在正式开发中不能使用increment,存在线程安全问题
sequence:Oracle中的主键生成策略
hilo:高低位算法(数据库中主键自增使用的就是这种算法)。:主键自增,由hibernate来维护(开发时不使用)
native: hilo+sequence+identity(自动三选一策略)(方便,省的换库的时候再改)
uuid:产生随机字符串作为主键。(前提:主键类型必须为String类型)
assigned:自然主键生成策略。hibernate不会管理主键值,由开发人员自己录入
-->
<generator class="native"></generator>
</id>
<property name="cust_name" column="cust_name">
<!-- <column name="cust_name" sql-type="varchar"></column> -->
</property>
<property name="cust_source" column="cust_source"></property>
<property name="cust_industry" column="cust_industry"></property>
<property name="cust_level" column="cust_level"></property>
<property name="cust_linkman" column="cust_linkman"></property>
<property name="cust_phone" column="cust_phone"></property>
<property name="cust_mobile" column="cust_mobile"></property>
</class>
</hibernate-mapping>
可以写下面这段代码来测试
public class Demo {
@Test
public void fun1(){
//1:获得session
Session session = HibernateUtils.openSession();
//2:控制事务
Transaction tx = session.beginTransaction();
//3:执行操作
Customer c = new Customer();
c.setCust_name("联想");
session.save(c);
//4:提交事务,关闭资源
tx.commit();
session.close();
}
}