hibernate操作数据库 插入修改数据库默认值 dynamic-insert dynamic-update
- 格式:doc
- 大小:61.00 KB
- 文档页数:9
Hibernate项目的构建与配置1.在项目里倒入Hibernate所必须的Jar包(1)Hibernate框架可以使用在任何的Java项目里,并不一定是Web项目。
只需要在项目里倒入Hibernate所必须要使用的jar包就可以了。
(2)在Hibernate的官网下载hibernate-release-4.2.2.Final.zip解压,要使用Hibernate必须导入的jar包就在目录“hibernate-release-4.2.2.Final\lib\required”下。
倒入此路径下的所有jar包就可以了。
2.配置hibernate.cfg.xml文件(1)配置hibernate.cfg.xml文件可以参考“\project\etc”目录下的hibernate.cfg.xml文件与hibernate.properties文件。
(2)使用Hibernate连接MySQL的hibernate.cfg.xml配置文件如下:<hibernate-configuration><session-factory>(设置显示Hibernate产生的SQL语句)<property name="show_sql">true</property>(设置MySQL的SQL语法的方言)<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>(设置MySQL的驱动程序)<property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>(设置MySQL的数据库路径、用户名、密码)<property name="hibernate.connection.url">jdbc:mysql:///java</property><property name="ername">root</property><property name="hibernate.connection.password">lizhiwei</property>(设置当数据库要保存的表不存在时,就新建表)<property name="hibernate.hbm2ddl.auto">update</property>(设置对象与数据库表的关系映射文件)<mapping resource="vo/User.hbm.xml"/></session-factory></hibernate-configuration>(3)此配置文件一般放在项目的src目录下。
操作数据(insert、update、delete)插⼊数据使⽤Insert Into 插⼊if(exists(select*from sys.databases where name ='webDB'))drop database webDBgo--创建数据库create database webDB on primary(name ='webDB',filename='d:\webDB.mdf',size = 5mb,maxsize=unlimited,filegrowth=10%)log on(name ='webDB_log',filename ='d:\webDB.ldf',size=3mb,maxsize=50mb,filegrowth=2mb)use webDBgo--创建表create table student(id int identity(1,1) primary key,name varchar(20) not null,sex char(2) not null,age int)--使⽤Insert Into 插⼊⼀⾏数据insert into student (name,sex,age) values ('⽩⼤伟','男',26)--id为标识列⾃动增长⽆需为其添加值--插⼊某个列insert into student (name,sex) values ('魏⼒夫','妖')--如果插⼊全部列,可以不⽤写列名insert into student values ('李东','男',37)插⼊标识列Set Identity_Insert--如果需要在标识列中插⼊⼀个值,可以使⽤Set Identity_Insert语句,但注意主键不可重复!set Identity_Insert student on --设置允许插⼊标识列insert into student (id,name,sex,age) values (4,'梁不贱','男',24)set Identity_Insert student off --插⼊后关闭使⽤Insert Into 插⼊多⾏数据--使⽤Insert Into 插⼊多⾏数据,使⽤逗号分割insert into student (name,sex,age) values('张三','男',18),('李四','⼥',19),('王五','⼥',20)使⽤Select语句插⼊--使⽤Select 语句可以将现有表中的多⾏数据插⼊到⽬标表中insert into student (name,sex,age) select Sname,Ssex,Sage from oldTable使⽤Select Into插⼊--使⽤Select Into 插⼊数据--该⽅法其实是创建了⼀张新表,然后由select语句将所有⾏添加到新创建的表中。
今天徒弟用到了一句复杂的查询语句。
结果执行报错,但是在SQL中执行没有问题,于是来求助我了。
语句的HQL/SQL格式如下:select count(1) ,cxltype,sum(dzsje),sum(iperson)from (selectxl.cxltype,g.iperson,(select sum(y.dzsje) from Ysklist as y wherey.cykpid = g.cregno) as dzsje from Guestreg as g,Xl as xl where g.xluuid = xl.uuid ) as t where …… group by t.cxltype结果执行出错,最终发现,HQL无法支持from后面跟子查询的方式,网上查了N 多资料,发现遇到这个问题的人还真是不少,但每一个相关的问题帖都没有满意的答复,甚至于多数都是没有跟帖的。
一阵心寒,hibernate叱咤风云,竟然对这个支持如此之弱?虽然这个语句可以通过另外的方法来做(比如建视图或者直接使用SQL来做),但总是不甘心,于是又开始查阅各处资料,最后找到了思路,觉得既然HQL不支持,那么只能把这种子查询封装为对象来做了,那么肯定是需要hbm配置这种临时的子查询对象的,于是开始着手hbm配置的资料中查,hbm中配置对象的都是class标签,开始把范围缩小,针对hbm的class标签的属性资料开始翻查,找到了几个比较可能的属性,where、subselect、mutable、entity-bean,貌似这些都可能跟临时对象有关。
于是反复尝试,并继续翻查资料最终在Hibernate reference 3.2.0 ga 正式版中文参考手册中找到了一些比较可靠的资料:5.1.3. class你可以使用class元素来定义一个持久化类:<classname="ClassName"table="tableName"discriminator-value="discriminator_value"mutable="true|false"schema="owner"catalog="catalog"proxy="ProxyInterface"dynamic-update="true|false"dynamic-insert="true|false"select-before-update="true|false"polymorphism="implicit|explicit"where="arbitrary sql where condition"persister="PersisterClass"batch-size="N"optimistic-lock="none|version|dirty|all"lazy="true|false"entity-name="EntityName"check="arbitrary sql check condition"rowid="rowid"subselect="SQL expression"abstract="true|false"node="element-name"/>name (可选): 持久化类(或者接口)的Java全限定名。
Hibernate 参数设置一览表2007年11月25日星期日21:59Hibernate 参数设置一览表(强烈推荐)属性名用途hibernate.dialect 一个Hibernate Dialect类名允许Hibernate针对特定的关系数据库生成优化的SQL. 取值full.classname.of.Dialecthibernate.show_sql 输出所有SQL语句到控制台. 有一个另外的选择是把org.hibernate.SQL这个log category设为debug。
eg.true | falsehibernate.format_sql 在log和console中打印出更漂亮的SQL。
取值true | false hibernate.default_schema 在生成的SQL中, 将给定的schema/tablespace附加于非全限定名的表名上. 取值SCHEMA_NAMEhibernate.default_catalog 在生成的SQL中, 将给定的catalog附加于非全限定名的表名上. 取值CATALOG_NAMEhibernate.session_factory_name SessionFactory 创建后,将自动使用这个名字绑定到JNDI中. 取值jndi/composite/namehibernate.max_fetch_depth 为单向关联(一对一, 多对一)的外连接抓取(outer join fetch)树设置最大深度. 值为0意味着将关闭默认的外连接抓取. 取值建议在0到3之间取值hibernate.default_batch_fetch_size 为Hibernate关联的批量抓取设置默认数量. 取值建议的取值为4, 8, 和16hibernate.default_entity_mode 为由这个SessionFactory打开的所有Session指定默认的实体表现模式. 取值dynamic-map, dom4j, pojohibernate.order_updates 强制Hibernate按照被更新数据的主键,为SQL更新排序。
目录1.1Hibernate中的批量处理技术及应用实例 (2)1.1.1Hibernate中的批量处理技术 (2)1.1.2大批量的数据更新(Batch updates)技术及应用实例 (3)1.1.3大批量的数据删除技术及应用实例 (7)1.1Hibernate中的批量处理技术及应用实例1.1.1Hibernate中的批量处理技术1、批量插入(Batch inserts)(1)内存溢出异常使用Hibernate将100000 条记录插入到数据库的一个很自然的做法可能是这样的Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction() ;for(int i=0; i<100000 ;i++) {Student stu = new Student();….session.save(stu);}mit();session.close();这段程序大概运行到50000 条记录左右会失败并抛出内存溢出异常(OutOfMemoryException)。
这是因为Hibernate 把所有新插入的学生(Student)实例在session级别的缓存区(也就是Hibernate的一级缓存)进行了缓存的缘故,导致内存不够而出现内存溢出异常(OutOfMemoryException)。
那如何解决该问题,使用下面所介绍的JDBC的批量处理技术。
(2)采用分段插入及时清除缓存的方法●将JDBC的批量抓取数量(batch size)参数设置到一个合适值(比如,10-50之间)在hibernate.properties配置文件中设置如下:hibernate.jdbc.batch_size 20 同时,我们也可以在执行批量处理时关闭二级缓存:在hibernate.properties配置文件中设置如下:e_second_level_cache false●示例代码如果要将很多对象持久化,则必须通过经常的调用flush() 以及稍后调用clear() 来控制第一级缓存的大小,否则会出现错误——优化Hibernate,程序上采用分段插入及时清除缓存的方法。
hibernate saveorupdate举例使用Hibernate是一个用于Java语言的对象关系映射框架,它提供了一种将对象模型与关系数据库进行映射的方式,使开发人员可以通过面向对象的方式进行数据库操作。
其中,saveOrUpdate()是Hibernate中一个常用的方法,用于保存或更新实体对象。
在本文中,我将详细介绍saveOrUpdate()方法的使用,并以示例代码来演示其具体的操作步骤。
首先,我们需要配置Hibernate的相关环境和依赖。
在项目的pom.xml 文件中,添加如下的Hibernate依赖:xml<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>5.4.0.Final</version></dependency>同时,我们需要在项目中配置Hibernate的相关配置文件,如hibernate.cfg.xml。
在该文件中,我们需要配置数据库的连接信息、实体类与数据库表的映射关系等。
接下来,我们创建一个实体类,假设为User,用于映射到数据库中的一张用户表。
javaEntityTable(name = "user")public class User {IdGeneratedValue(strategy = GenerationType.IDENTITY)private Long id;Columnprivate String username;Columnprivate String password;getters and setters}在上述代码中,我们使用Entity注解将User类与数据库表进行映射,并使用Table注解指定了数据库表的名称。
liquibase insert语句Liquibase是一个数据库变更管理工具,可以帮助开发团队跟踪和自动化数据库的变更。
Insert语句用于将新的数据插入到数据库表中。
本文将分享Liquibase中Insert语句的相关内容,包括语法结构、参数说明以及一些示例。
Liquibase中的Insert语句用于向数据库表中插入数据。
插入数据是在数据表中创建新的行,每一行代表了一个记录或实体。
Insert语句可以一次插入多行数据,每一行数据包含了表中的各个字段的值。
Insert语句的语法结构如下:```yaml<insert><column name="column_name" value="column_value"/><!-- 可以添加多个字段 --></insert>```在Insert语句中,我们使用`<insert>`标签定义插入语句,并在其中使用`<column>`标签指定要插入的字段和对应的值。
通过在`<column>`标签中使用`name`属性指定字段名,使用`value`属性指定字段的值。
下面是一些Insert语句的参数说明:- `<insert>`: 插入语句的开始标签。
- `<column>`: 插入的字段,可以包含多个。
- `name`: 字段名称。
- `value`: 字段的值。
接下来,我们来看一些Insert语句的示例:```yaml<insert tableName="employee"><column name="id" value="1"/><column name="name" value="John Doe"/><column name="age" value="30"/></insert>```上述示例表示在employee表中插入一行数据,该行数据包含了id、name和age三个字段。
Hibernate注解常用的hibernate annotation标签如下:@Entity--注释声明该类为持久类。
@Table(name="promotion_info")--持久性映射的表(表名="promotion_info)。
@Column(name=”DESC”,nullable=false,length=512)--用于指定持久属性或字段的映射列。
@Id--注释可以表明哪种属性是该类中的独特标识符(即相当于数据表的主键)。
@GeneratedValue--定义自动增长的主键的生成策略。
@Transient--将忽略这些字段和属性,不用持久化到数据库。
@Temporal(TemporalType.TIMESTAMP)--声明时间格式。
@Enumerated--声明枚举@Version--声明添加对乐观锁定的支持@OneToOne--可以建立实体bean之间的一对一的关联@OneToMany--可以建立实体bean之间的一对多的关联@ManyToOne--可以建立实体bean之间的多对一的关联@ManyToMany--可以建立实体bean之间的多对多的关联@Formula--一个SQL表达式,这种属性是只读的,不在数据库生成属性(可以使用sum、average、max等)@OrderBy--Many端某个字段排序(List)下面是对以上常用Hibernate注解标签的详细介绍与举例:@Entity--注释声明该类为持久类。
将一个Javabean类声明为一个实体的数据库表映射类,最好实现序列化.此时,默认情况下,所有的类属性都为映射到数据表的持久性字段.若在类中,添加另外属性,而非映射来数据库的, 要用下面的Transient来注解.@Table(name="promotion_info")--持久性映射的表(表名="promotion_info).@T able是类一级的注解,定义在@Entity下,为实体bean映射表,目录和schema的名字,默认为实体bean的类名,不带包名.示例:@Entity@T able(name="CUST", schema="RECORDS")public class Customer { ... }@Column(name=”DESC”,nullable=false,length=512)--用于指定持久属性或字段的映射列。
1. Doctype所有的XML映射都需要定义如上所示的doctype。
DTD可以从上述URL中获取,也可以从hibernate-x.x.x/src/net/sf/hibernate目录中、或hibernate.jar文件中找到。
Hibernate总是会首先在它的classptah中搜索DTD文件。
如果你发现它是通过连接Internet查找DTD 文件,就对照你的classpath目录检查XML文件里的DTD声明。
2. hibernate-mapping这个元素包括一些可选的属性。
schema和catalog属性,指明了这个映射所连接(refer)的表所在的schema和/或catalog名称。
假若指定了这个属性,表名会加上所指定的schema 和catalog的名字扩展为全限定名。
假若没有指定,表名就不会使用全限定名。
default-cascade指定了未明确注明cascade属性的Java属性和集合类Hibernate会采取什么样的默认级联风格。
auto-import属性默认让我们在查询语言中可以使用非全限定名的类名。
<hibernate-mappingschema="schemaName" (1)catalog="catalogName" (2)default-cascade="cascade_style" (3)default-access="field|property|ClassName" (4)default-lazy="true|false" (5)auto-import="true|false" (6)package="" (7)/>(1) schema (可选): 数据库schema的名称。
(2) catalog (可选): 数据库catalog的名称。
Hibernate 知识点小结Hibernate一, Hibernate 介绍:Hibernate 只是一个将持久化类与数据库表相映射的工具,每个持久化类实例均对应于数据库表中的一个数据行而已。
用户只需直接使用面向对象的方法操作此持久化类实例,即可完成对数据库表数据的插入、删除、修改、读取等操作。
当然实际的Hibernate 框架非常复杂,用分层的概念划分的话,它相当于在业务逻辑处理层和数据库底层JDBC驱动之间的一层,即通常说的持久化层,而用户通过XML 配置文件将具体的持久化类与数据库表映射起来。
Hibernate 的实际过程还需依赖SQL 语言和JDBC 编程接口,但是Hibernate 将原本分散的JDBC 和SQL 配合产生的接口变成了对象化的接口,定义了自己的基于面向对象设计的HQL(Hibernate Query Language)查询语言,通过它生成实际的SQL 语句传递到数据库执行的。
1) ConfigurationConfiguration 类负责管理Hibernate 运行时需要获取一些底层实现的基本配置信息,如:数据库URL、数据库用户、数据库用户密码、数据库JDBC 驱动类、数据库适配器(dialect,用于对特定数据库支持)等。
Hibernate 的配置文件为hibernate.cfg.xml 或者hibernate.properties,缺省在CLASSPATH 路径下,可调用如下进行初始化:Configuration config = new Configuration().configure();2) SessionFactorySessionFactory 负责创建Session 实例,通过Configuation 实例创建它:SessionFactory sessionFactory =config.buildSessionFactory();如果需要访问多个数据库,要分别为其创建对应的SessionFactory 实例。
JDBCUpdate操作返回值和Insert操作返回主键JDBC Update操作返回值在操作数据库时,update操作会返回数据库更新⾏数,但是在JDBC默认情况下则不会返回数据库更新⾏数,这⼀点有所不同,在实际操作中可能会出现意想不到的结果。
在使⽤ORM框架时,例如Mybatis、Hibernate时由于其底层同样使⽤JDBC API,所以同样会出现上诉问题。
JDBC API⾸先,我们看⼀下JDBC API中是对update操作返回值得定义,主要涉及要Statement.executeUpdate()和PreparedStatement.executeUpdate()两个操作,其返回值定义⼀样:either (1) the row count for SQL Data Manipulation Language (DML) statements or (2) 0 for SQL statements that return nothing也就是说DDL语句返回值为0,⽽DML语句返回值只是说返回Row Count,⽽没有说返回Affect Count。
JDBC Update操作的⼏个例⼦我们来编写⼏个例⼦,实际来看看JDBC Update的返回值。
注:这⾥使⽤的是Mysq数据库进⾏测试:JDBC Connection Properties:driver=com.mysql.jdbc.Driverurl=jdbc:mysql://120.55.59.65:3306/study_jdbc?characterEncoding=utf8username=rootpassword=********JDBC DDL:Connection connection = DriverUtils.getConnection();String sql1 = "DROP TABLE IF EXISTS `update_return_value`;";String Sql2 = " CREATE TABLE `update_return_value`"+ "(`id` bigint(20) PRIMARY KEY NOT NULL AUTO_INCREMENT, `name` varchar(255))"+ "ENGINE=InnoDB AUTO_INCREMENT=1;";PreparedStatement preparedStatement = connection.prepareStatement(sql1);preparedStatement.executeUpdate();PreparedStatement statement = connection.prepareStatement(Sql2);int updateValue = statement.executeUpdate();System.out.println("Update Return Value: " + updateValue);控制台输出:Update Return Value: 0JDBC Insert:Connection connection = DriverUtils.getConnection();String sql = "INSERT INTO update_return_value(name) VALUES (?)";PreparedStatement preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1, "2222");int updateValue = preparedStatement.executeUpdate();System.out.println("Update Return Value: " + updateValue);控制台输出:Update Return Value: 1JDBC正确的Update操作,注意这⾥,我们重复执⾏2次:Connection connection = DriverUtils.getConnection();String sql = "UPDATE update_return_value SET name = ? WHERE id = ?";PreparedStatement preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1, "11111");preparedStatement.setLong(2, 1L);int updateValue = preparedStatement.executeUpdate();System.out.println("Update Return Value: " + updateValue);控制台输出:Update Return Value: 1 /n Update Return Value: 1JDBC不正确的Update操作:Connection connection = DriverUtils.getConnection();String sql = "UPDATE update_return_value SET name = ? WHERE id = ?";PreparedStatement preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1, "11111");preparedStatement.setLong(2, 2L);int updateValue = preparedStatement.executeUpdate();System.out.println("Update Return Value: " + updateValue);控制台输出:Update Return Value: 0从上⾯我们可以看出,出乎意料的是在正确update更新操作执⾏2次结果都是1,如果是返回值是⾏影响数⽬则第⼆次应该为0,因为第⼆次更新时数据库并没有变化。
数据库ID⾃增hibernate利⽤mysql的⾃增长id属性实现⾃增长id和⼿动赋值id并存 我们知道在中如果设置了表id为⾃增长属性的话,insert语句中如果对id赋值(值没有被⽤到过)了,则插⼊的数据的id会为⽤户设置的值,并且该表的id的最⼤值会重新计算,以插⼊后表的id最⼤值为⾃增值起点 但是如果使⽤,也想实现这个的特性的话,怎么做呢? ⾸先我们看下hibernate的id⽣成策略: hibernate⽂档写道 1、⾃动增长identity适⽤于MySQL、DB2、MS SQL Server,采⽤⽣成的主键,⽤于为long、short、int类型⽣成唯⼀标识使⽤SQL Server 和 MySQL 的⾃增字段,这个⽅法不能放到中,不⽀持⾃增字段,要设定sequence(MySQL 和 SQL Server 中很常⽤)数据库中的语法如下:MySQL:create table t_user(id int auto_increment primary key, name varchar(20));SQL Server:create table t_user(id int identity(1,1) primary key, name varchar(20));< id name="id" column="id" type="long">< generator class="identity" />< /id>2、sequenceDB2、Oracle均⽀持的序列,⽤于为long、short或int⽣成唯⼀标识数据库中的语法如下:Oracle:create sequence seq_name increment by 1 start with 1;需要主键值时可以调⽤seq_name.nextval或者seq_name.curval得到,数据库会帮助我们维护这个sequence序列,保证每次取到的值唯⼀,如:insert into tbl_name(id, name) values(seq_name.nextval, ‘Jimliu’);< id name="id" column="id" type="long">< generator class="sequence">< param name="sequence">seq_name</param>< /generator>< /id>如果我们没有指定sequence参数,则Hibernate会访问⼀个默认的sequence,是hibernate_sequence,我们也需要在数据库中建⽴这个sequence此外,sequence还可以有另外⼀个参数是paramters,可以查看Hibernate的API了解它的⽤法,见org.hibernate.id.SequenceGenerator调⽤数据库的sequence来⽣成主键,要设定序列名,不然hibernate⽆法找到:< param name="sequence">NAME_SEQ</param>(Oracle中很常⽤)3、hilo使⽤⼀个⾼/低位⽣成的long、short或int类型的标识符,给定⼀个表和字段作为⾼位值的来源,默认的表是hibernate_unique_key,默认的字段是next_hi。
hibernate操作数据库 插入修改数据库默认值 dynamic-insert dynamic-update [size=medium][/size] Hibernate允许我们在映射文件里控制insert和update语句的内容.比如在映射文件中句中,修改的时候,将不包括这个字段了.insert同 理.dynamic动态SQL语句的配置也是很常用的.下面介绍配置SQL语句的具体属性: 1)元素 insert属性:设置为false,在insert语句中不包含这个字段,表示永远不会被插入,默认true 2)元素 update属性:设置为false,在update语句中不包含这个字段,表示永远不会被修改,默认true 3)元素 mutable属性:设置为false就是把所有的元素的update属性设置为了false,说明这个对象不会被更新,默认true 4)元素 dynamic-insert属性:设置为true,表示insert对象的时候,生成动态的insert语句,如果这个字段的值是null就不会加入到insert语句当中.默认false 5)元素 dynamic-update属性,设置为true,表示update对象的时候,生成动态的update语句,如果这个字段的值是null就不会被加入 到update语句中,默认false.有 hibernate提供了dynamic-update属性 你只要设置为true就可以在更新的时候只更新发生改变的字段 其余字段保持数据库中的原有值。 6)元素 dynamic-insert属性:设置为true,表示把所有的元素的dynamic-insert属性设置为true,默认false 7)元素 dynamic-update属性:设置为true,表示把所有的元素的dynamic-update属性设置为true,默认false
Hibernate生成动态SQL语句的消耗的系统资源(比如CPU,内存等)是很小的,所以不会影响到系统的性能,如果表中包含N多字段,建议把 dynamic-update属性和insert属性设置为true,这样在插入和修改数据的时候,语句中只包括要插入或者修改的字段.可以节省SQL语 句的执行时间,提高程序的运行效率. ---------------------------------------------------------------------------------------------------------------------- Hibernate之formula Hibernate映射文件的部分,property元素有一个formula属性。该属性的意思是,可以在值对象中定义一个字段,但在映射文件中 不映射成对应数据库的字段,而是通过formula属性指定一个sql语句。将sql语句的返回值赋给该字段。当时就觉得这个属性挺有用的。今天做到成绩 管理那部分,突然想到需要一个成绩的排名。本来想在数据库中定义一个rank的字段。但是由于排名是不固定的,只能在获取成绩数据的时候动态的决定排名。 于是就想起这个属性来了。
在我的值对象score.java中加上一个rank字段,然后在映射文件中加上一下这句代码 懂sql的都能看明白吧,我说一下需要注意的。首先是sql语句一定要放到一对括号了。然后在引用数据库字段时一定要定义别名,如果不使用别名的话,像我 这个sql里,直接写student_score代表当前对象代表的记录行的数据。这个sql语句的意思就是,找出score表里 student_score的数值比当前对象的student_score大的数据的行数。返回这个数加1,就是当前的排名了。 经过这样的写法,在jsp文件中就可以直接使用score.rank获得当前成绩的排名了 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 第 17 章 Native SQL查询 上一页 下一页
第 17 章 Native SQL查询 你也可以使用你的数据库的Native SQL语言来查询数据。这对你在要使用数据库的某些特性的时候(比如说在查询提示或者Oracle中的 CONNECT关键字),这是非常有用的。这就能够扫清你把原来直接使用SQL/JDBC 的程序迁移到基于 Hibernate应用的道路上的障碍。 Hibernate3允许你使用手写的sql来完成所有的create,update,delete,和load操作(包括存储过程)
17.1. 创建一个基于SQL的Query SQL查询是通过SQLQuery接口来控制的,它是通过调用Session.createSQLQuery()方法来获得 List cats = sess.createSQLQuery("select {cat.*} from cats cat") .addEntity("cat", Cat.class); .setMaxResults(50); .list(); 这个查询指定了: SQL查询语句,它带一个占位符,可以让Hibernate使用字段的别名. 查询返回的实体,和它的SQL表的别名. addEntity()方法将SQL表的别名和实体类联系起来,并且确定查询结果集的形态。 addJoin()方法可以被用于载入其他的实体和集合的关联,TODO:examples! 原生的SQL查询可能返回一个简单的标量值或者一个标量和实体的结合体。 Double max = (Double) sess.createSQLQuery("select max(cat.weight) as maxWeight from cats cat") .addScalar("maxWeight", Hibernate.DOUBLE); .uniqueResult();
17.2. 别名和属性引用 上面使用的{cat.*}标记是 "所有属性" 的简写.你可以显式地列出需要的字段,但是你必须让Hibernate 为每一个属性注入字段的别名.这些字段的站位符是以字段别名为前导,再加上属性名.在下面的例子里,我们从一个其他的表(cat_log) 中获取Cat对象,而非Cat对象原本在映射元数据中声明的表.注意我们甚至在where子句中也可以使用属性别名. 对于命名查询,{}语法并不是必需的.你可以在第 17.3 节 “命名SQL查询”得到更多的细节. String sql = "select cat.originalId as {cat.id}, " + "cat.mateid as {cat.mate}, cat.sex as {cat.sex}, " + "cat.weight*10 as {cat.weight}, cat.name as {cat.name} " + "from cat_log cat where {cat.mate} = :catId"
List loggedCats = sess.createSQLQuery(sql) .addEntity("cat", Cat.class) .setLong("catId", catId) .list(); 注意:如果你明确地列出了每个属性,你必须包含这个类和它的子类的属性! and its
subclasses!
17.3. 命名SQL查询 可以在映射文档中定义查询的名字,然后就可以象调用一个命名的HQL查询一样直接调用命名SQL查询.在这种情况下,我们不 需要调用addEntity()方法. SELECT person.NAME AS {person.name}, person.AGE AS {person.age}, person.SEX AS {person.sex} FROM PERSON person WHERE person.NAME LIKE 'Hiber%' List people = sess.getNamedQuery("mySqlQuery") .setMaxResults(50) .list(); 一个命名查询可能会返回一个标量值.你必须使用元素来指定字段的别名和 Hibernate类型 SELECT p.NAME AS name, p.AGE AS age, FROM PERSON p WHERE p.NAME LIKE 'Hiber%' 和元素分别用作 外连接和定义那些初始化集合的查询
17.3.1. 使用return-property来明确地指定字段/别名 使用你可以明确的告诉Hibernate使用哪些字段,这和使用{}-语法 来让Hibernate注入它自己的别名是相反的.