全面解析Hibernate关联操作、查询操作、高级特性、并发处理机制

本文所需的数据库初始文件,Hibernate常用操作的完整示例代码(包含所有Hibernate操作所需jar文件)提供下载学习:http://download.csdn.net/detail/daijin888888/9551724

1、Hibernate关联映射

  1)什么是关联映射?

如果表之间具有关联关系,Hibernate允许我们在hbm.xml中描述他们的关联关系,然后在我们操作其中一张表时,自动的根据这种关系操作到另外的关系表,那么这种关联关系的设置,我们称之为关联映射。

    2)关联映射的好处?

一次访问可以关联操作多张表

--关联查询出关系表的数据

--关联新增、修改关系表的数据

--关联删除关系表的数据

    3)关联映射实现步骤

--了解表之间的关系,且明确关系字段

--在实体类中追加关联属性,用于封装关联的数据

--需要配置hbm.xml文件,设置关联关系

*2、一对多关联    

例:假如一个Account有多条Service记录,希望在查询account数据时,自动连带着查询出它对应的service数据。

  1)表关系

一对多的关系,关系字段是service.account_id。(即Service表中要有与Account表关联的字段account_id,该字段对应Account表中的id)

2)追加关系属性

在Account类中,追加关联属性services,其类型为Set<Service>。

 private Set<Service> services = new HashSet<Service>();

 3)设置关联关系

--语法

在Account.hbm.xml中,设置一对多关系

   <set name="关联属性名">
    <key column="关联字段名"/>
    <one-to-many class="关联表的实体类名"/>
   </set>
  --实现
   <set name="services">
    <key column="account_id"/>
    <one-to-many class="com.*.entity.Service"/>
   </set>

 4)示例代码

已知:

--关联属性services

--关联字段account_id

--关联对象Service --> 表名service

<span style="font-size:14px;">public void testFind() {
 Session session = HibernateUtil.getSession();
 Account a = (Account) session.load(Account.class, 1010);
 System.out.println("---显示Account账号信息---");
 System.out.println(a.getId() + " " + a.getRealName() + " " + a.getIdcardNo());
 System.out.println("---显示当前账号下的业务账号---");
 Set<Service> services = a.getServices();
 for (Service s : services) {
  System.out.println(s.getId() + " " + s.getOsUserName() + " " + s.getUnixHost());
 }
 System.out.println(a.toString());
}</span> 

*3、多对一关联 

例:希望在查询service数据后,可以自动的查询出它对应的account数据。

 1)关联关系 

service与account具有多对一的关系,关系字段为service.account_id

 2)追加关联属性

--在Service实体类中追加关联属性account,其类型为Account。

private Account account;

此后accountId属性可以去掉,可以通过getAccount().getId()方法来得到account_id的值

 3)设置关联关系

a、语法:

--在Service.hbm.xml中,追加关联关系的配置

--<many-to-one name="关联属性名"
                    column="关系字段名"
                    class="关联表的实体类名"/>

b、实现:

<many-to-one name="account"
                column="account_id"
                class="com.*.entity.Account"/>

4)示例代码

已知:

--关联属性account

--关联字段account_id

--关联对象Account --> 表名account,主键id

<span style="font-size:14px;">public void testFind() {
 Session session = HibernateUtil.getSession();
 Service s = (Service) session.get(Service.class, 2002);
 System.out.println("----显示业务账号信息---");
 System.out.println(s.getId() + " " + s.getOsUserName() + " " + s.getUnixHost());
 System.out.println("----显示相关账务账号信息---");
 System.out.println(s.getAccount().getId() + " " + s.getAccount().getRealName());
}</span> 

*4、关联操作   

 1)关联查询

如果需要当前对象和关联属性一起采用一个SQL语句实例化,可以采用下面方法:

a、(不推荐)修改hbm.xml中的关联属性映射

lazy属性:

true表示启用延迟加载;

false表示关闭延迟加载

fetch属性:

join表示采用连接方法与主对象一起查询,此时,lazy="false"失效;

select(默认)表示单独发送一个SQL查询关联数据

b、(推荐)通过HQL及join fetch语法

--from Account a join fetch a.services where a.id=?

含义:在查询Account对象时,将services关联属性数据采用表连接方式一并查出来。

--from Service s join fetch s.account where s.id=?

