Hibernate框架

idea 配置Hibernate:
在这里插入在这里插入图片描述图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意:每个表需要设主键,不然掭的pojo类会报错

然后导入数据库驱动:
pom.xml

//MySql 驱动
<dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.6</version>
</dependency>
//Oracle驱动
<dependency>
      <groupId>cn.easyproject</groupId>
      <artifactId>ojdbc7</artifactId>
      <version>12.1.0.2.0</version>
</dependency>

如果生成的mapping.xml文件,又没在resource文件里,需要在pom.xml添加:

<resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
        </includes>
      </resource>
    </resources>

然后在hibernate.cfg.xml文件里添加用户名和密码:

    <!--值设为thread,采用sessionFactory的getCurrentSession()方法获得的Session对象,不需要执行close()方法,会在事务结束时自动关闭-->
    <!--此配置在多线程中可以获得线程安全的Session对象,为每个线程绑定一个Session,每个线程使用自己独立的Session-->
     <property name="current_session_context_class">thread</property>
    
    <!--  mysql连接URL  -->
    <property name="connection.url">jdbc:mysql://localhost:3306/sale?useUnicode=true&amp;characterEncoding=UTF-8&amp;useSSL=true</property>

    <!--  mysql驱动  -->
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
   
    <!--  mysql账户名  -->
    <property name="connection.username">root</property>

    <!--  mysql密码  -->
    <property name="connection.password">root</property>


    <!--  数据库方言  -->
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

    <!--  显示sql语句  -->
    <property name="show_sql">true</property>

<!--在控制台输出SQL语句-->
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.format_sql">true</property>
    
    <mapping class="cn.kgc.pojo.User"/>
<!--值设为thread,采用sessionFactory的getCurrentSession()方法获得的Session对象,不需要执行close()方法,会在事务结束时自动关闭-->
<!--此配置在多线程中可以获得线程安全的Session对象,为每个线程绑定一个Session,每个线程使用自己独立的Session-->
<property name="current_session_context_class">thread</property>

<!--  Oracle连接URL  -->
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>

<!--  Oracle驱动  -->
<property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
 
 <!-- Oracle 账户名  -->
<property name="connection.username">c##zeng</property>
 
 <!--  Oracle l密码  -->
<property name="connection.password">123456</property>

<!--在控制台输出SQL语句-->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>

<mapping class="cn.kgc.pojo.User"/>

有外键关系的pojo属性生成的关联对象需要在get方法上把@JoinColumn注解加上:,insertable=false,updatable=false

@ManyToOne
@JoinColumn(name = "SGRADE", referencedColumnName = "GID",insertable=false,updatable=false)
public Grade getGradeBySgrade() {
    return gradeBySgrade;
}

也可以在新键数据库连接的时候不要有外键关系的字段:
在这里插入图片描述
JAVA运用:
hibernate.cfg.xml配置

<!--值设为thread,采用sessionFactory的getCurrentSession()方法获得的Session对象,不需要执行close()方法,会在事务结束时自动关闭-->
<!--此配置在多线程中可以获得线程安全的Session对象,为每个线程绑定一个Session,每个线程使用自己独立的Session-->
<property name="current_session_context_class">thread</property>
public void name() {
        Configuration configuration = new Configuration().configure();//创建配置对象
        SessionFactory sessionFactory = configuration.buildSessionFactory();//创建会话工厂
        //Session session = sessionFactory.openSession();//开启会话
        Session session=sessionFactory.getCurrentSession();  //开启会话,结合配置文件可以不用手动关闭Session
        Transaction transaction = session.beginTransaction();//开启事务
        Query query =  session.createQuery("from User ");
        List<User> bankUserList = query.list();
        User user=session.get(User.class,1L);   //主键获取指定对象,如果没有数据返回null,不会延迟加载
        //User user1=session.load(User.class,1L); //主键获取指定对象,如果没有数据会报错,会延迟加载
        session.delete(user);        //删除
        session.save(user);         //增加
        //session.update(user);     //更新数据,用于将游离状态的对象恢复为持久状态,同时进行更新数据操作
        //session.saveOrUpdate(user);   //更新数据,传入参数是瞬时状态的对象调用save()方法,传入参数是游离状态的对象调用update()方法
        //session.merge(user);  //更新数据,对游离状态的对象和瞬时状态的对象都不影响
        //session.flush();        //刷新缓存,触发脏检查,视情况执行相关的SQL语句
        transaction.commit();       //提交事务,会先调用session.flush()方法,减少访问数据库的频率,缩短当前事务对数据库中相关资源的锁定时间。
        //transaction.rollback();     //回滚事务
        //session.close();
        //sessionFactory.close();
        session.evict(user); //会把指定的缓冲对象进行清除
        session.clear();    //把缓冲区内的全部对象清除,但不包括操作中的对象
        System.out.println(bankUserList.size());
}

