SS5.1_Hibernate_IdStrategyXML ~ SS5.5_Hibernate_IdStrategyXML 主键生成策略 XML映射文件的方式

来源:互联网 发布:轰炸机软件 编辑:程序博客网 时间:2024/06/07 03:35

我们接下来要创建的项目结构:


主键的生成策略第1种情况:整型字段sid主键的生成策略<generator class="assigned"/>;

创建学生实体:

package net.nw.vo;
public class Student {
private int sid;
private String sname;

public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
}

创建对象 - 关系映射文件, 注意整型字段sid主键的生成策略<generator class="assigned"/>:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- hibernate映射,包名对应java的包名 -->
<hibernate-mapping package="net.nw.vo">
    <!-- 指定对实体类net.nw.vo.Student与数据库关系表student的映射关系,当两者相同时,可以不指定table -->
    <class name="net.nw.vo.Student" table="student">
         <!-- id指定实体属性(name="sid")与关系表主键(column="sid")之间映射关系 -->
         <id name="sid" column="sid" type="int">
          <generator class="assigned"/>
         </id>

         <!-- 实体属性与关系表字段之间映射关系,如果两者名字相同,column可以不写 -->
         <property name="sname" column="sname" type="string"></property>
    </class>
</hibernate-mapping>

创建数据库连接配置文件和注册对象 - 关系资源映射文件:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>
    <session-factory>
   <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
 <property name="connection.url">jdbc:mysql://localhost:3306/testdb</property>
 <property name="connection.username">root</property>
 <property name="connection.password">123456</property>
 <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
 <property name="show_sql">true</property>
 <property name="hbm2ddl.auto">update</property>
 <property name="current_session_context_class">thread</property>
 <mapping resource="net/nw/vo/Student.hbm.xml" />
    </session-factory>
</hibernate-configuration>

创建日志配置文件log4j.properties:

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=warn, stdout

#log4j.logger.org.hibernate=info
#log4j.logger.org.hibernate=debug

### log HQL query parser activity
#log4j.logger.org.hibernate.hql.ast.AST=debug

### log just the SQL
log4j.logger.org.hibernate.SQL=debug

### log JDBC bind parameters ###
log4j.logger.org.hibernate.type=info
#log4j.logger.org.hibernate.type=debug

### log schema export/update ###
log4j.logger.org.hibernate.tool.hbm2ddl=debug

### log HQL parse trees
#log4j.logger.org.hibernate.hql=debug

### log cache activity ###
#log4j.logger.org.hibernate.cache=debug

### log transaction activity
log4j.logger.org.hibernate.transaction=debug

### log JDBC resource acquisition
#log4j.logger.org.hibernate.jdbc=debug

### enable the following line if you want to track down connection ###
### leakages when using DriverManagerConnectionProvider ###
#log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace

创建单元测试文件:

package net.nw.vo;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import junit.framework.TestCase;
public class TestStudent extends TestCase {
private static SessionFactory sessionFactory ;
@Override
protected void setUp() throws Exception {
System.out.println("setUp()...");
sessionFactory = new Configuration().configure().buildSessionFactory();
}
@Override
protected void tearDown() throws Exception {
System.out.println("tearDown()...");
sessionFactory.close();
}
public void testSave(){
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
try{
Student s = new Student();
s.setSname("wangwu");
session.save(s);
tx.commit();

}catch(Exception ex){
tx.rollback();
ex.printStackTrace();
}
}
}

导入单元测试jar包:

项目上右键单击 ------》Build Path ------》Configure Build Path ... ------》Add Library ... ------》JUnit ------》JUnit library version: JUnit 4  ------》OK


导入mysql-connector-java-5.1.40-bin.jar的jar包:

项目上右键单击 ------》Build Path ------》Configure Build Path ... ------》Add External JARS ... ------》/root/mysql-connector-java-5.1.40-bin/mysql-connector-java-5.1.40-bin.jar ------》OK


运行单元测试方法testSave(),注意控制台输出的创建student表结构的SQL脚本(没有自增属性哦!):

运行单元测试之前必需手动地把testdb数据库中的学生表删掉:drop table student;

用鼠标一直展开到TestStudent单元测试类内部的所有方法这一层 ------》右键单击testSave() void ------》Run As ------》Junit Test

控制台会输出如下信息:

setUp()...
23:57:10,658  INFO TransactionFactoryFactory:59 - Using default transaction strategy (direct JDBC transactions)
23:57:10,664  INFO TransactionManagerLookupFactory:80 - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
23:57:10,877  INFO SchemaUpdate:155 - Running hbm2ddl schema update
23:57:10,877  INFO SchemaUpdate:167 - fetching database metadata
23:57:10,878  INFO SchemaUpdate:179 - updating schema
23:57:10,885  INFO DatabaseMetadata:119 - table not found: student
23:57:10,886  INFO DatabaseMetadata:119 - table not found: student
23:57:10,887 DEBUG SchemaUpdate:203 - create table student (sid integer not null, sname varchar(255), primary key (sid))
23:57:10,961  INFO SchemaUpdate:217 - schema update complete
23:57:11,035 DEBUG JDBCTransaction:82 - begin
23:57:11,035 DEBUG JDBCTransaction:87 - current autocommit status: false
23:57:11,061 DEBUG JDBCTransaction:134 - commit
23:57:11,067 DEBUG SQL:111 - insert into student (sname, sid) values (?, ?)
Hibernate: insert into student (sname, sid) values (?, ?)
23:57:11,077 DEBUG JDBCTransaction:147 - committed JDBC Connection
tearDown()...

注意:控制台输出信息中创建表的脚本中没有自动生成auto_increment,故student表没有自增主键;

 再接合保存记录的实现代码:

Student s = new Student();

s.setSname("wangwu");

session.save(s);

tx.commit();

java代码中我们没有手动添加主键值,上面向MySQL数据库中写入第1条记录没出现任何问题,但是写入第2条记录就会抛出错误信息;

把上面的wangwu改成zhaoliu再次提交单元测方法控制台会输出如下信息:

setUp()...
00:11:00,323  INFO TransactionFactoryFactory:59 - Using default transaction strategy (direct JDBC transactions)
00:11:00,329  INFO TransactionManagerLookupFactory:80 - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
00:11:00,507  INFO SchemaUpdate:155 - Running hbm2ddl schema update
00:11:00,507  INFO SchemaUpdate:167 - fetching database metadata
00:11:00,509  INFO SchemaUpdate:179 - updating schema
00:11:00,528  INFO TableMetadata:65 - table found: testdb.student
00:11:00,528  INFO TableMetadata:66 - columns: [sid, sname]
00:11:00,529  INFO TableMetadata:68 - foreign keys: []
00:11:00,529  INFO TableMetadata:69 - indexes: [primary]
00:11:00,529  INFO SchemaUpdate:217 - schema update complete
00:11:00,655 DEBUG JDBCTransaction:82 - begin
00:11:00,655 DEBUG JDBCTransaction:87 - current autocommit status: false
00:11:00,664 DEBUG JDBCTransaction:134 - commit
00:11:00,668 DEBUG SQL:111 - insert into student (sname, sid) values (?, ?)
Hibernate: insert into student (sname, sid) values (?, ?)
00:11:00,689  WARN JDBCExceptionReporter:100 - SQL Error: 1062, SQLState: 23000
00:11:00,689 ERROR JDBCExceptionReporter:101 - Duplicate entry '0' for key 'PRIMARY'
00:11:00,690 ERROR AbstractFlushingEventListener:324 - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update

...  ...

...  ...

解决办法,我们可以手动创建带自增主键的student表即可:

DROP TABLE student;

CREATE TABLE `student` (
  `sid` int(11) NOT NULL AUTO_INCREMENT,
  `sname` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`sid`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;


主键的生成策略第2种情况:字符串字段sid主键的生成策略<generator class="assigned"/>;

 第1步: 修改学生实体类net.nw.vo.Student中主键属性的类型

package net.nw.vo;
public class Student {
private String sid;
private String sname;

public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}

public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
}

 第2步:修改主键的数据类型(与实体类中定义的sid类型要一致),注意蓝色字体标识的部分:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- hibernate映射,包名对应java的包名 -->
<hibernate-mapping package="net.nw.vo">
    <!-- 指定对实体类net.nw.vo.Student与数据库关系表student的映射关系,当两者相同时,可以不指定table -->
    <class name="net.nw.vo.Student" table="student">
         <!-- id指定实体属性(name="sid")与关系表主键(column="sid")之间映射关系 -->
         <id name="sid" column="sid"
type="string">
          <generator class="assigned"/>
         </id>

         <!-- 实体属性与关系表字段之间映射关系,如果两者名字相同,column可以不写 -->
         <property name="sname" column="sname" type="string"></property>
    </class>