含义:在查询Service对象时,将account关联属性数据采用表连接方式一并查出来。

--from Service s join fetch s.account where s.account.id=?

注意:

--HQL中写的是对象和属性

--join fetch后面没有on子句,而fetch的是关联属性
            --query.setInteger来设置整型参数值,下标从0开始。

--如果明确该HQL只会返回一条记录,可以使用query.uniqueResult()方法返回唯一的记录

c、示例代码(改写上述一对多关联的查询代码)

<span style="font-size:14px;">public void testFind() {
 Session session = HibernateUtil.getSession();
 // Account a = (Account) session.load(Account.class, 1010);
 String hql = "from Account a join fetch a.services where a.id=?";
 Query query = session.createQuery(hql);
 query.setInteger(0, 1010);// ?从0开始
 Account a = (Account) query.uniqueResult();// 单行查询可采用
 System.out.println("---显示Account账号信息---");
 System.out.println(a.getId() + " " + a.getRealName() + " " + a.getIdcardNo());
 System.out.println("---显示当前账号下的业务账号---");
 Set<Service> services = a.getServices();
 for (Service s : services) {
  System.out.println(s.getId() + " " + s.getOsUserName() + " " + s.getUnixHost());
 }
 System.out.println(a.toString());
}</span> 

  2)级联添加、级联修改

a、当表具有关联关系时,Hibernate不仅仅提供关联查询的功能,还具有关联添加、修改、删除关联表中数据的能力,这种能力称之为级联操作。

b、如何实现级联操作

需要在关联属性设置的位置,追加属性cascade

--none:默认不支持级联

--save-update:支持级联添加与更新

--delete:支持级联删除

--all:支持级联添加、更新、删除

c、说明

通常1对多的表关系,1的一方是主表,多的一方是从表,往往是需要在添加、更新、删除主表时连带添加、更新、删除从表的数据。如:删除账务账号时,要连带删除业务账号的数据

    3)级联删除

a、设置cascade="delete"或cascade="all"就可以支持级联删除

b、通常情况下,需要在1的一方set标签处,追加属性inverse="true"

c、session.delete(obj);obj需要是持久对象,不能new,需要load/get取出

d、批量删除的方法:

级联删除采用n+1个delete语句清除主表和外键表的关联数据。

如果是批量删除,不推荐级联删除,建议采用HQL编写delete删除语句

delete from Service where account.id=?//删除Service表中所有account.id=?的数据,(该句替代级联操作中的n个delete语句)

delete from Account where id=?

4)inverse属性(理解)详细说明点这里

是否交出关系维护的控制权。即默认情况下,Account和Service对象之间的关系由双方负责维护。意思是对Account或Service对象做级联操作时,需要执行update语句将关联字段设置成相同ID。如果需要取消某一方的关系维护工作,可以在关联属性部分添加inverse="true"设置,这样可以避免update语句执行。

true:交出控制权,当前的对象不负责维护两张表的关联关系

false:不交出控制权,当前的对象要负责维护两张表的关联关系

提示:往往是一的一方(即<one-to-many>映射部分)设置为inverse="true",这样在对一方级联操作时,可以避免大量的update更新语句。

*5、多对多关联

例:管理员admin_info和角色role_info具有多对多的关系,希望在查询管理员时能够连带着查询出他对应的角色。 数据库设计时,需采用3张表表示。

ADMIN_INFO(管理员)

ADMIN_ROLE(管理员和角色关系)

ROLE(角色)

    1)关系字段

关系字段位于他们的中间表admin_role中,

admin_id=admin_info.id

role_id=role_info.id

    2)追加关联属性在管理员的实体类中追加角色相关属性

Set<Role> roles

   3)在Admin.hbm.xml中追加关联映射配置

--语法
    <set name="关联属性名" table="中间表名">
      <key column="Admin的关联字段名"/>
      <many-to-many class="关联表的实体类名"
        column="关联表的关系字段名"/>
    </set>
    --代码
    <set name="roles" table="admin_role">
      <key column="admin_id"/>
      <many-to-many class="com.*.entity.Role"
        column="role_id"/>
    </set>

 4)级联操作

cascade表示支持级联操作,操作的是另一方的表,而并不是表示级联操作中间表。对于中间表的维护,不需要写cascade属性。

 5)inverse