动态设置查询参数:

public void name() {
        Configuration configuration = new Configuration().configure();//创建配置对象
        SessionFactory sessionFactory = configuration.buildSessionFactory();//创建会话工厂
        Session session = sessionFactory.openSession();//开启会话
        Transaction transaction = session.beginTransaction();//开启事务
        Stuinfo stuinfo=new Stuinfo();
        StringBuilder stringBuilder=new StringBuilder("from Stuinfo where 1=1");
        //StringBuffer stringBuffer=new StringBuffer();
        //加了select是投影查询,new Stuinfo:将每条查询结果封装成对象,需要构造方法
        //stringBuffer.append("select new Stuinfo(stuname,stuno) from Stuinfo where 1=1");  
        //动态设置HQL
        if(stuinfo.getStuname()!=null && stuinfo.getStuname().length()>0){
            stringBuilder.append("and stuinfo.stuname=:stuname");
        }
        Query query = session.createQuery(stringBuilder.toString());
        query.setProperties(stuinfo);
        
        //分页查询
        query.setFirstResult(0);    //从第几条记录开始,第一条记录的位置,从0开始
        query.setMaxResults(5);     //返回记录的条数
        //获取查询结果集
        List<Stuinfo> bankUserList = query.list();
        //获取查询结果集,缓存机制
        List<Stuinfo> bankUserList = query.iterate();
          //获取查询的唯一结果,如果不是唯一会报错
        Stuinfo  stuinfo = (Stuinfo) query.uniqueResult();
}
public void test() {
        Configuration configuration = new Configuration().configure();//创建配置对象
        SessionFactory sessionFactory = configuration.buildSessionFactory();//创建会话工厂
        Session session = sessionFactory.openSession();//开启会话
        Transaction transaction = session.beginTransaction();//开启事务

        Stuinfo stuinfo1=new Stuinfo();
        //:stuname:字段名是HQL语句占位符,尽量用这种
        String sql="from Stuinfo where stuname=:stuname";
        Query query1=session.createQuery(sql);
        //补全参数的值
        query1.setParameter("stuname","zsc");
        //绑定命名参数与一个对象的属性值,自动把对象的stuname属性值与命名参数绑定
        query1.setProperties(stuinfo1);
        //补全参数的值,参数是String类型。
        query1.setString("stuname","zsc");
        //?:HQL语句占位符	
        String sql1="from Stuinfo where stuname=?";
        Query query2=session.createQuery(sql1);
        query2.setParameter(0,"zsc");     
        //补全参数的值,参数是String类型。
        query1.setString(0,"zsc");        

        Query query =  session.createQuery("from Stuinfo ");
        //Stuinfo info=session.get(Stuinfo.class,1l);  //取指定对象
        List<Stuinfo> bankUserList = query.list();
}

双向关联的增删改操作:
cascade属性
set元素的inverse属性

<set name="usersByRid" inverse="true" cascade="all">
     <key>
          <column name="urole" not-null="true"/>
     </key>
     <one-to-many not-found="ignore" class="cn.kgc.pojo.User"/>
</set>

cascade属性的值:
none:默认值,操作当前对象时,忽略其他关联的对象
save-update:当通过save(),update(),saveOrUpdate()方法时,保存所有关联的对象
delete:当通过delete()方法时,删除所有关联的对象
all:包含save-update,delete的行为

set元素的inverse属性值:
false:默认值,主动方,主动负责维护关联关系
true:让出主动

延迟加载:
lazy属性:
A.类级别:值为true是延迟加载(默认值);false是立即加载

<class name="cn.kgc.pojo.User" table="user" schema="sale" lazy="true">
        <id name="uid" column="uid"/>
        <property name="uname" column="uname"/>
        <property name="upassword" column="upassword"/>

B.一对多关联级别:值为true是延迟加载(默认值),extra增强延迟加载,false是立即加载

<set name="usersByRid" inverse="true" cascade="all" lazy="true">
  <key>
       <column name="urole" not-null="true"/>
  </key>
  <one-to-many not-found="ignore" class="cn.kgc.pojo.User"/>
</set>

C.多对一关联级别:值为proxy是延迟加载(默认值),no-proxy无代理延迟加载,false是立即加载