</hibernate-mapping>

假如您没有设置主键值

Student s = new Student();
//s.setSid("s100");
s.setSname("zhaoliu");
session.save(s);
tx.commit();

控制台输出的信息会抛出如下错误信息:

org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): net.nw.vo.Student

解决办法:必须给主键字段赋值,注意红色字体标识的部分:

package net.nw.vo;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import junit.framework.TestCase;
public class TestStudent extends TestCase {
private static SessionFactory sessionFactory ;
@Override
protected void setUp() throws Exception {
System.out.println("setUp()...");
sessionFactory = new Configuration().configure().buildSessionFactory();
}
@Override
protected void tearDown() throws Exception {
System.out.println("tearDown()...");
sessionFactory.close();
}
public void testSave(){
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
try{
Student s = new Student();
s.setSid("s100");
s.setSname("zhaoliu");
session.save(s);
tx.commit();

}catch(Exception ex){
tx.rollback();
ex.printStackTrace();
}
}
}

运行单元测试之前必需手动地把testdb数据库中的学生表删掉:drop table student;

控制台输出的信息会抛出如下信息:

setUp()...
00:55:12,707  INFO TransactionFactoryFactory:59 - Using default transaction strategy (direct JDBC transactions)
00:55:12,709  INFO TransactionManagerLookupFactory:80 - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
00:55:12,901  INFO SchemaUpdate:155 - Running hbm2ddl schema update
00:55:12,901  INFO SchemaUpdate:167 - fetching database metadata
00:55:12,903  INFO SchemaUpdate:179 - updating schema
00:55:12,909  INFO DatabaseMetadata:119 - table not found: student
00:55:12,912  INFO DatabaseMetadata:119 - table not found: student
00:55:12,914 DEBUG SchemaUpdate:203 -
create table student (sid varchar(255) not null, sname varchar(255), primary key (sid))
00:55:12,925  INFO SchemaUpdate:217 - schema update complete
00:55:13,011 DEBUG JDBCTransaction:82 - begin
00:55:13,012 DEBUG JDBCTransaction:87 - current autocommit status: false
00:55:13,045 DEBUG JDBCTransaction:134 - commit
00:55:13,049 DEBUG SQL:111 - insert into student (sname, sid) values (?, ?)
Hibernate: insert into student (sname, sid) values (?, ?)
00:55:13,060 DEBUG JDBCTransaction:147 - committed JDBC Connection
tearDown()...


MySQL-connector-Java-5.1.40.zip包:http://download.csdn.net/detail/zhengzizhi/9747510

SS5.1_Hibernate_Hibernate_IdStrategyXML.zip源码下载地址:http://download.csdn.net/detail/zhengzizhi/9749812



第1步:必需手动地把testdb数据库中的学生表删掉 drop table student;

第2步:必需手动地在testdb数据库中的创建hi_value表 create table hi_value(next_hi integer not null);

第3步:修改对象 - 关系映射文件Student.hbm.xml,注意红色字体标识的部分;

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- hibernate映射,包名对应java的包名 -->
<hibernate-mapping package="net.nw.vo">
    <!-- 指定对实体类net.nw.vo.Student与数据库关系表student的映射关系,当两者相同时,可以不指定table -->
    <class name="net.nw.vo.Student" table="student">
         <!-- id指定实体属性(name="sid")与关系表主键(column="sid")之间映射关系 -->
         <id name="sid" column="sid" type="int">

          <generator class="hilo">
      <param name="table">hi_value</param>
      <param name="column">next_hi</param>
      <param name="max_lo">100</param>
  </generator>

         </id>
         <!-- 实体属性与关系表字段之间映射关系,如果两者名字相同,column可以不写 -->
         <property name="sname" column="sname" type="string"></property>
    </class>
</hibernate-mapping>

第4步:修改学生实体类主键的类型l,注意红色字体标识的部分;