通常情况下,多对多关联,不需要写inverse="true",原因是另一方在插入数据时,可能没有管中间表的数据,需要当前的一方来维护,因此不能写inverse="true",否则的话,双方都不维护这个关系,数据上有问题。

  6)示例Java代码

<span style="font-size:14px;">    // 移除角色
  @Test
  public void testDeleteRole() {
    Session session = HibernateUtil.getSession();
    Transaction tx = session.beginTransaction();
    try {
      Admin a = (Admin) session.load(Admin.class, 1);
      Role r1 = (Role) session.load(Role.class, 1);
      a.getRoles().remove(r1);
      session.update(a);
      tx.commit();
    } catch (HibernateException e) {
      e.printStackTrace();
      tx.rollback();
    } finally {
      session.close();
    }
  }
  // 追加角色
  @Test
  public void testAddRole() {
    Session session = HibernateUtil.getSession();
    Transaction tx = session.beginTransaction();
    try {
      Admin a = (Admin) session.load(Admin.class, 1);
      Role r1 = (Role) session.load(Role.class, 1);
      Role r2 = (Role) session.load(Role.class, 43);
      Role r3 = (Role) session.load(Role.class, 44);
      a.getRoles().add(r1);
      a.getRoles().add(r2);
      a.getRoles().add(r3);
      session.update(a);
      tx.commit();
    } catch (HibernateException e) {
      e.printStackTrace();
      tx.rollback();
    } finally {
      session.close();
    }
  }
  @Test
  public void testFind() {
    Session session = HibernateUtil.getSession();
    Transaction tx = session.beginTransaction();
    try {
      Admin a = (Admin) session.load(Admin.class, 1);
      System.out.println("----显示管理员信息---");
      System.out.println(a.getId() + " " + a.getName() + " "
          + a.getTelephone());
      System.out.println("----显示管理员角色信息---");
      for (Role role : a.getRoles()) {
        System.out.println(role.getName() + " ");
      }
      tx.commit();
    } catch (HibernateException e) {
      e.printStackTrace();
      tx.rollback();
    } finally {
      session.close();
    }
  }</span> 

6、继承关联

例:在电商网站上搜索商品,比如输入iphone来搜索,搜索结果中可以包含手机、手机膜、手机壳、充电器、耳机等等相关的产品信息。这种功能,我们可以在设计表时用一种特殊的一对一的关系来表现。即将所有商品通用的属性提取到一张公共的表中product,具体商品表中只保存该商品特有的属性,那么具体商品表和product表具有一对一的关系。在搜索时只搜索product表,就可以将相关的信息模糊查找出来。

--通用信息表product(id,name,price,desc)

--书的商品表book(id,authod,publishing,words)

--希望在操作book表时,能够自动的将通用的字段维护到product表中。

    1)明确表的关系

book与product具有一对一的关系,这种关系的目的是为了复用product表中的字段,像是一种继承关系

    2)实体类

Book extends Product

    3)配置文件中体现关联关系

--父类型同原先的配置文件写法一致

--子类型具有特殊性

    <joined-subclass
        name="类型名" table="表名"
        extends="父类名称">
        <key column="关联字段名"/>
        <property name="" type="" column=""/>
        ...
      </joined-subclass>

4)继承关系中,由于2张表具有类似于父子的关系,那么子表中必须引用父表中的数据,不存在不引用的情况,即必须在维护子表同时维护父表。所以这是固定的情况,就不用写cascade,inverse。

5)描述类别(了解)

<joined-subclass>数据库有父类表和子类表
        <union-subclass>数据库有子类表、没有父类表(子类表已包含父类表字段,无父类表,但有父类实体对象)
        <subclass>数据库有父类子类都用一个表(设计较乱,即没有进行表拆分,很少用)

*7、Hibernate查询

1)*HQL查询(Hibernate Query Language)

属于面向对象查询语句,针对Hibernate映射过来的POJO进行查询,从而实现对数据库的查询。

a、以非主键做条件查询

--条件参数以?表示,query.setString(0,"");

--条件参数以:x表示,query.setString("x","");

示例代码:

<span style="font-size:14px;">    // 测试按非主键做条件查询
  @Test
  public void testFind1() {
    String hql = "from Service where account.id=? and unixHost=?";
    Session session = HibernateUtil.getSession();
    Query query = session.createQuery(hql);
    query.setInteger(0, 1011);
    query.setString(1, "192.168.0.23");
    List<Service> list = query.list();
    for (Service s : list) {
      System.out.println(s.getId() + " " + s.getOsUserName() + " "
          + s.getUnixHost());
    }
    session.close();
  }
  // 等价于testFind1,采用“:标识符”替代
  @Test
  public void testFind2() {
    String hql = "from Service where account.id=:aid and unixHost=:host";
    Session session = HibernateUtil.getSession();
    Query query = session.createQuery(hql);
    query.setInteger("aid", 1011);
    query.setString("host", "192.168.0.23");
    List<Service> list = query.list();
    for (Service s : list) {
      System.out.println(s.getId() + " " + s.getOsUserName() + " "
          + s.getUnixHost());
    }
    session.close();
  }</span> 

b、只查询一部分属性

--默认返回的集合中封装的是Object[]
            --new Service(id,unixHost,osUserName)使返回的结合中封装的是Service对象,

注意:

Service中需要追加响应的构造器;

不要丢掉无参构造器;

示例代码:

<span style="font-size:14px;">    // 获取部分字段结果,默认采用Object[]封装数据
  @Test
  public void testFind3() {
    String hql = "select s.id,s.unixHost,s.osUserName from Service s where s.account.id=?";
    Session session = HibernateUtil.getSession();
    Query query = session.createQuery(hql);
    query.setInteger(0, 1011);
    List<Object[]> list = query.list();
    for (Object[] objs : list) {
      System.out.println(objs[0] + " " + objs[1] + " " + objs[2] + " ");
    }
    session.close();
  }
  // 等价于testFind3,需要添加对应的构造方法
  @Test
  public void testFind4() {
    String hql = "select new Service(s.id,s.unixHost,s.osUserName) from Service s where s.account.id=?";
    Session session = HibernateUtil.getSession();
    Query query = session.createQuery(hql);
    query.setInteger(0, 1011);
    List<Service> list = query.list();
    for (Service s : list) {
      System.out.println(s.getId() + " " + s.getOsUserName() + " "
          + s.getUnixHost());
    }
    session.close();
  }</span> 

c、HQL定义在配置文件中(了解即可)

--通过query元素在配置文件中定义HQL
            --query元素写在class的后面
            --session.getNamedQuery(HQL名);

示例代码:<query/>与<class/>在hbm.xml中同级摆放

<span style="font-size:14px;"><query name="findAll"><!-- CDATA内包括纯文本字段,防止出现特殊字符 -->
  <![CDATA[
  from Service
  ]]>
  </query></span>
<span style="font-size:14px;">    // 将HQL定义到hbm.xml中(只适用静态HQL语句结构)
  @Test
  public void testFind5() {
    Session session = HibernateUtil.getSession();
    // 获取hbm.xml中<query>定义的hql语句
    Query query = session.getNamedQuery("findAll");
    List<Service> list = query.list();
    for (Service s : list) {
      System.out.println(s.getId() + " " + s.getOsUserName() + " "
          + s.getUnixHost());
    }
    session.close();
  }</span> 

    d、分页查询

--查询记录

query.setFirstResult((page-1)*pageSize);

query.setMaxResults(pageSize);

--查询总页数

select count(*) from Service

示例代码:

<span style="font-size:14px;">    // 测试分页查询
  @Test
  public void testFind6() {
    int page = 2;
    String hql = "from Service order by id";
    Session session = HibernateUtil.getSession();
    Query query = session.createQuery(hql);
    // 追加分页参数设置
    query.setFirstResult((page - 1) * 3);// 设置抓起记录的起点,从0开始
    query.setMaxResults(3);// 设置最大抓取数量
    List<Service> list = query.list();// 执行查询,如果没有分页设置就查所有值
    for (Service s : list) {
      System.out.println(s.getId() + " " + s.getOsUserName() + " "
          + s.getUnixHost());
    }
    session.close();
  }
  // select count(*) from SERVICE
  @Test
  public void testFind7() {
    String hql = "select count(*) from Service";
    Session session = HibernateUtil.getSession();
    Query query = session.createQuery(hql);
    Long size = (Long) query.uniqueResult();
    System.out.println("记录总数:" + size);
    session.close();
  }</span> 

   e、关联查询(记住一种即可)

