学习hibernate(四) -- hibernate常用配置

    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");
    }

学习hibernate(四) -- hibernate常用配置_第1张图片

    设置了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>

    通过该属性创建表:

学习hibernate(四) -- hibernate常用配置_第2张图片

    身份证字段长度通过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());
    }

学习hibernate(四) -- hibernate常用配置_第3张图片

    观察打印的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(四) -- hibernate常用配置_第4张图片

    结果如图,以上就是hibernate中配置文件里的常用属性。

你可能感兴趣的:(学习hibernate(四) -- hibernate常用配置)