Hibernate常用
一.对象关系映射基础 1.hibernate对象属性映射 映射文件中,<property>元素的access属性用于指定Hibernate访问持久化类的属性的方式。有以下两种可选值: property:这是默认值,表示是通过属性相应的get,set方法来访问属性。 field:表面是运用Java反射机制直接访问类的属性,此属性可以没有get,set方法。 例如:<property name="name" access="field"/> 这样设置是直接通过属性值取得,可以没有get,set方法。 反之name则是根据set,get后的Name对应,配置文件的name名可以不跟实体bean里的属性名直接对应。 我们常用的hql语句例如:List customers = session.find("from Customer as c where c.name = 'Tom'"); 这里的c.name中的name名字是根据配置文件里的name所对应,并不是和实体bean里的属性名对应。 2.在持久化类的访问方法中加入程序逻辑 (1)hibernate在执行find方法时候会调用bean中的set方法把查询出的内容放入属性中,提供给我们获取其中的值。 在执行save,update等方法时候会调用bean中的get方法获得我们提交的数据进行持久化操作。 所以,可以通过在set,get方法中加入相应我们需要的逻辑,如果不需要让hibernate在执行查询或保存操作时候隐式的调用get,set方法, 可以在映射文件中设置field参数 (2)利用<property>元素的formula属性。 如果数据表里没有totalPrice价格总和字段,而我们需要在获得用户对象的同时,需要知道它对应多个订单的价格总和, 我们可以在CUSTOMER实体bean里定义totalPrice属性,生成get,set方法,再利用以下代码可以实现 例如:<property name="totalPrice" formula="(select sum(o.PRICE) from ORDERS o where o.CUSTOMER_ID=ID)"/> (3)控制insert和update语句 例如:<property name="price" update="false" insert="false" column="PRICE"/> 设置成false代表在保存或修改此类时候,price不被操作。一般多用于多对一关系映射中,避免级联操作。
?
二.关联映射 1.主键自动生成映射 <id name="id" type="java.lang.String" column="ID" length="32"> <generator /> </id> 2.一对一主键关联 <one-to-one name="order" cascade="all"/> constrained属性为true,表明ORDERS表的ID主键同时作为外键参照CUSTOMERS表。 当前xml文件中,必须为OID使用foreign标识符生成策略: <one-to-one name="customer" constrained="true"/> <id name="id" type="java.lang.String" column="ID"> <generator column="CUSTOMER_ID"/> 4.一对多关联 <set name="orders" cascade="save-update" inverse="true" lazy="extra"> <key column="CUSTOMER_ID" /> <one-to-many cascade="save-update" lazy="extra" fetch="join"> <key column="CUSTOMER_ID"></key> <list-index column="SHOW_INDEX"></list-index> <!--orders表中索引位置字段SHOW_INDEX--> <one-to-many /> </list> 5.多对多关联 <set name="orders" table="CUSTOMERS_TO_ORDERS" cascade="save-update" lazy="extra"> <key column="CUSTOMER_ID"/> <!--双向多对多关联必须把其中一端的inverse属性设为true--> <many-to-many column="ORDER_ID"/> </set> 注:当中间表需要有更多的属性字段时,可把多对多分解成两个一对多关联。 6.在数据库中对集合排序 set,map映射支持sort属性(内存排序),order-by属性(数据库排序)。 例如: <set name="orders" cascade="save-update" inverse="true" lazy="extra" order-by="ID asc"> <key column="CUSTOMER_ID" /> <!--当加载Customer对象的orders集合的时,会进行排序操作--> <one-to-many cascade="save-update" inverse="true" lazy="extra" where="STATUS='1'"> <key column="CUSTOMER_ID" /> <!--当加载Customer对象的orders集合的时,只会查出STATUS为1的order对象--> <one-to-many name="code">三.检索方式 1.分页查询 List result = this.getSession().createQuery("from Customer c order by c.name asc") .setFirstResult(0).setMaxResults(10).list(); 2.条件查询 //如果hql语句中含有参数可以使用以下方法提高安全性: Object[] args = {name,order}; //传入的查询条件的变量名字 Type[] types = {Hibernate.STRING,Hibernate.entity(Order.class)}; //变量类型 //Type[]是hibernate提供的变量类型,order为自定义对象类型。 //根据参数说在位置的索引值,传入的变量名字,变量类型来进行查询。 List list = this.query("from Customer c where c.name=? and c.order=?",args,types) public List query(String hql, Object[] args, Type[] types){ Query query = this.getSession().createQuery(hql); query.setParameters(args, types); return query.list(); } 3.批量延迟检索 映射文件中<set>元素有一个batch-size属性,用于为延迟检索或立即检索策略设定批量检索的数量。 注:批量检索的属性值范围不宜过大,如果过大就失去了延迟加载的意义,如果太小也会失去批量检索的意义。 一般设置为:3-10。合理的运用批量检索可以提高检索性能。具体请查阅说明文档。 4.检索单个对象 Customer customer = (Customer)this.getSession().createQuery("from Customer c order by c.name asc") .setMaxResults(1).uniqueResult(); 5.隐式内连接 //标准的HQL内连接查询语句: "from Customer c inner join c.orders"; //如果Customer类中没有orders集合属性,可以采用SQL风格的隐式内连接查询语句: "from Customer c,Order o where c.in=o.customer_id"; 6.分组查询 //例如以下查询语句仅统计具有一条以上订单的客户的所有订单的总价: "select c.id,c.name,sum(o.price) from Customer c join c.orders o group by c.id having (count(o)>1)"; 7.HQL查询的select子句 "select new map(c.name as personName) from Customer c" //HQL语句返回的结果是集合,其中集合元素是Map对象,以personName作为Map的key。 8.SQL查询通过对象属性显示 //SimpleJdbcTemplete是spring为hibernate查询提供的工具类 SimpleJdbcTemplete simpleJdbcTemplete; List<Map<String,Object>> list = simpleJdbcTemplete.queryForList(sql.toString(), new Object[]{});
?
?<觉得写的不错,转载中>