--from Service s,Account a

where s.account.id=a.id

--from Service s inner join s.account a

--select s.account.realName from Service s

   总结:

 HQL与SQL的相同点

--支持select,from,where,group,order by子句

--支持inner join,left join等连接

--支持>,<,>=,<=,in,not in,between,like等条件

--支持分组统计函数count,sum,max,min,avg

HQL与SQL的不同点

--HQL语句区分大小写,即大小写敏感。关键字不区分。

--HQL中写的是对象名和属性名,而不是表名和字段名

--不支持join on中的on子句

--不支持select *

--不支持数据库函数,比如日期函数to_date()、字符函数to_char()等

2)Criteria查询(不够直观,了解即可)

使用Hibernate的API来拼一个HQL

Criteria c = session.createCriteria(Service.class);

示例代码:

<span style="font-size:14px;">    // 使用Hibernate的API来拼一个HQL
  @Test
  public void testFind1() {
    Session session = HibernateUtil.getSession();
    Criteria c = session.createCriteria(Service.class);
    c.add(Restrictions.and(Restrictions.like("osUserName", "huang%"),
        Restrictions.eq("unixHost", "192.168.0.26")));// 追加查询条件
    List<Service> list = c.list();// 执行查询,如果没有分页设置就查所有值
    c.addOrder(Order.desc("id"));// 追加排序
    // c.setFirstResult(arg0);//分页
    // c.setMaxResults(arg0);
    for (Service s : list) {
      System.out.println(s.getId() + " " + s.getOsUserName() + " "
          + s.getUnixHost());
    }
    session.close();
  }</span> 

    3)SQL查询

直接帮助我们调用JDBC来执行SQL查询

SQLQuery sqlQuery = session.createSQLQuery(sql);

示例代码:

<span style="font-size:14px;">    @Test
  public void testFind1() {
    String sql = "select * from Service";
    Session session = HibernateUtil.getSession();
    SQLQuery sqlQuery = session.createSQLQuery(sql);
    sqlQuery.setFirstResult(0);// 分页
    sqlQuery.setMaxResults(3);
    // 默认采用数组封装一条记录
    List<Object[]> list = sqlQuery.list();
    for (Object[] objs : list) {
      System.out.println(objs[0] + " " + objs[2]);
    }
    session.close();
  }
  //同testFind1(),指定封装记录的实体
  @Test
  public void testFind2() {
    String sql = "select * from Service";
    Session session = HibernateUtil.getSession();
    SQLQuery sqlQuery = session.createSQLQuery(sql);
    sqlQuery.setFirstResult(0);// 分页
    sqlQuery.setMaxResults(3);
    // 指定封装记录的实体类
    sqlQuery.addEntity(Service.class);
    // 采用指定的Service类型封装一条记录
    List<Service> list = sqlQuery.list();
    for (Service s : list) {
      System.out.println(s.getId() + " " + s.getOsUserName());
    }
    session.close();
  }</span> 

8、Hibernate高级特性(了解)

1)二级缓存

a、二级缓存(默认关闭)

--二级缓存是SessionFactory级别的缓存,由SessionFactory负责管理

--缓存的也是实体对象
            --缓存数据可以被不同的Session间共享
            --适用环境:对象数据频繁共享;对象数据变化频率小

b、二级缓存的使用步骤
            --导缓存包ehcache.jar
            --导入缓存配置文件ehcache.xml
            --在hibernate.cfg.xml中,设置开启二级缓存,并且设置缓存驱动类

<span style="font-size:14px;"><!-- 使用二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- 指定二级缓存组件的驱动类ehcache.jar -->
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property></span> 

--在要缓存的POJO的关系映射文件hbm.xml中设置元素<cache usage="readonly"/>

示例代码:

<span style="font-size:14px;"><span style="font-size:14px;">    @Test
  public void testFind1() {
    // 第一次查询,使用session1
    Session session1 = HibernateUtil.getSession();
    Service s1 = (Service) session1.get(Service.class, 2002);
    System.out.println(s1.getOsUserName() + " " + s1.getUnixHost());
    session1.close();
    // 第二次查询,使用session2(配置二级缓存后,两次查询均到二级缓存中取数据)
    // HibernateUtil.getSessionFactory().evict(Service.class);// 移除后则还是查询两次
    Session session2 = HibernateUtil.getSession();
    Service s2 = (Service) session2.get(Service.class, 2002);
    System.out.println(s2.getOsUserName() + " " + s2.getUnixHost());
  }</span></span> 

  2)查询缓存

