hibernate.cfg.xml的常用属性配置。
在进行项目开发时,建议选择一款数据源包来托管数据库连接。hibernate包中有一组包叫c3p0,它是一个开源的JDBC连接池,实现了数据源与JNDI绑定,支持JDBC3规范和JDBC2标准拓展。
使用c3p0需要进行两步操作,首先将jar包导入到项目中,然后在hibernate.cfg.xml中对其进行配置。
jar包在/hibernate-release-4.3.11.Final/lib/optional/c3p0中存放。
导入后,配置hibernate.cfg.xml文件。
<!-- 最大连接数 --> <property name="hibernate.c3p0.max_size">20</property> <!-- 最小连接数 --> <property name="hibernate.c3p0.min_size">5</property> <!-- 获得连接的超时时间,如果超过这个时间,会抛出异常,单位毫秒 --> <property name="hibernate.c3p0.timeout">120</property> <!-- 最大的PreparedStatement的数量 --> <property name="hibernate.c3p0.max_statements">100</property> <!-- 每隔120秒检查连接池里的空闲连接 ,单位是秒--> <property name="hibernate.c3p0.idle_test_period">120</property> <!-- 当连接池里面的连接用完的时候,C3P0一下获取的新的连接数 --> <property name="hibernate.c3p0.acquire_increment">2</property>
测试一下是否使用了c3p0数据源,打印一个connection对象的类型。
@Test public void test() { session.doWork(new Work() { @Override public void execute(Connection connection) throws SQLException { System.out.println(connection); /** * output:com.mchange.v2.c3p0.impl.NewProxyConnection@68746f22 * */ } }); }
hibernate中还有两个常用属性,getch_size和batch_size(oracle、sqlserver支持,mysql不支持)。
getch_size是设定JDBC的statement每次从数据库中取出多少条数据。
batch_size是对数据库进行批量删除、批量更新和批量插入的时候批次的大小。
*.hbm.xml的常用属性配置。
之前的代码调用的update或者insert时,总是会更新或者插入全部的字段,但是通过dynamic_insert和dynamic_update属性,可以插入或更新实体类设置的属性。
<?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> <!-- update之前先进行select,对象与数据库中的记录一致,则不执行update --> <class name="cn.net.bysoft.model.User" table="S_USER" select-before-update="true" dynamic-update="true"> <id name="id" type="integer" column="ID"> <!-- 指定主键的生成方式,native是使用数据库本地的方式 --> <generator class="native"></generator> </id> <property name="name" type="string" column="NAME"></property> <property name="birthday" type="timestamp" column="BIRTHDAY"></property> </class> </hibernate-mapping>
@Test public void testDynamicUpdate() { User user = (User)session.get(User.class, 2); user.setName("Kobe"); }
设置了dynamic_update属性等于true后,flush时update的只是修改过的字段,而不再是全部字段。dynamic_insert同理。
id节点中,生成数据库id的方式,常用的有四种,分别是increment、identity、sequence、hilo和native。
<id name="id" type="integer" column="ID"> <!-- 指定主键的生成方式,native是使用数据库本地的方式 --> <generator class="native"></generator> </id>
他们的含义分别是:
属性名 |
说明 |
increment |
读取映射的数据表中id的最大值+1作为id值,但线程不安全,建议只在测试时使用。 |
identity |
使用数据库的自增功能,但数据库必须支持自增列。 |
sequence |
使用数据库的序列功能,但数据库必须支持序列。 |
hilo |
由hibernate使用高低算法生成,不依赖底层的数据库。 |
native |
使用数据库本地的方式生成id,数据库可以自增就自增,可以序列就序列,若都不支持则调用hilo生成id值。 |
id节点过后是property节点,property节点有一个属性叫access,它的默认值是property,意思是在取值赋值时使用类的get/set方法,设置成field的话,取值赋值将采用反射的方式。
还有一个属性是type,该属性可以设置实体类属性的类型,类型有三个种类,分别是Java类型、数据库类型和hibernate类型,hibernate类型是Java类型和数据库类型的适配器。
Java类型 |
hibernate类型 |
标准数据库类型 |
java.lang.Interger/int |
integer/int |
INTEGER |
java.lang.Long/long |
long |
BIGINT |
java.lang.Short/short |
short |
SMALLINT |
java.lang.Byte/byte |
byte |
TINYINT |
java.lang.Float/float |
float |
FLOAT |
java.lang.Double/double |
double |
DOUBLE |
java.math.BigDecimal |
big_decimal |
NUMERIC |
java.lang.Charatcter/Java.lang.String/char |
character |
CHAR(1) |
java.lang.String |
string |
VARCHAR |
java.lang.Boolean/boolean |
boolean/yes_no/true_false |
BIT |
java.util.Data/java.sql.Data |
date |
DATE |
java.util.Data/java.util.Timestamp |
timestamp |
TIMESTAMP |
java.util.Calendar |
calendar |
TIMESTAMP |
java.util.Calendar | calendar_date |
Date |
byte[] |
binary |
BLOB |
java.util.String |
text |
TEXT |
java.sql.Blob |
blob |
BLOB |
java.sql.Clob |
clob |
CLOB |
剩下的一些常用属性是:
属性名 |
说明 |
unique |
设置唯一标识字段,该字段的值不能重复。 |
update |
该自动的值是否可以被修改。 |
index |
设置该字段为索引。 |
length |
设置该字段的长度。 |
formula | 设置一个SQL表达式生成值。 |
scale |
保留几位小数位数。 |
写一个测试用例使用这些属性:
<?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> <!-- update之前先进行select,对象与数据库中的记录一致,则不执行update --> <class name="cn.net.bysoft.model.Employee" table="S_EMPLOYEE" dynamic-update="true"> <id name="id" type="integer" column="ID"> <!-- 指定主键的生成方式,native是使用数据库本地的方式 --> <generator class="native"></generator> </id> <!-- 设置了unique属性为true。身份证不能重复 --> <!-- 设置了length属性为18。身份证长度为18位 --> <property name="idcard" type="string" column="IDCARD" unique="true" length="18"></property> <property name="firstName" type="string" column="FIRSTNAME"></property> <property name="lastName" type="string" column="LASTNAME"></property> <!-- 设置了formula属性为fullname使用firstName.lastName来初始化值。 --> <property name="fullName" type="string" column="FULLNAME" formula="(SELECT CONCAT(e.FIRSTNAME, '.', e.LASTNAME) FROM S_EMPLOYEE e WHERE e.ID = id)"></property> <property name="birthday" type="timestamp" column="BIRTHDAY"></property> <!-- 保留两位小数 --> <property name="salary" type="double" column="SALARY" scale="2"></property> </class> </hibernate-mapping>
通过该属性创建表:
身份证字段长度通过length属性设置了长度,保存一条数据,在查询:
@Test public void test() { Employee employee = new Employee(); employee.setFirstName("Jack"); employee.setLastName("Sparrow"); employee.setIdcard("123456789123456789"); employee.setBirthday(new Date()); employee.setSalary(20000.0000D); // 保存。 session.save(employee); }
@Test public void test() { Employee employee = (Employee) session.get(Employee.class, 1); System.out.println(employee.getFullName()); }
观察打印的sql语句,会发现fullname是通过子查询获得结果后,复制给了fullname字段,而数据库本身并没有fullname字段。
最后,测试一下CLOB与BLOB两个类型的数据的操作,在Employee类中加入一个简介字段和照片字段。
@Test public void test() throws IOException { Employee employee = (Employee) session.get(Employee.class, 1); // 创建一个Clob对象。 String strContent = "He's a Pirate."; Clob content = Hibernate.getLobCreator(session).createClob(strContent); employee.setContent(content); // 定位图片。 InputStream stream = new FileInputStream("1.jpg"); // 创建一个Blob对象。 Blob photo = Hibernate.getLobCreator(session).createBlob(stream, stream.available()); employee.setPhoto(photo); }
通过Hibernate创建Clob对象和Blob对象,创建完成后更新数据库中的数据,结果如下:
可以看到数据库中已经保存了CONTENT和PHOTO两个字段的数据,建议使用CLOB不如直接使用string方便。读取这两个字段的方式如下:
@Test public void testGetBlobAndClob() throws IOException, SQLException { Employee employee = (Employee) session.get(Employee.class, 1); // 输入照片的文件大小。 Blob photo = employee.getPhoto(); InputStream stream = photo.getBinaryStream(); System.out.println(stream.available()); // 输入简介。 Clob content = employee.getContent(); Reader reader = content.getCharacterStream();// 得到流 BufferedReader br = new BufferedReader(reader); String strContent = br.readLine(); StringBuffer sb = new StringBuffer(); while (strContent != null) {// 执行循环将字符串全部取出付值给StringBuffer由StringBuffer转成STRING sb.append(strContent); strContent = br.readLine(); } strContent = sb.toString(); System.out.println(strContent); }
结果如图,以上就是hibernate中配置文件里的常用属性。