<many-to-one name="roleByUrole" class="cn.kgc.pojo.Role" lazy="proxy">
     <column name="urole" not-null="true"/>
</many-to-one>

HQL支持的常用连接类型:
适用于有关联关系的持久化类,并且在映射文件中做了关联关系映射

内连接:inner join 或 join 
迫切内连接:inner join fetch 或 join fetch
左外连接:left outer join 或 left join
迫切左外连接:left outer join fetch 或 left join fetch
右连接:right outer join 或 right join

常用聚合函数:

count():统计记录条数
sum():求和
min():求最小值
max():求最大值
avg():求平均值

子查询:
子查询应用在HQL语句的where子句中,子查询语句需放在()里面,如:

//查询工资高于平均工资的员工
from emp e where e.salary>(select avg(salary) from emp)

all:子查询语句返回的所有记录
any:子查询语句返回的任意一条记录
some:与“any”意思相同
in:与“=any”意思相同
exists:子查询语句至少返回一条记录

操作集合的函数或属性:

size() 或 size:获取集合中元素的数目
minIndex()  或 minIndex:对于建立了索引的集合,获得最小的索引
maxIndex() 或 maxIndex:对于建立了索引的集合,获得最大的索引
minElement() 或 minElement:对于包含基本类型元素的集合,获得集合中取值最小的元素
maxElement() 或 maxElement:对于包含基本类型元素的集合,获得集合中取值最大的元素
elements():获取集合中所有的元素

优化查询性能:
1,Hibernate查询优化:
a,使用迫切左外连接或迫切内连接查询策略,配置二级缓存和查询缓存等方式,减少select语句的数目,降低访问数据库的频率
b,使用延迟加载等方式避免加载多余的不需要访问的数据
c,使用Query接口的iterate()方法减少select语句中的字段,减少访问数据库的数据量,并结合缓存等机制减少数据库访问次数,提高查询效率

2,HQL优化:
a,避免 or 操作的使用不当,如果where子句中有多个条件,并且其中某个条件没有索引,使用or,将导致全表扫描。
b,避免使用 not,如果where子句的条件包含 not关键字,那么执行时该字段的索引实效
c,避免 like 的特殊形式,如果like 以一个“%”或“—”开始,即前模糊,则该字段的索引不起作用
d,避免使用 distinct ,指定distinct会导致在结果中删除重复的行,这会对处理时间造成一定的影响,因此在不要求或允许冗余时,避免使用
e,索引在以下情况下实效,使用时应注意:对字段使用函数,对字段进行计算。

Hibernate注解:
1,Hibernate注解配置持久化类:

@Entity:将一个类声明为一个持久化类
@Table:为持久化类映射指定表(table),目录(catalog)和schema的名称。默认值:持久化类名,不带包名。可以省略,省略时默认表名和持久化类名相同
@Id:声明了持久化类的标识属性(相当于数据表的主键)
@GeneratedValue:定义标识属性的生成策略
@UniqueConstraint:定义表的唯一约束
@Lob:表示属性将被持久化为 Blob 或者 Clob 类型
@Column:将属性映射到数据库字段
@Transient:指定可以忽略的属性,不用持久化到数据库

2,Hibernate注解配置关联关系:

@OneToOne:建立持久化类之间的一对一关联关系
@OneToMany:建立持久化类之间的一对多关联关系
@ManyToOne:建立持久化类之间的多对一关联关系
@ManyToMany:建立持久化类之间的多对多关联关系

如:多对一
fetch = FetchType.LAZY:采用延迟加载,默认值是FetchType.EAGER;
@JoinColumn:指定了维系关系的外键字段

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "urole", referencedColumnName = "rid",insertable=false,updatable=false)
public Role getRoleByUrole() {
    return roleByUrole;
}

如:一对多
mappedBy:将关联关系的控制权交给对方,相当于配置文件中的inverse=“true”,值userByChild:关联的属性名;
cascade = {CascadeType.ALL}:级联操作的类型,可多选,逗号隔开

    @OneToMany(mappedBy = "userByChild",cascade = {CascadeType.ALL})
    public Collection<Master> getMastersByUid() {
        return mastersByUid;
    }

cascade的级联操作的类型:

CascadeType.ALL:包含所有级联操作
CascadeType.REMOVE:级联删除
CascadeType.PERSIST:persist()方法级联
CascadeType.MERGE:级联更新
CascadeType.REFRESH:级联刷新

配置二级缓存:
引用:https://www.cnblogs.com/xiaoluo501395377/p/3377604.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值