a、查询缓存

一级和二级缓存只能是缓存单个对象。如果遇到某个字符串结果、数组结果或者List集合,可以使用查询缓存存储。
            --可以看成是特殊的二级缓存
            --使用的是二级缓存的缓存空间
            --缓存的是除实体对象之外的数据类型
            --依赖于二级缓存,默认是关闭的,需开启二级缓存才能使用。

b、使用步骤

--开启二级缓存
            --在hibernate.cfg.xml中设置开启查询缓存

<span style="font-size:14px;"><!-- 开启查询缓存 -->
<property name="hibernate.cache.use_query_cache">true</property></span> 

--query.list()查询之前,设置允许进行查询缓存,query.setCacheable(true);

 c、使用环境

--需要频繁执行的相同的查询语句
            --查询结果集内容改变频率小
            --结果集数据量不要太多
        提示:相同的SQL,第一次去数据库查询,后续几次从缓存取出。因为缓存的是SQL+结果集内容

示例代码:

<span style="font-size:14px;"><span style="font-size:14px;">    @Test
  public void testFind() {
    find();
    System.out.println("-------");
    find();
  }
  private void find() {
    String hql = "from Service where account.id=?";
    Session session = HibernateUtil.getSession();
    Query query = session.createQuery(hql);
    query.setInteger(0, 1011);
    // 启用查询缓存执行
    query.setCacheable(true);
    List<Service> list = query.list();
    for (Service s : list) {
      System.out.println(s.getId() + " " + s.getOsUserName());
    }
  }</span></span> 

9、Hibernate并发处理-加锁

举例:

模拟12306购票机制,假设当前有一张火车票的表tickets(id,line,amount,version),模拟多人同时购票的场景。

    1)悲观锁

--程序悲观的认为,每个访问者都存在并发的问题,于是会对每条数据加锁,那么只有当前持有锁的访问者释放该锁时,下一个访问者才能访问数据,这种机制称之为悲观锁。

--就是说无论如何都要给一条数据加锁,不管该数据是否会发生并发的问题。

--特点

效率低,安全性高

--实现:

get(Class,id,LockMode.UPGRADE)
            select * from emp for update

注:这里利用的是数据库自带的for update子句进行加锁,并非是Hibernate自己发明的加锁机制。

    2)乐观锁

--程序乐观的认为,每个访问者都不会有并发的问题产生,因此不去加锁。而是当数据更新时,判断该数据是否发生了版本的变化,如果发生变化,则说明在此期间有并发产生,因此报错给予提示,本次更新失败。
        --借助版本字段,当第一个用户更新提交后,Hibernate会将该字段更新加1,这样后续用户提交的对象版本字段比数据库中的小,即在更新时发现版本变了,就抛出异常并更新失败。

--一个成功,其他失败

--特点

效率高,用户体验差

--实现

a、需要在表中追加版本字段,用于记录数据的版本;

b、实体类中追加版本属性;

c、hbm.xml中追加版本的配置<version name="" type="" column="">

3)如何选择

--如果是并发量大的情况,应选择乐观锁

--如果是并发量小的情况,应选择悲观锁