package net.nw.vo;
public class Student {
private int sid;
private String sname;

public int getSid() {
return sid;
}
public void setSid(intsid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
}

第5步:修改单元测试方法 ------ 去掉主键赋值;

package net.nw.vo;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import junit.framework.TestCase;
public class TestStudent extends TestCase {
private static SessionFactory sessionFactory ;
@Override
protected void setUp() throws Exception {
System.out.println("setUp()...");
sessionFactory = new Configuration().configure().buildSessionFactory();
}
@Override
protected void tearDown() throws Exception {
System.out.println("tearDown()...");
sessionFactory.close();
}
public void testSave(){
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
try{
Student s = new Student();
s.setSname("zhangsan");
session.save(s);
tx.commit();

}catch(Exception ex){
tx.rollback();
ex.printStackTrace();
}
}
}

第6步:运行单元测试,控制台会抛出如下错误信息;

org.hibernate.id.IdentifierGenerationException: could not read a hi value - you need to populate the table: hi_value

解决办法:必需手动添加等差等于1的记录------ insert into hi_value(next_hi) values(1);  再次运行单元测试控制台会成功地输出如下信息

setUp()...
14:38:22,104  INFO TransactionFactoryFactory:59 - Using default transaction strategy (direct JDBC transactions)
14:38:22,106  INFO TransactionManagerLookupFactory:80 - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
14:38:22,284  INFO SchemaUpdate:155 - Running hbm2ddl schema update
14:38:22,284  INFO SchemaUpdate:167 - fetching database metadata
14:38:22,285  INFO SchemaUpdate:179 - updating schema
14:38:22,301  INFO TableMetadata:65 - table found: testdb.student
14:38:22,302  INFO TableMetadata:66 - columns: [sid, sname]
14:38:22,302  INFO TableMetadata:68 - foreign keys: []
14:38:22,302  INFO TableMetadata:69 - indexes: [primary]
14:38:22,309  INFO TableMetadata:65 - table found: testdb.hi_value
14:38:22,309  INFO TableMetadata:66 - columns: [next_hi]
14:38:22,309  INFO TableMetadata:68 - foreign keys: []
14:38:22,311  INFO TableMetadata:69 - indexes: []
14:38:22,311  INFO SchemaUpdate:217 - schema update complete
14:38:22,432 DEBUG JDBCTransaction:82 - begin
14:38:22,432 DEBUG JDBCTransaction:87 - current autocommit status: false
14:38:22,441 DEBUG SQL:111 - select next_hi from hi_value for update
14:38:22,451 DEBUG SQL:111 - update hi_value set next_hi = ? where next_hi = ?
14:38:22,458 DEBUG JDBCTransaction:134 - commit
14:38:22,461 DEBUG SQL:111 - insert into student (sname, sid) values (?, ?)
Hibernate: insert into student (sname, sid) values (?, ?)
14:38:22,464 DEBUG JDBCTransaction:147 - committed JDBC Connection
tearDown()...

在单元测试里再作两次修改,分别添加lisi和wangwu两笔学生记录


分析生成的主键值特点:

生成sid=101之前 next_hi=1 ;

生成sid=202之前 next_hi=2 ;

生成sid=303之前 next_hi=3 ;

当上面截图sid=303,sname=wangwu之后,此时 next_hi=4 ;

很容易推理猜想出主键的通项 = N x ( next_hi + max_lo ),其中N是自然数,换成我们赋予的初始值,那么通项 = N x ( 1 + 100) ;

如果我们要想生成主键sid的值是1, 2, 3, 4, 5, 6 ... 这样的自增主键值,我们只需要设置max_lo=0即可


MySQL-connector-Java-5.1.40.zip包:http://download.csdn.net/detail/zhengzizhi/9747510
SS5.2_Hibernate_Hibernate_IdStrategyXML.zip源码下载地址:http://download.csdn.net/detail/zhengzizhi/9749951


<generator class="increment"/> 范例代码如下面Identity一样,本范例省略




第1步:必需手动删除testdb数据库中的student表和hi_value表 drop table student; drop talbe hi_value;

第2步:修改对象 - 关系映射文件Student.hbm.xml,注意红色字体标识的部分;

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- hibernate映射,包名对应java的包名 -->
<hibernate-mapping package="net.nw.vo">
    <!-- 指定对实体类net.nw.vo.Student与数据库关系表student的映射关系,当两者相同时,可以不指定table -->
    <class name="net.nw.vo.Student" table="student">
         <!-- id指定实体属性(name="sid")与关系表主键(column="sid")之间映射关系 -->
         <id name="sid" column="sid" type="int">
<generator class="identity"/>
         </id>
         <!-- 实体属性与关系表字段之间映射关系,如果两者名字相同,column可以不写 -->
         <property name="sname" column="sname" type="string"></property>
    </class>
</hibernate-mapping>

第3步:单元测试代码如下,提交1条zhangsan的记录到testdb数据库中的student表里;

package net.nw.vo;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import junit.framework.TestCase;
public class TestStudent extends TestCase {
private static SessionFactory sessionFactory ;
@Override
protected void setUp() throws Exception {
System.out.println("setUp()...");
sessionFactory = new Configuration().configure().buildSessionFactory();
}
@Override
protected void tearDown() throws Exception {
System.out.println("tearDown()...");
sessionFactory.close();
}
public void testSave(){
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
try{
Student s = new Student();
s.setSname("zhangsan");
session.save(s);
tx.commit();

}catch(Exception ex){
tx.rollback();
ex.printStackTrace();
}
}
}

第4步:运行单元测试方法testSave(),控制台打印输出如下信息

setUp()...
16:58:32,827  INFO TransactionFactoryFactory:59 - Using default transaction strategy (direct JDBC transactions)
16:58:32,829  INFO TransactionManagerLookupFactory:80 - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
16:58:32,991  INFO SchemaUpdate:155 - Running hbm2ddl schema update
16:58:32,991  INFO SchemaUpdate:167 - fetching database metadata
16:58:32,992  INFO SchemaUpdate:179 - updating schema
16:58:33,001  INFO DatabaseMetadata:119 - table not found: student
16:58:33,003  INFO DatabaseMetadata:119 - table not found: student
16:58:33,003 DEBUG SchemaUpdate:203 - create table student (sid integer not null auto_increment, sname varchar(255), primary key (sid))
16:58:33,009  INFO SchemaUpdate:217 - schema update complete
16:58:33,174 DEBUG JDBCTransaction:82 - begin
16:58:33,175 DEBUG JDBCTransaction:87 - current autocommit status: false
16:58:33,180 DEBUG SQL:111 - insert into student (sname) values (?)
Hibernate: insert into student (sname) values (?)
16:58:33,191 DEBUG JDBCTransaction:134 - commit
16:58:33,194 DEBUG JDBCTransaction:147 - committed JDBC Connection
tearDown()...



MySQL-connector-Java-5.1.40.zip包:http://download.csdn.net/detail/zhengzizhi/9747510
SS5.3_Hibernate_Hibernate_IdStrategyXML.zip源码下载地址:http://download.csdn.net/detail/zhengzizhi/9750111



第1步:必需手动删除testdb数据库中的student表 drop table student;

第2步:修改对象 - 关系映射文件Student.hbm.xml,注意红色字体标识的部分;

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- hibernate映射,包名对应java的包名 -->
<hibernate-mapping package="net.nw.vo">
    <!-- 指定对实体类net.nw.vo.Student与数据库关系表student的映射关系,当两者相同时,可以不指定table -->
    <class name="net.nw.vo.Student" table="student">
         <!-- id指定实体属性(name="sid")与关系表主键(column="sid")之间映射关系 -->
         <id name="sid" column="sid" type="int">
<generator class="native"/>
         </id>
         <!-- 实体属性与关系表字段之间映射关系,如果两者名字相同,column可以不写 -->
         <property name="sname" column="sname" type="string"></property>
    </class>
</hibernate-mapping>

如果主键生成策略是native,它会智能地根据id name="sid" column="sid" type="int" 这行主键的类型自动地添加自增字段特性

单元测试代码如下:

package net.nw.vo;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import junit.framework.TestCase;
public class TestStudent extends TestCase {
private static SessionFactory sessionFactory ;
@Override
protected void setUp() throws Exception {
System.out.println("setUp()...");
sessionFactory = new Configuration().configure().buildSessionFactory();
}
@Override
protected void tearDown() throws Exception {
System.out.println("tearDown()...");
sessionFactory.close();
}
public void testSave(){
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
try{
Student s = new Student();
s.setSname("zhangsan");
session.save(s);
tx.commit();

}catch(Exception ex){
tx.rollback();
ex.printStackTrace();
}
}
}

运行单元测试方法testSave() ,控制台打印输出如下信息:

setUp()...
18:00:27,118  INFO TransactionFactoryFactory:59 - Using default transaction strategy (direct JDBC transactions)
18:00:27,120  INFO TransactionManagerLookupFactory:80 - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
18:00:27,263  INFO SchemaUpdate:155 - Running hbm2ddl schema update
18:00:27,263  INFO SchemaUpdate:167 - fetching database metadata
18:00:27,264  INFO SchemaUpdate:179 - updating schema
18:00:27,267  INFO DatabaseMetadata:119 - table not found: student
18:00:27,268  INFO DatabaseMetadata:119 - table not found: student
18:00:27,268 DEBUG SchemaUpdate:203 - create table student (sid integer not null auto_increment, sname varchar(255), primary key (sid))
18:00:27,276  INFO SchemaUpdate:217 - schema update complete
18:00:27,338 DEBUG JDBCTransaction:82 - begin
18:00:27,339 DEBUG JDBCTransaction:87 - current autocommit status: false
18:00:27,345 DEBUG SQL:111 - insert into student (sname) values (?)
Hibernate: insert into student (sname) values (?)
18:00:27,356 DEBUG JDBCTransaction:134 - commit
18:00:27,360 DEBUG JDBCTransaction:147 - committed JDBC Connection
tearDown()...

SS5.4_Hibernate_Hibernate_IdStrategyXML.zip源码下载地址:
MySQL-connector-Java-5.1.40.zip包:http://download.csdn.net/detail/zhengzizhi/9747510

第1步:必需手动删除testdb数据库中的student表 drop table student;
第2步:修改对象 - 关系映射文件Student.hbm.xml,注意红色字体标识的部分;
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- hibernate映射,包名对应java的包名 -->
<hibernate-mapping package="net.nw.vo">
    <!-- 指定对实体类net.nw.vo.Student与数据库关系表student的映射关系,当两者相同时,可以不指定table -->
    <class name="net.nw.vo.Student" table="student">
         <!-- id指定实体属性(name="sid")与关系表主键(column="sid")之间映射关系 -->
         <id name="sid" column="sid" type="string"">
<generator class="uuid.hex"/>
         </id>
         <!-- 实体属性与关系表字段之间映射关系,如果两者名字相同,column可以不写 -->
         <property name="sname" column="sname" type="string"></property>
    </class>
</hibernate-mapping>

第3步:修改学生实体类主键sid类型;

package net.nw.vo;
public class Student {
privateString sid;
private String sname;

publicString getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
}
如果主键生成策略是native,它会智能地根据id name="sid" column="sid" type="int" 这行主键的类型自动地添加自增字段特性
单元测试代码如下:
package net.nw.vo;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import junit.framework.TestCase;
public class TestStudent extends TestCase {
private static SessionFactory sessionFactory ;
@Override
protected void setUp() throws Exception {
System.out.println("setUp()...");
sessionFactory = new Configuration().configure().buildSessionFactory();
}
@Override
protected void tearDown() throws Exception {
System.out.println("tearDown()...");
sessionFactory.close();
}
public void testSave(){
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
try{
Student s = new Student();
s.setSname("zhangsan");
session.save(s);
tx.commit();

}catch(Exception ex){
tx.rollback();
ex.printStackTrace();
}
}
}
运行单元测试方法testSave() ,控制台打印输出如下信息:

setUp()...
20:05:38,309  INFO TransactionFactoryFactory:59 - Using default transaction strategy (direct JDBC transactions)
20:05:38,311  INFO TransactionManagerLookupFactory:80 - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
20:05:38,465  INFO SchemaUpdate:155 - Running hbm2ddl schema update
20:05:38,465  INFO SchemaUpdate:167 - fetching database metadata
20:05:38,466  INFO SchemaUpdate:179 - updating schema
20:05:38,469  INFO DatabaseMetadata:119 - table not found: student
20:05:38,481  INFO DatabaseMetadata:119 - table not found: student
20:05:38,482 DEBUG SchemaUpdate:203 - create table student (sid varchar(255) not null, sname varchar(255), primary key (sid))
20:05:38,489  INFO SchemaUpdate:217 - schema update complete
20:05:38,619 DEBUG JDBCTransaction:82 - begin
20:05:38,620 DEBUG JDBCTransaction:87 - current autocommit status: false
20:05:38,627 DEBUG JDBCTransaction:134 - commit
20:05:38,630 DEBUG SQL:111 - insert into student (sname, sid) values (?, ?)
Hibernate: insert into student (sname, sid) values (?, ?)
20:05:38,639 DEBUG JDBCTransaction:147 - committed JDBC Connection
tearDown()...

再添加1条lisi的数据记录到student表中,注意并没有给主键字串赋值,这种全球唯一的uuid主键值可以用到分布式系统中,截图查看一下已经添加的两条数据如下:




0 0
原创粉丝点击