Hibernate学习2之继承映射与C3P0连接池
一、继承映射的需要
关系数据库的表之间不存在继承关系,
但为了将面向对象中的继承关系映射到关系数据库中,
可以使用以下三种继承映射策略:
-每个继承层次一张表
-每个具体类一张表
-每个类一张表。
二、对比
--每个继承层次一张表:
(优点)最简单、执行效率最高(因为无需进行任何关联操作)
(缺点)存在冗余字段;在数据表中需要加入额外的区分各个类的字段;
同时不允许为子类成员属性对应的字段定义为not null约束。
--每个具体类一张表:
(优点)数据结构清晰,且可以对子类成员属性映射的字段定义not null 约束
(缺点)子表的主键不能重复,不能使用数据库的自增方式生成主键
--每个子类一张表:
(优点)数据结构层次清晰,没有冗余,且可以对子类的成员属性映射的字段定义not null约束
(缺点)类的继承层次比较多时,需要关联的表也越多查询性能不如每个继承构成一张表
三、c3p0连接池(参考:http://baike.baidu.com/view/1528732.htm?fr=aladdin)
--连接池的需要:直接向数据库申请、释放连接时要降低性能的,因为不适用连接池,
那么每一次数据访问请求都必须经历创建数据库连接、打开数据库、存取数据和关闭数据库连接等步骤,
而连接并打开数据库是一件即消耗资源又费时的工作,当频繁发生数据库操作时,就会导致系统性能的急剧下降,
所以需要连接池这个代理。
--思想:将数据库连接作为对象存储在一个Vector对象中,
一旦数据库连接建立后,不同的数据库访问请求就可以共享这些连接。
--数据库连接池的主要操作:
1.建立数据库连接池对象(服务器启动)
2.按照事先指定的参数创建初始数量的数据库连接(即:空闲连接数)
3.对于一个数据库访问请求,直接从连接池中得到一个连接。如果数据库连接池对象中没有空闲的连接,而且连接数没有达到最大(即:最大活跃连接数),创建一个新的数据库连接。
4.存取数据库。
5.关闭数据库,释放所有数据连接(此时的关闭数据库连接,并非真正关闭,而是将其放入空闲队列中。如实际空闲连接数大于初始空闲连接数则释放连接)。
6.释放数据库连接池对象(服务器停止、维护期间,释放数据库连接池对象,并释放所有连接)。
四、实验步骤(继承映射+C3P0)
①创建数据库连接
②新建Java项目
③为项目添加Hibernate支持
④创建持久化类
⑤为持久化类创建映射文件
⑥修改hibernate.cfg.xml,在其中配置C3P0以及其它一些属性
⑦创建工具类,获取session
⑧编写测试类,查看运行结果
五、核心代码
hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <!-- Generated by MyEclipse Hibernate Tools. --> <hibernate-configuration> <session-factory> <!-- 数据库连接设置 --> <!-- 配置数据库JDBC驱动 --> <property name="hibernate.connection.driver_class"> com.mysql.jdbc.Driver</property> <!-- 配置数据库连接URL --> <property name="hibernate.connection.url"> <![CDATA[jdbc:mysql://localhost:3306/javaii-8?useUnicode=true&characterEncoding=utf8]]> </property> <!-- 配置数据库用户名 --> <property name="hibernate.connection.username"> root</property> <!-- 配置数据库密码 --> <property name="hibernate.connection.password"> 1</property> <!-- 指定使用c3p0连接池 --> <property name="connection.provider_class"> org.hibernate.connection.C3P0ConnectionProvider</property> <!-- 连接池中保留的最大连接数 --> <property name="c3p0.max_size">100</property> <!-- 连接池中保留的最小连接数 --> <property name="c3p0.min_size">10</property> <!-- 获取连接的超时时间,单位是毫秒 --> <property name="c3p0.timeout">500</property> <!-- 最大的PrepareStatement的数量 --> <property name="c3p0.max_statements">100</property> <!-- 配置数据库方言 --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 根据持久化类自动在数据库中建表 --> <property name="hbm2ddl.auto">update</property> <!-- 配置session的运行环境,在web中使用jta,在java application中使用thread --> <property name="current_session_context_class">thread</property> <!-- 输出运行时生成的SQL语句 ps:在控制台显示 --> <property name="show_sql">true</property> <!-- 列出所有的映射文件 --> <mapping resource="sise/ye/domain/Person.hbm.xml"/> </session-factory> </hibernate-configuration>
Person.java/Studetn.java/Worker.java
package sise.ye.domain; /* * 项目名称:javaII-8 * 包名:sise.ye.domain * 类:Person.java * 创建人:叶晓东 * 创建时间:2014.4.17 * 描述:该类为持久化类,同时为Student和Worker持久化类的父类 * 备注: * @version 1.0 * @param id 编号 * @param name 姓名 * @param sex 姓名 * @param age 年龄 */ public class Person { private int id; private String name; private String sex; private int age; //======构造方法====== public Person(){} public Person(String name,String sex,int age){ this.name=name; this.sex=sex; this.age=age; } //======set/get===== 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 String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } package sise.ye.domain; /* * 项目名称:javaII-8 * 包名:sise.ye.domain * 类名:Student.java * 创建人:叶晓东 * 创建时间:2014.4.17 * 描述:持久化类,继承Person类 * 备注: * @version 1.0 * @param sno * @param school */ public class Student extends Person{ private String sno; private String school; //======构造方法====== public Student(){} public Student(String name,String sex,int age,String sno,String school){ super(name,sex,age); this.sno=sno; this.school=school; } //====set/get====== public String getSno() { return sno; } public void setSno(String sno) { this.sno = sno; } public String getSchool() { return school; } public void setSchool(String school) { this.school = school; } } package sise.ye.domain; /* * 项目名称:javaII-8 * 包名:sise.ye.domain * 类名:Worker.java * 创建人:叶晓东 * 创建时间:2014.4.17 * 描述:持久化类,继承Person类 * 备注: * @version 1.0 * @param no * @param salary */ public class Worker extends Person{ private String no; private double salary; //======构造方法===== public Worker(){} public Worker(String name,String sex,int age,String no,double salary){ super(name,sex,age); this.no=no; this.salary=salary; } //======set/get===== public String getNo() { return no; } public void setNo(String no) { this.no = no; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } }
Person.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="sise.ye.domain"> <!-- name指定持久化类的类名,table指定数据表的表名 ,discriminator-value--> <class name="Person" table="person" discriminator-value="person"> <!-- 将Person类中的id属性映射为数据表person中的主键id --> <id name="id" type="int" column="id"> <generator class="native"/> </id> <!-- 设置鉴别字段名称 --> <discriminator column="type" type="string" length="15"/> <!-- 从父类Person继承下来的共同属性 --> <property name="name" type="string" column="name" length="20"/> <property name="sex" type="string" column="sex" length="2"/> <property name="age" type="int" column="age"/> <!-- 子类Student新增的属性 --> <subclass name="Student" discriminator-value="student"> <property name="sno" type="string" length="10"/> <property name="school" type="string" length="50"/> </subclass> <!-- 子类Worker新增的属性 --> <subclass name="Worker" discriminator-value="Worker"> <property name="no" column="wno" type="string" length="10"/> <property name="salary" column="salary" type="double"/> </subclass> </class> </hibernate-mapping>
六、代码分析(其他映射讲解http://download.csdn.net/detail/yy228313/7318833)
继承映射的子类的映射文件不用写,只需在父类中添加<subclass>元素,name对应持久化类,discriminiator-value属性设置表名。
在<subclass>元素中设置子类的属性使用<property>元素,name属性设置持久化类对应的属性,column设置表的字段,type设置字段类型(PS:string中的s是小写)
C3P0需要导入架包,下载http://download.csdn.net/detail/yy228313/7318943
在Hibernate的配置文件hibernate.cfg.xml中添加
<!-- 指定使用c3p0连接池 --> <property name="connection.provider_class"> org.hibernate.connection.C3P0ConnectionProvider</property> <!-- 连接池中保留的最大连接数 --> <property name="c3p0.max_size">100</property> <!-- 连接池中保留的最小连接数 --> <property name="c3p0.min_size">10</property> <!-- 获取连接的超时时间,单位是毫秒 --> <property name="c3p0.timeout">500</property> <!-- 最大的PrepareStatement的数量 --> <property name="c3p0.max_statements">100</property>
七、代码下载:
http://download.csdn.net/detail/yy228313/7318903