以上所述是小编给大家介绍的 全面解析Hibernate关联操作、查询操作、高级特性、并发处理机制的相关知识,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • 在Java的Hibernate框架中对数据库数据进行查询操作

    Hibernate查询语言(HQL)是一种面向对象的查询语言,类似于SQL,但不是对表和列操作,HQL适用于持久对象和它们的属性. HQL查询由Hibernate转换成传统的SQL查询,这在圈上的数据库执行操作. 虽然可以直接使用SQL语句和Hibernate使用原生SQL,但建议使用HQL尽可能避免数据库可移植性的麻烦,并采取Hibernate的SQL生成和缓存策略的优势. 都像SELECT,FROM和WHERE等关键字不区分大小写,但如表名和列名的属性是区分在HQL敏感. FROM 语句 使

  • Java的Hibernate框架中Criteria查询使用的实例讲解

    我们讲一下Criteria查询,这个对于不是太熟悉SQL语句的我们这些程序员来说是很容易上手的.  废话不多说,看一下例子:  实体类如下: public class User implements Serializable{ private static final long serialVersionUID = 1L; public Long id; private String name; private int age; //省略Get/Set方法 } 映射文件我们就不写了,很简单的一个

  • hibernate 命名查询如何实现

    什么是命名查询? Hibernate允许在映射文件中定义字符串形式的查询语句,这种查询方式成为命名查询 使用命名查询有什么好处? 由于使用Hibernate的HQL常常需要在Java代码中写字符串查询语句,HQL混杂在代码之间,破坏代码可读性,通过使用命名查询,可以使业务逻辑和查询语句分离,使您专注于查询,而避免了 SQL 或者 HQL 代码分散于整个应用程序中的情况. 可以应用命名查询做复杂查询的处理 命名查询如何实现? 介绍下面几种方式: 方法一:在配置文件中<class/>标记的下面,声

  • Hibernate中的多表查询及抓取策略

    1.Hibernate中的多表查询  1.1SQL中的多表查询 [交叉连接] select * from A,B; [内连接] 显示内连接:inner join(inner 可以省略) Select * from A inner join B on 条件; 隐式内连接: Select * from A,B where 条件; [外连接] 左外连接:left outer join Select * from A left outer join B on 条件; 右外连接:right outer j

  • springmvc4+hibernate4分页查询功能实现

    Springmvc+hibernate成为现在很多人用的框架整合,最近自己也在学习摸索,由于我们在开发项目中很多项目都用到列表分页功能,在此参考网上一些资料,以springmvc4+hibnerate4边学边总结,得出分页功能代码,虽然不一定通用,对于初学者来说有参考价值. 分页实现的基本过程: 一.分页工具类 思路: 1.编写Page类,定义属性,应该包括:查询结果集合.查询记录总数.每页显示记录数.当前第几页等属性. 2.编写Page类,定义方法,应该包括:总页数.当前页开始记录.首页.下一

  • Java Hibernate中使用HQL语句进行数据库查询的要点解析

    一.实体对象查询 实体对象查询是hql查询的基础,作为一种对象查询语言,在查询操作时和sql不同,查询字符串中的内容要使用类名和类的属性名来代替.这种查询方法相对简单,只要有SQL功底,使用hql是很简单的,但是有一些问题需要注意,就是查询获取数据不是目的,需要考虑的是如何编写出高效的查询语句,这才是讨论的重点. 1.N+1问题 (1)什么是N+1问题 在刚听到这个名词时疑惑可能是有的,以前根本就没有听过N+1问题,那么它是指什么呢?N+1指的是一张表中有N条数据,那么在获取这N条数据时会产生N

  • Java的Hibernate框架数据库操作中锁的使用和查询类型

     Hibernate与数据库锁 一.为什么要使用锁? 要想弄清楚锁机制存在的原因,首先要了解事务的概念. 事务是对数据库一系列相关的操作,它必须具备ACID特征: A(原子性):要么全部成功,要么全部撤销. C(一致性):要保持数据库的一致性. I(隔离性):不同事务操作相同数据时,要有各自的数据空间. D(持久性):一旦事务成功结束,它对数据库所做的更新必须永久保持. 我们常用的关系型数据库RDBMS实现了事务的这些特性.其中,原子性. 一致性和持久性都是采用日志来保证的.而隔离性就是由今天我

  • Hibernate 查询方式总结

    1. get() and load() Java代码 session.get(Clazz, id); session.load(Clazz, id); session.get(Clazz, id); session.load(Clazz, id); 说明: load()与get()的区别 请注意如果没有匹配的数据库记录,load()方法可能抛出无法恢复的异常(unrecoverable exception). 如果类的映射使用了代理(proxy),load()方法会返回一个未初始化的代理,直到你

  • 全面解析Hibernate关联操作、查询操作、高级特性、并发处理机制

    本文所需的数据库初始文件,Hibernate常用操作的完整示例代码(包含所有Hibernate操作所需jar文件)提供下载学习:http://download.csdn.net/detail/daijin888888/9551724 1.Hibernate关联映射   1)什么是关联映射? 如果表之间具有关联关系,Hibernate允许我们在hbm.xml中描述他们的关联关系,然后在我们操作其中一张表时,自动的根据这种关系操作到另外的关系表,那么这种关联关系的设置,我们称之为关联映射.     

  • hibernate增删改查操作代码

    Hibernate对数据删除操作 删除User表中个一条数据,是需要更具User表的主键id值来删除的.首先根据id值向数据库中查询出来对应的对象.可以采用两种方式一是session的get方法,一个是session的load方法. Session的Get方法:调用这个方法会返回一个Object对象.然后我们对其强制转换.Useruser = (User)session.get(User.class," 402881e5441c035e01441c0360510003"); 当我们传递

  • YII框架关联查询操作示例

    本文实例讲述了YII框架关联查询操作.分享给大家供大家参考,具体如下: 以customer order两个表为例 关联查询控制器中 $customer = Customer::find()->where('name'=>'zhangsan')->one(); $orders = $customer->hasmany('orders',['customer_id']=>'id')->asArray()->all(); $orders = $customer->

  • MongoDB多表关联查询操作实例详解

    本文实例讲述了MongoDB多表关联查询操作.分享给大家供大家参考,具体如下: Mongoose的多表关联查询 首先,我们回忆一下,MySQL多表关联查询的语句: student表: calss表: 通过student的classId关联进行查询学生名称,班级的数据: SELECT student.name,student.age,class.name FROM student,class WHERE student.classId = class.id Mongoose多表联合查询(还是以众所

  • yii框架数据库关联查询操作示例

    本文实例讲述了yii框架数据库关联查询操作.分享给大家供大家参考,具体如下: <?php namespace app\controllers; use yii\web\Controller; use app\models\Customer; class CustomerController extends Controller{ //根据顾客名字查询出所有的订单信息 public function actionIndex(){ $customer = Customer::find()->whe

  • MongoDB查询之高级操作详解(多条件查询、正则匹配查询等)

    MongoDB查询之高级操作 语法介绍 MongoDB查询文档使用find()方法,同时find()方法以非结构化的方式来显示所有查询到的文档. -- 1.基本语法 db.collection.find(query, projection) -- 返回所有符合查询条件的文档 db.collection.findOne(query, projection) -- 返回第一个符合查询条件的文档 -- query:可选,查询条件操作符,用于指定查询条件 -- projection:可选,投影操作符,用

  • Python模型聚合查询\Q查询\F查询\分组查询操作技巧解析

    目录 模型中的一些查询操作: 1.聚合查询:aggregate()是QuerySet 的一个终止子句 2.Q查询: 如果你需要执行更复杂的查询(例如OR语句) 3.F查询: (查询的是一整列数据!) 4.分组查询 4.1一对多关系 4.2多对多关系 模型中的一些查询操作: 1.聚合查询:aggregate()是QuerySet 的一个终止子句 它返回一个包含一些键值对的字典 from movie.models import User from django.db.models import Co

  • django模型查询操作的实现

    目录 1.创建对象 2.保存ForeignKey和ManyToManyField字段 3.检索对象 跨越多值的关系查询 使用F表达式引用模型的字段: 4.缓存和查询集 5.使用Q对象进行复杂查询 6.比较对象 7.删除对象 8.复制模型实例 9.批量更新对象 10.关系的对象 反向查询: 11.使用原生SQL语句 一旦创建好了数据模型,Django就会自动为我们提供一个数据库抽象API,允许创建.检索.更新和删除对象操作 下面的示例都是通过下面参考模型来对模型字段进行操作说明: from dja

  • php mysql PDO 查询操作的实例详解

    php mysql PDO 查询操作的实例详解 <?php $dbh = new PDO('mysql:host=localhost;dbname=access_control', 'root', ''); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $dbh->exec('set names utf8'); /*添加*/ //$sql = "INSERT INTO `user` SET `log

  • 数据库表的查询操作(实验二)

    [实验目的]:了解SQL语言的使用,进一步理解关系运算,巩固数据库的基础知识. [实验要求]:掌握利用Select语句进行各种查询操作:单表查询.多表连接及查询.嵌套查询.集合查询等. [实验内容] 一.单表查询 1.简单查询 打开查询分析器,根建立teacher表,并加入数据.从teacher表中分别检索出教师的所有信息,以及仅查询教工号.姓名和职称.语句如下: select * from teacher select tno, tname from teacher 如要查询时改变列标题的显示

随机推荐