Hibernate笔记2

[捷稀 JCG Q30 Pro 刷机说明] 以刷入openwrt24.10为例 摘要: 本文详细介绍了捷稀JCG Q30 Pro路由器刷入OpenWrt 24.10系统的步骤。通过先刷入OpenWrt 23.05过渡固件,再升级Uboot,最后通过TFTP加载工厂镜像完成刷机。关键步骤包括解锁分区、刷写Uboot、进入恢复模式及配置网络。文章还提供了无线设置、Tailscale内网穿透等进阶命令,并附参考文档和固件下载链接。适用于有一定技术基础的玩家,需注意操作风险,严格按流程执行。 阅读详情

 

 

 

 

 

u  hibernate是什么?

1.    hibernate 是一个框架(framework)

2.    hibernate 是一个orm框架 []

l  orm (object relation mapping) 对象关系映射框架

 

o object -> 业务层(只对对象操作)

r relation-> 关系数据库

m mapping 对象关系映射文件

3.    hibernate 处于我们项目的持久层位置(正因为如此,所以有人又把hibernate称为 持久层框架)

4.    hibernate 实际上就是对jdbc进行了轻量级的封装.

5.    hibernate 的基础还是我们java 反射机制

 

l  除了hiberante 这个orm框架,还有一些:

apache ojb / toplink / ibatis / ejb cmp

Apache OJB ()

  Cayenne ()

  Jaxor ()

  Hibernate ()

  iBatis ()

  jRelationalFramework()

  mirage ()

  SMYLE ()

  TopLink ()

 

 

把对象持久化: 把对象的信息保存到数据库或者是文件.

 

总结: hibernate 是对jdbc进行轻量级封装的  orm 框架,充当项目的持久层.

 

u  为什么需要hibernate?

 

 

u  快如入门案例:

 

hiberante 可以用在 j2se 项目,也可以用在 j2ee(web项目中)

struts是web框架,所以用在 web项目

 

我们使用手动配置hibernate方式开发一个hibernate 项目,完成crud操作 。

 

开发流程

1.    创建一个项目

2.    画出一个简单项目框架示意图

3.    引入hibernate 开发包 (从网上下载google  hibernate  http://www.hibernate.org),完后我们

4.    开发hibernate 有三种方法(开发顺序)

我们使用第二种开发项目

创建employe 表.

create table employee(

id number primary key,

name varchar2(64) not null,

email varchar2(64) not null,

hiredate date not null)

 

创建一个序列,将来用于主键的自增长 :

--创建一个序列

create sequence emp_seq

start with 1

increment by 1

minvalue 1

nomaxvalue

nocycle

nocache

 

5.    开发domain对象和对象关系映射文件

 

对象关系映射文件: 作用是用于指定 domain对象和表的映射关系. ,该文件的取名有规范:

domain对象.hbm.xml,一般我们放在 和domain对象同一个文件夹下(包下)

 

我们的Employee.hbml.xml配置文件 :

<!DOCTYPE hibernate-mapping PUBLIC

       "-//Hibernate/HibernateMapping DTD 3.0//EN"

       "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 

<hibernate-mappingpackage="com.hsp.domain">

       <classname="Employee" table="employee">

       <!--id元素用于指定主键属性 -->

       <idname="id" column="id"type="java.lang.Integer">

       <!--该元素用于指定主键值生成策略hilonative increment sequence uuid -->

       <generatorclass="sequence">

       <paramname="sequence">emp_seq</param>

       </generator>

       </id>

       <!--对其它属性还有配置-->

       <propertyname="name" type="java.lang.String">

       <columnname="name" not-null="false"  />

       </property>

       <propertyname="email" type="java.lang.String" >

       <columnname="email" not-null="false"/>

       </property>

       <propertyname="hiredate" type="java.util.Date">

       <columnname="hiredate" not-null="false" />

       </property>

       </class>

      

</hibernate-mapping>

 

6.    手动配置我们的hibernate.cfg.xml文件,该文件用于配置 连接的数据库的类型,driver,

,用户名,密码 ,url ....同时管理 对象关系映射文件 ,该文件的名称,我们一般不修改.

 

hibernate.cfg.xml配置文件

<?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">

<hibernate-configuration>

<session-factory>

       <!--hibernate 设计者,给我们提供了一写常用的配置 -->

       <!--配置使用的driver-->

       <propertyname="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>

       <propertyname="connection.username">scott</property>

       <propertyname="connection.password">tiger</property>

       <propertyname="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:orclhsp</property>

       <!--配置dialect方言,明确告诉hibernate连接是哪种数据库 -->

       <propertyname="dialect">org.hibernate.dialect.OracleDialect</property>

       <!--显示出对于sql-->

       <propertyname="show_sql">true</property>

       <!--指定管理的对象映射文件-->

       <mappingresource="com/hsp/domain/Employee.hbm.xml"/>

</session-factory>

</hibernate-configuration>

 

7.    测试文件TestMain.java

package com.hsp.view;

import com.hsp.util.*;

import java.util.Date;

 

 

 

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

import org.hibernate.cfg.*;

 

import com.hsp.domain.Employee;

public class TestMain {

 

       /**

        * @param args

        */

       publicstatic void main(String[] args) {

              //查询[load]->hql语句(hibernate query language)

       }

       publicstatic void delEmp() {

              //删除

              //获取一个session

              Sessionsession=MySessionFactory.getSessionFactory().openSession();

              Transactionts=session.beginTransaction();

              //删除1.先获取该雇员,然后删除

              Employee emp=(Employee)session.load(Employee.class, 3);

              session.delete(emp);

              ts.commit();

              session.close();

       }

 

 

 

       publicstatic void updateEmp() {

              // TODO Auto-generated method stub

              //修改用户

              //获取一个会话

              Sessionsession=MySessionFactory.getSessionFactory().openSession();

             

              Transactionts=session.beginTransaction();

              //修改用户1. 获取要修改的用户,2.修改

              //load是通过主键属性,获取该对象实例.<--->表的记录对应

              Employee emp=(Employee)session.load(Employee.class, 3);

              emp.setName("韩顺平8");//update...

              emp.setEmail("abc@sohu.com");

              ts.commit();

              session.close();

       }

 

      

      

       publicstatic void addEmployee() {

              //我们使用hibernate完成crud操作[这里我们只见对象,不见表]

              //现在我们不是用service ,直接测试.

              //1。创建Configuration,该对象用于读取hibernate.cfg.xml,并完成初始化

              Configuration configuration=newConfiguration().configure();

              //2.创建SessoinFactory[这是一个会话工厂,是一个重量级的对象]

              SessionFactorysessionFactory=configuration.buildSessionFactory();

              //3.创建Sessoin 相当于jdbc Connection[ servelt HttpSession ,也不是 jsp session]

              Sessionsession=sessionFactory.openSession();

              //4.对hiberate而言,要求程序员,在进行 增加,删除,修改的时候使用事务提交,

              Transaction transaction =session.beginTransaction();

              //添加一个雇员

              Employee employee=new Employee();

              employee.setName("shunping");

              employee.setEmail("shunping@sohu.com");

              employee.setHiredate(new Date());

              //insert .............

              //保存

              session.save(employee);//save employee就是持久化该对象 (把对象保存到了数据库中称为一条记录)

              //==>insert into ....[被hiberante封装]

              //提交

              transaction.commit();

              session.close();

       }

 

}

 

u  现在我们体验一下hibernate切换数据库的优势.

这次,我们使用 让hibernate自动完成 domain->映射文件->表 的工作.

1.    首先我们把  hibernate.cfg.xml文件重新配置.

<?xml version="1.0"encoding="utf-8"?>

<!DOCTYPE hibernate-configuration PUBLIC

        "-//Hibernate/Hibernate ConfigurationDTD 3.0//EN"

       "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

       <!--hibernate 设计者,给我们提供了一写常用的配置 -->

       <!--配置使用的driver-->

       <propertyname="connection.driver_class">com.mysql.jdbc.Driver</property>

       <propertyname="connection.username">root</property>

       <propertyname="connection.password">root</property>

       <propertyname="connection.url">jdbc:mysql:/localhost:3306/test</property>

       <!--配置dialect方言,明确告诉hibernate连接是哪种数据库 -->

       <propertyname="dialect">org.hibernate.dialect.MySQLDialect</property>

       <!--显示出对于sql-->

       <propertyname="show_sql">true</property>

       <!--让hibernate给我们自动创建表 create :如果没有该表则创建. -->

       <propertyname="hbm2ddl.auto">create</property>

       <!--指定管理的对象映射文件-->

       <mappingresource="com/hsp/domain/Employee.hbm.xml"/>

</session-factory>

</hibernate-configuration>

2.    对对象映射文件,做了相应的修改.

       <!--对主键生成策略我们做了修改-->

       <idname="id" column="id"type="java.lang.Integer">

       <generatorclass="increment"></generator>

       </id>

 

笔试题: 请列举出hibernate常见的接口和类

 

?请解释什么事pojo类,它有什么要求:

1.    pojo类是和一张表对应

2.    一般我们放在 com.xxx.domain下

3.    pojo 需要一个主键属性(用于标示一个pojo对象)

4.    除了主键属性外,它应当还有其属性,属性的访问权限是private

5.    提供 set /get 方法

6.    它应当有一个无参的构造方法(hibernate 反射)

7.    pojo类其实就是javabean/ 有些老程序员 叫他  date对象

 

 

上机练习:

写一个简单的雇员管理系统.

emp( id , name , tel , birthday ),

可以,进入主界面

 

 

请选择数据库类型

1.    表示 连接 oracle

2.    表示 连接 mysql

3.    表示 连接 sql server

 

 

请选择操作

1.    显示所有雇员

2.    根据id查询指定雇员

3.    修改雇员信息(请先输入id)

4.    根据id 删除雇员.

 

 

* 用户可以多次选择操作.

 

 

 

 

u  hibernate的核心类和接口

①     Configuration 类

它的用处是:

1.    读取hibernate.cfg.xml

2.    管理对象关系映射文件 <mapping resource=””>

3.    加载hibernate 的驱动,url ,用户..

4.    管理hibernate配置信息

 

②     hibernate.cfg.xml

③     对象关系映射文件

④     SessionFactory (会话工厂)

1.    可以缓存sql语句和数据(称为session级缓存)!!

2.    是一个重量级的类,因此我们需要保证一个数据库,有一个SessionFactroy

这里我们讨论一个通过SessionFactory获取 Session的两个方法 openSession() 一个 getCurrentSession();

1.    openSession() 是获取一个新的session

2.    getCurrentSession () 获取和当前线程绑定的session,换言之,在同一个线程中,我们获取的session是同一session,这样可以利于事务控制

如果希望使用getCurrentSession 需要配置 hibernate.cfg.xml中配置.

3.    如何选择

原则:

       ①如果需要在同一线程中,保证使用同一个Session则,使用getCurrentSession()

       ②如果在一个线程中,需要使用不同的Session,则使用opentSession()

4.    通过 getCurrentSession() 获取的session在事务提交后,会自动关闭,通过openSession()获取的session则必须手动关闭

5.    如果是通过getCurrentSession() 获取 sesssion ,进行查询需要事务提交.

 

全局事务和本地事务

jndi

 

l  如何确定你的session有没有及时关闭

windows  cmd netstat –an      [oracle 1521mysql 3306 sql server 1433]

linux/unix  netstat –anp top 

 

⑤     session接口

它的主要功能和作用是:

1.      Session一个实例代表与数据库的一次操作(当然一次操作可以是crud组合)

2.      Session实例通过SessionFactory获取,用完需要关闭。

3.      Session是线程不同步的(不安全),因此要保证在同一线程中使用,可以用getCurrentSessiong()。

4.      Session可以看做是持久化管理器,它是与持久化操作相关的接口

 

u  get vs load

1.     如果查询不到数据,get 会返回 null,但是不会报错, load 如果查询不到数据,则报错ObjectNotFoundException

2.    使用get 去查询数据,(先到一级/二级)会立即向db发出查询请求(select ...), 如果你使用的是 load查询数据,(先到一级、二级))即使查询到对象,返回的是一个代理对象,如果后面没有使用查询结果,它不会真的向数据库发select ,当程序员使用查询结果的时候才真的发出select ,这个现象我们称为懒加载(lazy)

3.    通过修改配置文件,我们可以取消懒加载

<class  name="Employee"lazy="false" table="employee">

4.    如何选择使用哪个: 如果你确定DB中有这个对象就用load(),不确定就用get()(这样效率高)

 

u  我们对获取session的工具类,升级,让它可以直接返回 全新的session和线程相关的session

代码:

packagecom.hsp.util;

importorg.hibernate.Session;

importorg.hibernate.SessionFactory;

importorg.hibernate.cfg.Configuration;

final publicclass HibernateUtil { //SqlHelper

     private static SessionFactorysessionFactory=null;

     //使用线程局部模式

     private static ThreadLocal<Session>threadLocal=new ThreadLocal<Session>();

     private HibernateUtil(){};

     static {

            sessionFactory=newConfiguration().configure("com/hsp/config/hsp.cfg.xml").buildSessionFactory();

     }

    

     //获取全新的全新的sesession

     public static Session openSession(){

            returnsessionFactory.openSession();

     }

     //获取和线程关联的session

     public static Session getCurrentSession(){

           

            Sessionsession=threadLocal.get();

            //判断是否得到

            if(session==null){

                   session=sessionFactory.openSession();

                   //把session对象设置到 threadLocal,相当于该session已经和线程绑定

                   threadLocal.set(session);

            }

            returnsession;

           

           

     }

    

    

}

 

u  query接口

通过query接口我们可以完成更加复杂的查询任务.

举例: 通过用户来查询数据.

快如入门:

Sessionsession=HibernateUtil.getCurrentSession();

              Transactionts=null;

             

              try{

                    

                     ts=session.beginTransaction();

                    

                     //获取query引用[这里 Employee不是表.而是domain类名]

                     //[where 后面的条件可以是类的属性名,也可以是表的字段,安照hibernate规定,我们还是应该使用类的属性名.]

                     Queryquery=session.createQuery("from Employee where namehsp='shunping'");

                     //通过list方法获取结果,这个list会自动的将封装成对应的domain对象

                     //所以我们jdbc进行二次封装的工作没有.

                     List<Employee> list=query.list();

                     for(Employee e: list){

                            System.out.println(e.getAaaid()+""+e.getHiredate());

                     }

                    

                     ts.commit();

                    

              }catch (Exception e) {

                    

                     if(ts!=null){

                            ts.rollback();

                     }

                     throw newRuntimeException(e.getMessage());

              }finally{

                     //关闭session

                     if(session!=null&&session.isOpen()){

                            session.close();

                     }

                    

              }

u  criteria 接口的简单使用

快如入门:

Sessionsession=HibernateUtil.getCurrentSession();

              Transactionts=null;

             

              try{

                    

                     ts=session.beginTransaction();

                    

                     Criteriacri=session.createCriteria(Employee.class).

                     setMaxResults(2).addOrder(Order.desc("id"));

                     List<Employee> list=cri.list();

                     for(Employee e: list){

                            System.out.println(e.getAaaid());

                     }

                    

                     ts.commit();

                    

              }catch (Exception e) {

                    

                     if(ts!=null){

                            ts.rollback();

                     }

                     throw newRuntimeException(e.getMessage());

              }finally{

                     //关闭session

                     if(session!=null&&session.isOpen()){

                            session.close();

                     }

                    

              }

 

u  如何使用eclipse进行hibernate 快速开发

我们以前面讲的对employee表进行crud为例,演示具体用法

 

手动配置:

db(table )->手写domain对象->对象关系映射文件

现在我们希望用工具完成 Domain对象和 关系映射文件的工作.

 

1.    创建web项目

2.    通过myeclipse 提供 数据库浏览器连接到我们的oracle数据库(多人开发)

* 这里请大家小心,如果我们测试

 

你们把自己的数据库通过 db 浏览器连接上

 

引入hibernate开发包.,同时自动创建hibernate.cfg.xml文件,如果希望把hibernate开发包升级,我们可以重新引入包.

 

 

下面我们使用myeclipse提供的逆向工程,自动的创建domain类和对象关系映射文件.

 

 

java对象(属性) <---------1. java类型 2. hibernate types------------->表字段类型

 

拉通练习一把.

 

 

 

 

u  为什么要学习hql(hibernate querylanguage)->这个是官方推荐,功能强大

? 删除

session.delete(对象) -> 批量删除

? 添加

session.save  session.persist

? 修改->批量修改

sessin.update(对象)

 

查询 对象 obj

obj.setXXX();

? 查询

load get

查询所有 性别是男的雇员?

 

u  hql的详解

为了讲解清楚,我模拟一个学生选课系统 ,创建三张表

从创建的三张表,我们看出:

hibernate 设计者推荐我们在设计表的时候,应当每张表有一个主键,而且该主键最好不含业务逻辑, 

 

product 表

id  productNo   name      price

1     bi001       冰箱       1000

2     nj111       电脑       2000 

 

我们现在使用hibernate工具,自动生成 domain 对象 和映射文件,如果我们的表有主外键的关系,则应当先映射主表,再映射从表

 

* uniqueResult方法

如果我们检索一个对象,明确知道最多只有一个对象,则建议使用该方法:

具体用法如下:

Student s=(Student)session.createQuery("from Student wheresid='20050003'").uniqueResult();

                     System.out.println(s.getSname());

*distinct的用法

过滤重复的记录

//比如,显示所有学生的性别和年龄.

                     Listlist=session.createQuery("select distinct sage,ssex fromStudent").list();

                     for(inti=0;i<list.size();i++){

                            Object [] objs=(Object[]) list.get(i);

                            System.out.println(objs[0].toString()+""+objs[1].toString());

                     }

*between and..

List list=session.createQuery("selectdistinct sage,ssex,sname from Student where sage between 20 and22").list();

                     for(inti=0;i<list.size();i++){

                            Object [] objs=(Object[]) list.get(i);

                            System.out.println(objs[0].toString()+""+objs[1].toString()+objs[2].toString());

                     }

*in /not in

//查询计算机系和外语系的学生信息

                    

                     List<Student>list=session.createQuery("from Student where sdept in ('计算机系','外语系')").list();

                     //取出1. for 增强

                     for(Students:list){

                            System.out.println(s.getSname()+""+s.getSaddress()+" "+s.getSdept());

                     }

*group by使用

//显示各个系的学生的平均年龄

List<Object[]>list=session.createQuery("select avg(sage),sdept from  Student group by sdept").list();

                     //取出1. for 增强

                     for(Object[]obj:list){

                            System.out.println(obj[0].toString()+""+obj[1].toString());

                     }

 

 

//having的使用

                     //1.对分组查询后的结果,进行筛选:比如请显示人数大于3的系名称

                     //a.查询各个系分别有多少学生.

                    

                     List<Object[]>list=session.createQuery("select count(*) as c1,sdept from  Student group by sdept havingcount(*)>3").list();

                     //取出1. for 增强

                     for(Object[]obj:list){

                            System.out.println(obj[0].toString()+""+obj[1].toString());

                     }

//2查询女生少于200人的系

                     //a.查询各个系的女生有多个个

                     List<Object[]>list=session.

                     createQuery("selectcount(*) as c1,sdept from  Student wheressex='F' group by sdept").list();

                     //取出1. for 增强

                     for(Object[]obj:list){

                            System.out.println(obj[0].toString()+""+obj[1].toString());

                     }

//1.查询计算机系共多少人?->如果我们返回的是一列数据

                     //这时我们的取法是直接取出list->object 而不是 list->Object[]

                     List<Object[]>list=session.

                     createQuery("selectsage from  Student where sdept='计算机系'").list();

                     //取出1. for 增强

                     for(Objectobj:list){

                            System.out.println(obj.toString());

                     }

3.查询选修11号课程的最高分和最低分.

                     List<Object[]> list=session.

                     createQuery("select11,max(grade),min(grade) from Studcourse where course.cid=11").list();

                     //取出1. for 增强

                     for(Object[] obj:list){

                            System.out.println(obj[0].toString()+"max="+obj[1].toString()+" min="+obj[2].toString());

                     }

//计算各个科目不及格的学生数量.(学生练习!)

                    

                     List<Object[]>list=session.

                     createQuery("selectcount(*),student.sdept from Studcourse where grade<60 group bystudent.sdept").list();

                     //取出1. for 增强

                     for(Object[]obj:list){

                            System.out.println(obj[0].toString()+""+obj[1].toString());

                     }

u  参数绑定案例 (jdbc->PreparedStatement setXXX)

使用参数绑定的好处有3:

1.    可读性提高, 2 效果高 3,防止 sql注入漏洞

? 面试题: 如果不使用参数绑定,怎样防止登录时, sql注入?

name password 

思路: 1. 通过用户名,查询出该用户名在数据库中对应的密码,然后再与用户输入的秘密比较,如果相等,则用户和法,否则,非法.

 

参数绑定有两种形式

Query q=session.createQuery(from Studentwhere sdept=:dept and sage>:age)

 

如果我们的参数是 :冒号形式给出的,则我们的参数绑定应当这样:

List<Student>list=session.createQuery("from Student where sdept=:a1 andsage>:sage")

                     .setString("a1","计算机系").setString("sage","2").list();

还有一种形式:

Query q=session.createQuery(from Studentwhere sdept=? and sage>?)

如果我们的参数是以 ? 形式给出的则,参数绑定应当:

List<Student>list=session.createQuery("from Student where sdept=? and sage>?")

                     .setString(0,"计算机系").setString(1,"2").list();

 

参数的绑定,可以分开写:形式如下:

Query query=session.createQuery("fromStudent where sdept=? and sage>?");

                    

                     query.setString(0,"计算机系");

                     query.setString(1,"2");

                     List<Student> list=query.list();

                     for(inti=0;i<list.size();i++){

                            Student s= list.get(i);

                            System.out.println(s.getSname()+""+s.getSage());

                     }

把HibernateUtil升级了

u  在映射文件中得到hql语句

hibernate提供了一种更加灵活的查询方法:

把hql语句配置到 对象关系映射文件,

<query name="myquerytest">

       <![CDATA[selectsname,ssex from Student where sage>22]]>

       </query>

在程序中,我们这样获取并执行:

Listlist=session.getNamedQuery("myquerytest").list();

              System.out.println(list.size());

              Iterator it=list.iterator();

              while(it.hasNext()){

                     Objectobj[]=(Object[])it.next();

                     System.out.println("n="+obj[0]);

       }

 

hibernate 对象的三种关系:

 

1.    one – to – one : 身份证<--->人

2.    one – to – many  部门 <---> 员工

3.    many-to-one   员工<--->部门

4.    many-to-many  学生<--->老师

 

criterial使用:

//查询年龄大于10岁的学生 criteria

             

              Sessions=HibernateUtil.getCurrentSession();

              Transaction tx=s.beginTransaction();

              Criteriacri=s.createCriteria(Student.class);

              //添加检索条件

              cri.add(Restrictions.gt("sage",new Long(10)));

              List<Student> list=cri.list();

              for(Student s1: list){

                     System.out.println(s1.getSname());

              }

             

              tx.commit();      

 

hibernate开发的三种方式中的:

编写domainobject + 映射文件------> 创建出对应的数据库,

这里我们说明如果要自动的创建出对应的数据库,需要做配置(hibernate.cfg.xml).

<propertyname="hbm2ddl.auto">create</property>

这里有四个配置值:create , update , create-drop, validate

create : 当我们的应用程序加载hibernate.cfg.xml [ new Configuration().config(); ]就会根据映射文件,创建出数据库, 每次都会重新创建, 原来表中的数据就没有!!!

update: 如果数据库中没有该表,则创建,如果有表,则看有没有变化,如果有变化,则更新.

create-drop: 在显示关闭 sessionFactory时,将drop掉数据库的schema

validate: 相当于每次插入数据之前都会验证数据库中的表结构和hbm文件的结构是否一致

 

l  在开发测试中,我们配置哪个都可以测试,但是如果项目发布后,最好自己配置一次,让对应的数据库生成,完后取消配置,

 

 

u  domain对象的细节:

1.    需要一个无参的构造函数(用于hibernate反射该对象)

2.    应当有一个无业务逻辑的主键属性.

3.    给每个属性提供 get set方法.

4.    在domian对象中的属性,只有配置到了对象映射文件后,才会被hiberante管理.

5.    属性一般是private范围

 

u  对对象关系映射文件的说明

对象关系文件中,有些属性是可以不配,hibernate会采用默认机制,比如

<class table=”?” > table 值不配,则以类的小写做表名

<property type=”?”> type不配置,则hibernate会根据类的属性类型,选择一个适当的类型

 

hibernate对象的三种状态,转换图:

面试图:如果判断一个对象处于怎样的状态?

主要的依据是: 1. 看该对象是否处于session, 2, 看在数据库中有没有对应的记录

瞬时态: 没有session管理,同时数据库没有对应记录

持久态: 有session管理,同时在数据库中有记录

脱管态/游离态: 没有session管理,但是在数据库中有记录.

 

u  懒加载:

简述: 当我们查询一个对象的时候,在默认情况下,返回的只是该对象的普通属性,当用户去使用对象属性时,才会向数据库发出再一次的查询.这种现象我们称为 lazy现象.

解决方法可以这样:

1.    显示初始化 Hibernate.initized(代理对象)

2.    修改对象关系文件 lazy  改写 lazy=false

3.    通过过滤器(web项目)openSessionInView

 

u  hibernate对象的关系映射

1.     many-to-one

2.    one-to-many

看一个需求: 通过一个部门号(1),来获取该部门的所有学生?

这里请大家参考代码:

 

3       one-to-one

一对一有有两种方式

(1)    基于主键的一对一

 

原理图 :

 

 

 

(2)   基于外键的一对一

 

原理图 :

 

3.     many-to-many

 

学生<--->课程 就是many-to-many

顾客<--->商品

qq<--->qq群

 

 

上机练习,

请自己想出 生活中

one-to-many

many-to-one

many-to-many

one-to-one

的四组对象关系,并使用hibernate实现写出

对应的domainobject和对象关系映射文件,并通过hbm2ddl 自动创建成功对应的表

 

 

 

 

 

u  为什么要学习hql(hibernate querylanguage)->这个是官方推荐,功能强大

? 删除

session.delete(对象) -> 批量删除

? 添加

session.save  session.persist

? 修改->批量修改

sessin.update(对象)

 

查询 对象 obj

obj.setXXX();

? 查询

load get

查询所有 性别是男的雇员?

 

u  hql的详解

为了讲解清楚,我模拟一个学生选课系统 ,创建三张表

从创建的三张表,我们看出:

hibernate 设计者推荐我们在设计表的时候,应当每张表有一个主键,而且该主键最好不含业务逻辑, 

 

product 表

id  productNo   name      price

1     bi001       冰箱       1000

2     nj111       电脑       2000 

 

我们现在使用hibernate工具,自动生成 domain 对象 和映射文件,如果我们的表有主外键的关系,则应当先映射主表,再映射从表

 

* uniqueResult方法

如果我们检索一个对象,明确知道最多只有一个对象,则建议使用该方法:

具体用法如下:

Student s=(Student)session.createQuery("from Student wheresid='20050003'").uniqueResult();

                     System.out.println(s.getSname());

*distinct的用法

过滤重复的记录

//比如,显示所有学生的性别和年龄.

                     Listlist=session.createQuery("select distinct sage,ssex from Student").list();

                     for(inti=0;i<list.size();i++){

                            Object [] objs=(Object[]) list.get(i);

                            System.out.println(objs[0].toString()+""+objs[1].toString());

                     }

*between and..

List list=session.createQuery("selectdistinct sage,ssex,sname from Student where sage between 20 and22").list();

                     for(inti=0;i<list.size();i++){

                            Object [] objs=(Object[]) list.get(i);

                            System.out.println(objs[0].toString()+""+objs[1].toString()+objs[2].toString());

                     }

*in /not in

//查询计算机系和外语系的学生信息

                    

                     List<Student>list=session.createQuery("from Student where sdept in ('计算机系','外语系')").list();

                     //取出1. for 增强

                     for(Students:list){

                            System.out.println(s.getSname()+""+s.getSaddress()+" "+s.getSdept());

                     }

*group by使用

//显示各个系的学生的平均年龄

List<Object[]> list=session.createQuery("selectavg(sage),sdept from  Student group bysdept").list();

                     //取出1. for 增强

                     for(Object[]obj:list){

                            System.out.println(obj[0].toString()+""+obj[1].toString());

                     }

 

 

//having的使用

                     //1.对分组查询后的结果,进行筛选:比如请显示人数大于3的系名称

                     //a.查询各个系分别有多少学生.

                    

                     List<Object[]>list=session.createQuery("select count(*) as c1,sdept from  Student group by sdept havingcount(*)>3").list();

                     //取出1. for 增强

                     for(Object[]obj:list){

                            System.out.println(obj[0].toString()+""+obj[1].toString());

                     }

//2查询女生少于200人的系

                     //a.查询各个系的女生有多个个

                     List<Object[]>list=session.

                     createQuery("selectcount(*) as c1,sdept from  Student wheressex='F' group by sdept").list();

                     //取出1. for 增强

                     for(Object[]obj:list){

                            System.out.println(obj[0].toString()+""+obj[1].toString());

                     }

//1.查询计算机系共多少人?->如果我们返回的是一列数据

                     //这时我们的取法是直接取出list->object 而不是 list->Object[]

                     List<Object[]>list=session.

                     createQuery("selectsage from  Student where sdept='计算机系'").list();

                     //取出1. for 增强

                     for(Objectobj:list){

                            System.out.println(obj.toString());

                     }

3.查询选修11号课程的最高分和最低分.

                     List<Object[]> list=session.

                     createQuery("select11,max(grade),min(grade) from Studcourse where course.cid=11").list();

                     //取出1. for 增强

                     for(Object[] obj:list){

                            System.out.println(obj[0].toString()+"max="+obj[1].toString()+" min="+obj[2].toString());

                     }

//计算各个科目不及格的学生数量.(学生练习!)

                    

                     List<Object[]>list=session.

                     createQuery("selectcount(*),student.sdept from Studcourse where grade<60 group bystudent.sdept").list();

                     //取出1. for 增强

                     for(Object[]obj:list){

                            System.out.println(obj[0].toString()+""+obj[1].toString());

                     }

u  参数绑定案例 (jdbc->PreparedStatement setXXX)

使用参数绑定的好处有3:

1.    可读性提高, 2 效果高 3,防止 sql注入漏洞

? 面试题: 如果不使用参数绑定,怎样防止登录时, sql注入?

name password 

思路: 1. 通过用户名,查询出该用户名在数据库中对应的密码,然后再与用户输入的秘密比较,如果相等,则用户和法,否则,非法.

 

参数绑定有两种形式

Query q=session.createQuery(from Studentwhere sdept=:dept and sage>:age)

 

如果我们的参数是 :冒号形式给出的,则我们的参数绑定应当这样:

List<Student>list=session.createQuery("from Student where sdept=:a1 andsage>:sage")

                     .setString("a1","计算机系").setString("sage","2").list();

还有一种形式:

Query q=session.createQuery(from Studentwhere sdept=? and sage>?)

如果我们的参数是以 ? 形式给出的则,参数绑定应当:

List<Student>list=session.createQuery("from Student where sdept=? and sage>?")

                     .setString(0,"计算机系").setString(1,"2").list();

 

参数的绑定,可以分开写:形式如下:

Query query=session.createQuery("fromStudent where sdept=? and sage>?");

                    

                     query.setString(0,"计算机系");

                     query.setString(1,"2");

                     List<Student> list=query.list();

                     for(inti=0;i<list.size();i++){

                            Student s= list.get(i);

                            System.out.println(s.getSname()+""+s.getSage());

                     }

把HibernateUtil升级了

u  在映射文件中得到hql语句

hibernate提供了一种更加灵活的查询方法:

把hql语句配置到 对象关系映射文件,

<query name="myquerytest">

       <![CDATA[selectsname,ssex from Student where sage>22]]>

       </query>

在程序中,我们这样获取并执行:

Listlist=session.getNamedQuery("myquerytest").list();

              System.out.println(list.size());

              Iterator it=list.iterator();

              while(it.hasNext()){

                     Objectobj[]=(Object[])it.next();

                     System.out.println("n="+obj[0]);

       }

 

hibernate 对象的三种关系:

 

1.    one – to – one : 身份证<--->人

2.    one – to – many  部门 <---> 员工

3.    many-to-one   员工<--->部门

4.    many-to-many  学生<--->老师

 

criterial使用:

//查询年龄大于10岁的学生 criteria

             

              Sessions=HibernateUtil.getCurrentSession();

              Transaction tx=s.beginTransaction();

              Criteria cri=s.createCriteria(Student.class);

              //添加检索条件

              cri.add(Restrictions.gt("sage",new Long(10)));

              List<Student> list=cri.list();

              for(Student s1: list){

                     System.out.println(s1.getSname());

              }

             

              tx.commit();      

 

hibernate开发的三种方式中的:

编写domainobject + 映射文件------> 创建出对应的数据库,

这里我们说明如果要自动的创建出对应的数据库,需要做配置(hibernate.cfg.xml).

<propertyname="hbm2ddl.auto">create</property>

这里有四个配置值:create , update , create-drop, validate

create : 当我们的应用程序加载hibernate.cfg.xml [ new Configuration().config(); ]就会根据映射文件,创建出数据库, 每次都会重新创建, 原来表中的数据就没有!!!

update: 如果数据库中没有该表,则创建,如果有表,则看有没有变化,如果有变化,则更新.

create-drop: 在显示关闭 sessionFactory时,将drop掉数据库的schema

validate: 相当于每次插入数据之前都会验证数据库中的表结构和hbm文件的结构是否一致

 

l  在开发测试中,我们配置哪个都可以测试,但是如果项目发布后,最好自己配置一次,让对应的数据库生成,完后取消配置,

 

 

u  domain对象的细节:

1.    需要一个无参的构造函数(用于hibernate反射该对象)

2.    应当有一个无业务逻辑的主键属性.

3.    给每个属性提供 get set方法.

4.    在domian对象中的属性,只有配置到了对象映射文件后,才会被hiberante管理.

5.    属性一般是private范围

 

u  对对象关系映射文件的说明

对象关系文件中,有些属性是可以不配,hibernate会采用默认机制,比如

<class table=”?” > table 值不配,则以类的小写做表名

<property type=”?”> type不配置,则hibernate会根据类的属性类型,选择一个适当的类型

 

hibernate对象的三种状态,转换图:

面试图:如果判断一个对象处于怎样的状态?

主要的依据是: 1. 看该对象是否处于session, 2, 看在数据库中有没有对应的记录

瞬时态: 没有session管理,同时数据库没有对应记录

持久态: 有session管理,同时在数据库中有记录

脱管态/游离态: 没有session管理,但是在数据库中有记录.

 

u  懒加载:

简述: 当我们查询一个对象的时候,在默认情况下,返回的只是该对象的普通属性,当用户去使用对象属性时,才会向数据库发出再一次的查询.这种现象我们称为 lazy现象.

解决方法可以这样:

1.    显示初始化 Hibernate.initized(代理对象)

2.    修改对象关系文件 lazy  改写 lazy=false

3.    通过过滤器(web项目)openSessionInView

 

通过openSessionInView来解决懒加载.

many-to-one 的many这方,如果你配置了

<class name="Student"lazy="false">

那么hibernate就会在 查询学生 many 方时,把它相互关联的对象也查询,这里我们可以看出,对select语句查询影响不大,

one-to-many 的one 的这方,如果你配置

<set name="stus"cascade="save-update" lazy="false">

当你去查询一个部门的时候,我们看到:

Hibernate: select department0_.id asid0_0_, department0_.name as name0_0_ from Department department0_ wheredepartment0_.id=?

Hibernate: select stus0_.dept_id asdept3_1_, stus0_.id as id1_, stus0_.id as id1_0_, stus0_.name as name1_0_,stus0_.dept_id as dept3_1_0_ from Student stus0_ where stus0_.dept_id=?

这样就会把该部门关联的学生全部返回,不管你使用否?

矛盾: 如何让我们的session范围更大.(缺点是session关闭会延时.)

 

u  hibernate对象的关系映射

1.     many-to-one

比如  Employe 和 Department

2.    one-to-many

比如  Departmetn 和 Employee

看一个需求: 通过一个部门号(1),来获取该部门的所有学生?

这里请大家参考代码:

 

3       one-to-one

一对一有有两种方式

(1)    基于主键的一对一

Person IdCard

基于主键的one-to-one指的就是 IdCard 这样主键值同时充当外键.

原理图 :

 

 

 

(2)   基于外键的一对一

 

原理图 :

 

3.     many-to-many

 

案例  学生《---》课程

 

学生<--->课程 就是many-to-many

顾客<--->商品

qq<--->qq群

 

 

上机练习,

请自己想出 生活中

one-to-many

many-to-one

many-to-many

one-to-one

的四组对象关系,并使用hibernate实现写出

对应的domainobject和对象关系映射文件,并通过hbm2ddl 自动创建成功对应的表

 

u  级联操作

所谓级联操作就是说,当你进行某个操作(添加/修改/删除...),就由hibernate自动给你完成.

比如: Department <---->Student 对象关系,我希望当我删除一个department ,那么就自动删除该部门的所有学生?

 

再比如: bbs项目

主帖<---->回帖 , 把主帖删除,那我们就希望把该主帖的回帖自动删除,这样我们可以使用级联(cascade)操作

\

案例:如何配置级联操作,当删除某个部门的时候,我们自动删除其学生.

首先我们在 配置文件中修改:

<!-- 配置one-to-many关系

 cascade="delete" 当删除该部门的时候(主对象,则级联删除它的学生从对象) -->

<setname="stus" cascade="delete">

<!-- 指定Student类对应的外键 -->

<keycolumn="dept_id" />

<one-to-manyclass="Student" />

</set>

 

java代码中操作:

//演示删除级联

                     //获取到某个部分

                     Department department=(Department)s.get(Department.class, 41);

                     s.delete(department);

 

u  演示save-update

配置文件:

<setname="stus" cascade="save-update">

<!-- 指定Student类对应的外键 -->

<keycolumn="dept_id" />

<one-to-manyclass="Student" />

</set>

代码:

//添加学生

Department department=new Department();

department.setName("业务部门3");

                    

Student stu1=new Student();

stu1.setName("顺平6");

//     stu1.setDept(department);

                     Studentstu2=new Student();

                     stu2.setName("小明6");

              //     stu2.setDept(department);

 

                     Set<Student>students=new HashSet<Student>();

                     students.add(stu1);

                     students.add(stu2);

                     department.setStus(students);

                    

                     s.save(department);

说明:

①在集合属性和普通属性中都能使用cascade

②一般讲cascade配置在one-to-many(one的一方,比如Employee-Department),和one-to-one(主对象一方)

 

 

 

 

hibernate综合运用.

以一个内部留言本来讲解.本案例本身不复杂,通过该案例我们讲解 struts+hibernate+接口编程的方式, 主要听点是程序结构的设计.

 

开始:

1.    看需求

2.    根据需求文档,我们画出程序框架图, 框架图的三个接口,暂时不写,后面我们再引入.

3.    创建一个web项目.

4.    创写web层.

4.1引入struts

42.把web层的jsp 表单 action 编写完毕,并且打通这个登录的模块

5. 引入hibernate 使用手动的方法来开发domain和对象关系文件

6. 把hibernate.cfg.xml写好

7. 写成工具类 dao HibernateUtil.java

8. 测试一下看看能否映射ok

测试成功!

9. 我们使用接口来解耦. web---接口--业务层

10. hibernate中,取消lazy 不要在 one-to-many 的 one的一方的<set /> ,可以在 many的一方配置 lazy=false;

11. 添加消息的功能.(假设用户是唯一的.,如果用户不唯一,我们可以通过id来发送信息)

 

 

 

* 在jsp页面中获取当前项目名称可以

<%=this.getServletContext().getContextPath() %>

通过标签: ${pageContext.request.contextPath}

 

 

 

 

 

1.    懒加载是什么? 为什么需要懒加载?

 

2.    如何解决懒加载问题

 

u  为什么需要缓存?

看一个案例:->原理图

从上图看出: 当我们去查询对象的时候,首先到一级缓存去取数据,如果有,则不到数据库中取,如果没有则到数据库中取,同时在一级缓存中放入对象.

u  一级缓存的细节

①     什么操作会向一级缓存放入数据

save,update,saveOrUpdate,load,get,list,iterate,lock

save 案例:

       //添加一个学生

                     Studentstudent=new Student();

                     student.setName("小东");

                    

                     s.save(student);//放入一级缓存

                    

                     //我马上查询

                     Studentstu2=(Student) s.get(Student.class, student.getId()); //select

                     System.out.println("你刚刚加入的学生名字是"+stu2.getName());

②     什么操作会从一级缓存取数据.

get / load / list

 

get / load 会首先从一级缓存中取,如没有.再有不同的操作[get 会立即向数据库发请求,而load 会返回一个代理对象,直到用户真的去使用数据,才会向数据库发请求]

?list 会不会从session缓存取数据?

案例:

//查询45号学生

             

                     Studentstu=(Student) s.get(Student.class, 45);

                    

                     System.out.println("|||||||||||||||||||");

                    

                     Stringhql="from Student where id=45";

                    

                    

                     Studentstu2=(Student) s.createQuery(hql).uniqueResult();

                    

                     System.out.println(stu2.getName());

从上面的案例,我看出query.list() query.uniueResut() 不会从一级缓取数据! 但是query.list 或者query.uniqueRestu() 会向一级缓存放数据的.

③     一级缓存不需要配置,就可以使用,它本身没有保护机制,所以我们程序员要考虑这个问题,我们可以同 evict 或者 clear来清除session缓存中对象. evict 是清除一个对象,clear是清除所有的sesion缓存对象

④     session级缓存中对象的生命周期, 当session关闭后,就自动销毁.

⑤     我们自己用HashMap来模拟一个Session缓存,加深对缓存的深入.

package com.hsp.view;

 

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

public class MyCache {

       //使用map来模拟缓存

       staticMap<Integer,Student> maps=new HashMap<Integer,Student>();

 

       publicstatic void main(String[] args) {

              // TODO Auto-generated method stub

 

              getStudent(1);

              getStudent(1);

              getStudent(1);

              getStudent(1);

              getStudent(3);

              getStudent(3);

             

             

             

       }

      

       public static Student getStudent(Integerid){  //s.get()

             

             

              //先到缓存去

              if(maps.containsKey(id)){

                     //在缓存有

                     System.out.println("从缓存取出");

                     returnmaps.get(id);

              }else{

                     System.out.println("从数据库中取");

                     //到数据库取

                     Studentstu=MyDB.getStudentFromDB(id);

                     //放入缓存

                     maps.put(id,stu);

                     returnstu;

              }

             

      

             

       }

 

}

 

//我的数据库

class MyDB{

      

       staticList<Student> lists=new ArrayList<Student>();

      

       //初始化数据库,假设有三个学生

       static{

              Student s1=new Student();

              s1.setId(1);

              s1.setName("aaa");

              Student s2=new Student();

              s2.setId(2);

              s2.setName("bbb");

              Student s3=new Student();

              s3.setId(3);

              s3.setName("ccc");

              lists.add(s1);

              lists.add(s2);

              lists.add(s3);

             

       }

      

       publicstatic Student getStudentFromDB(Integer id){

              for(Student s: lists){

                     if(s.getId().equals(id)){

                            return s;

                     }

              }

              return null;// 在数据库中没有.

             

       }

}

 

class Student{

       privateInteger id;

       privateString name;

       publicInteger getId() {

              return id;

       }

       publicvoid setId(Integer id) {

              this.id = id;

       }

       publicString getName() {

              return name;

       }

       publicvoid setName(String name) {

              this.name = name;

       }

}

 

u  为什么需要二级缓存?

因为一级缓存有限(生命周期短),所以我们需要二级缓存(SessionFactory缓存)来弥补这个问题

1.    需要配置

2.    二级缓存是交给第三方去处理,常见的Hashtable ,OSCache , EHCache

3.    二级缓存的原理

4.    二级缓存的对象可能放在内存,也可能放在磁盘.

 

u  快速入门案例

使用OsCache来演示二级缓存的使用.

 

1.    配置二级缓存

 

对配置说明:

<propertyname="hbm2ddl.auto">update</property>

       <!--启动二级缓存 -->

       <propertyname="cache.use_second_level_cache">true</property>

       <!--指定使用哪种二级缓存-->

       <propertyname="cache.provider_class">org.hibernate.cache.OSCacheProvider</property>

       <mappingresource="com/hsp/domain/Department.hbm.xml" />

       <mappingresource="com/hsp/domain/Student.hbm.xml" />

       <!--指定哪个domain启用二级缓存

       特别说明二级缓存策略:

       1.read-only

       2.read-write

       3.nonstrict-read-write

       4.transcational

       -->

       <class-cache class="com.hsp.domain.Student"usage="read-write"/>

2. 可以文件放在 src目录下,这样你可以指定放入二级缓存的对象capacity 大小. 默认1000

3 使用

// TODO Auto-generated method stub

              //通过获取一个sesion,让hibernate框架运行(config->加载hibernate.cfg.xml)

              Session s=null;

              Transaction tx=null;

             

              try {

                     //我们使用基础模板来讲解.

                     s=HibernateUtil.openSession();

                     tx=s.beginTransaction();

                    

                     //查询45号学生

             

                     Studentstu1=(Student) s.get(Student.class, 45);//45->一级缓存           

                     System.out.println(stu1.getName());

                    

                    

                     tx.commit();

                    

              } catch (Exception e) {

                     e.printStackTrace();

                     if(tx!=null){

                            tx.rollback();

                     }

              }finally{

                    

                     if(s!=null&& s.isOpen()){

                            s.close();

                     }

              }

             

              System.out.println("*********************************");

              try {

                     //我们使用基础模板来讲解.

                     s=HibernateUtil.openSession();

                     tx=s.beginTransaction();

                    

                     //查询45号学生

             

                     Studentstu1=(Student) s.get(Student.class, 45);    

                     System.out.println(stu1.getName());

                    

                     Studentstu3=(Student) s.get(Student.class, 46);    

                     System.out.println(stu3.getName());

                            tx.commit();

                    

              } catch (Exception e) {

                     e.printStackTrace();

                     if(tx!=null){

                            tx.rollback();

                     }

              }finally{

                    

                     if(s!=null&& s.isOpen()){

                            s.close();

                     }

              }

             

              //完成一个统计,统计的信息在Sessfactory

              //SessionFactory对象.

              Statistics statistics=HibernateUtil.getSessionFactory().getStatistics();

              System.out.println(statistics);

              System.out.println("放入"+statistics.getSecondLevelCachePutCount());

              System.out.println("命中"+statistics.getSecondLevelCacheHitCount());

              System.out.println("错过"+statistics.getSecondLevelCacheMissCount());

3. 在配置了二级缓存后,请大家要注意可以通过Statistics,查看你的配置命中率高不高

 

 

u  主键增长策略

①     increment

自增,每次增长1, 适用于所有数据库. 但是不要使用在多进程,主键类型是数值型

select max(id) from Student

②   identity

自增,每次增长1, 适用于支持identity的数据(mysql,sqlserver), 主键类型是数值

③   sequence

④   native

会根据数据类型来选择,使用identity,sequence ,hilo

selecthibernate_sequence.nextval from dual

主键类型是数值long , short ,int

<idname="id" type="java.lang.Integer">

<generatorclass="native"/>

</id>

⑤   hilo

hilo标识符生成器由Hibernate按照一种high/low算法生成标识符

用法:

<id name=”id” type=”java.lang.Integer” column=”ID”>

    <generatorclass=”hilo”>

   <paramname=”table”>my_hi_value</param>

   <paramname=”column”>next_value</param>

    </generator>

    </id>

⑥   uuid

会根据uuid算法,生成128-bit的字串

主键属性类型不能是数值型,而是字串型

⑦   assigned

用户自己设置主键值,所以主键属性类型可以是数值,字串

⑧   映射复合主键

⑨   foreign

在one-to-one的关系中,有另一张表的主键(Person) 来决定自己主键/外键( IdCard)

 

给出一个简单原则:

针对oracle [主键是int/long/short 建议使用 sequence] 主键是String 使用uuid或者assinged

针对 mysql [主键是 int/long/short 建议使用increment/assigend,如果是字串 UUId/assigned]

针对 sql server [主键是 int/long/short 建议使用identity/native/assinged ,如果主键是字串,使用uuid/assigned ]

 

one-to-one 又是基于主键的则使用foreign

 

u  hibernate最佳实践(在什么项目中使用最好)

对于数据量大,性能要求高系统,不太使用使用hiberante.

主要用于事务操作比较多的项目(oa/某个行业软件[石油、税务、crm, 财务系统.]

 

olap->hibernate用的比较少  oltp->hibernate

 

 

 

 

 

别再只盯着DDR5了!聊聊3D DRAM:它凭什么能解决AI算力的内存墙难题? 本文深入探讨了3D DRAM技术如何突破AI算力的内存墙限制。通过立体堆叠架构,3D DRAM在存储密度、带宽和延迟方面实现显著提升,有效解决AI训练和推理中的内存瓶颈问题。文章还分析了三星、SK海力士等巨头的技术路线图,并指出商业化面临的挑战与机遇。 阅读详情

相关推荐

数字IC笔记-低功耗技术

传统的降低Power的方法主要有: 1.门控时钟技术(clock gating) 2.多阈值电压技术(MultiShreshold) 3.动态电压频率调节技术(DVFS) 目前有以下几种低功耗技术: 1.多电压技术(Multi-Voltage) 2.MTCOMS Power Gating 技术(多阈值功耗控制技术),比如基带部分中的2G、3G、CDMA、LTE等通过awake—>sleep—>awake的方式间歇式的打开或关断其电源,power gating 可以完全关掉dynamic的pow

sinat_41774721的博客 1932

hibernate工厂模式_如何在Windows 7中管理Hibernate模式

hibernate工厂模式If you don’t use the Hibernate option in Windows 7, you can save some disk space by disabling it. Here we will look at a few different ways to manage hibernate options in Windows 7. 如果您在...

culinxia2707的博客 1466

TPRI-DMP平台介绍

TPRI-DMP为华能集团西安热工院自主产权的工业云PaaS平台,已经过13年的发展和迭代,其具备大规模能源电力行业生产应用软件开发和运行能力

ashou706的专栏 2270

调出win10的关机的休眠(hibernate)选项

调出win10的关机的休眠(hibernate)选项

w8y56f的专栏 4177

告别玄学:用Multisim或LTspice仿真带你直观理解PFC的三种工作模式(CCM/DCM/CrM)

本文通过Multisim和LTspice仿真工具,详细解析了PFC(功率因数校正)的三种工作模式(CCM、DCM、CrM)的本质差异。从波形捕捉到参数优化,提供了实用的仿真技巧和工程实践策略,帮助工程师直观理解并优化PFC电路设计,提升THD和功率因数。

weixin_30363285的博客 393

树莓派国内镜像源一键配置指南

本文提供树莓派国内镜像源一键配置指南,解决默认国外源访问缓慢问题。通过自动检测系统版本并支持清华、阿里云、中科大等主流镜像站选择,大幅提升软件更新与安装速度。包含详细的手动配置方法和常见问题排查,帮助用户快速完成树莓派换源优化。

tequila的博客 1373

Hibernate 简述及入门实例

总的概括,Hibernates是一个ORM的轻量级持久层框架,解决了对象和关系数据库中表的不匹配问题(阻抗不匹配)以及拥有开发代码不用去继承hibernate类或接口的优势(无侵入性)。hibernate框架实现使得开发人员可以避免反复地编写javajdbc部分代码,应用面向对象的思维操作关系型数据库。 二.使用myeclipse创建hibernate实例两种方法(以hibernate3

NapCoder的博客 358

【AI Agent】Hermes Agent解析

Hermes Agent:一个具备持久化学习能力的开源AI Agent框架 核心特点: 突破传统Agent的"无状态困境",通过记忆系统(SQLite+FTS5全文检索)实现跨会话经验积累 支持200+模型自由切换,11种模型家族和15+平台接入 五层架构设计(入口层、编排层、推理层、工具执行层、存储层)实现平台无关性 47+内置工具和动态技能沉淀机制,支持从任务执行中自动提炼可复用Skill 独特的四层记忆体系(会话/每日/长期/向量索引)和辩证式用户建模 与传统Agent对比: 具备自我进化能力,通过A

sysu_lluozh 911

Hibernate3.3.2 xml学习笔记

Hibernate3.3.2 xml学习笔记,请大家下载附件  

wjt276的专栏 160

手把手教你学SIMULINK模块库文件专栏-From Workspace 模块详解

模块是 Simulink 中的一个信号源模块,用于从 MATLAB 工作区加载数据作为输入信号。该模块允许用户将预先在 MATLAB 中生成的数据(如时间序列、矩阵或结构体)导入到 Simulink 模型中,从而实现更灵活的信号输入和仿真控制。通过深入了解其参数的影响及结合 MATLAB 脚本的应用,读者可以更加有效地利用这一模块进行仿真和研究。此外,通过实际应用场景的扩展以及常见问题解答部分的帮助,能够更好地掌握。模块是一个非常灵活的工具,适用于需要从 MATLAB 工作区加载数据的各种场景。

MHD0815的博客 631

学Simulink——基于故障诊断与容错控制的场景实例:并网逆变器在短路故障下的动态响应及恢复策略

本文详细介绍了使用Simulink进行并网逆变器短路故障模拟与保护策略设计的方法。通过构建高精度逆变器模型,模拟IGBT击穿和桥臂直通故障,分析动态响应特性。重点设计了基于Stateflow的微秒级快速保护逻辑,包括过流检测、PWM闭锁和故障报警。同时提出完整的恢复策略流程,涵盖放电、去磁、自检和软启动等关键步骤。仿真结果表明,该方法能在200μs内有效限制短路电流,保护器件安全,并实现系统可靠恢复。文章还探讨了硬件保护协同、多级保护和预测保护等高级策略,为新能源系统的安全运行提供了重要参考。

amy_mhd的博客 143

struts2+spring+hibernate+json+jquery+flexigrid开发笔记-绪言

   在软件开发过程中,我们总是会或多或少的遇到一些难以解决而又非得解决的问题,在解决问题的过程中很多时候都是在很突然的情况下就把问题解决了,但是当过一段时间后,我们在次碰到类似的问题,又得重头开始去思考,去解决问题,这不仅浪费了时间,还无形中提高了开发成本,这自然是老板不愿意看到的事情,产生这种问题的原因,其实是在于我们很多少做项目开发笔记,或者做的不认真倒致的,我就感觉我老是像这样,所以决定,

dengzhangsong的专栏 1285

AI预测彩票,使用chatgpt和lstm神经网络(文末附源码)

AI预测彩票,使用chatgpt和lstm神经网络(文末有彩蛋)

淘淘小窝 1万+

hibernate笔记2

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33994429的博客 93

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

hibernate,struts2学习笔记

fendou4533的专栏 537

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

小白学习笔记之struts2+hibernate整合

struts2+hibernate整合 1.导入jar包 在myeclipse中导入jar包。 2.配置web.xml &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://ww

weixin_43055079的博客 216

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

hibernate Day2 笔记

1、主键生成策略 <!--映射配置文件 >映射配置文件名称和位置没法有固定要求 >映射配置文件中的name属性值写实体类相关内容 -- class 标签name属性值实体类全路径 -- id标签和property标签name属性值 实体类的属性名称(注意要完全一样) -- id标签和property标签中的column属性是可以省略...

A458545418的博客 292

Hibernate快速笔记2

上篇:Hibernate快速笔记1 1.Hibernate的查询方式 2.Hibernate的抓取策略 Hibernate查询方式 OID检索:根据ID查询对象,Get/Load方法 session.get(Customer.class,1L) session.load(Customer.class, 2L) 对象导航检索:根据已查询对象,获得其关联对象,例如用户和角色 Custom...

fanleehao的博客 299

Hibernate学习笔记2

Hibernate学习笔记2 configuration Configuration 类的作用: 1.1 管理hibernate的配置信息 1.2 读取hibernate.cfg.xml的配置信息 1.3 加载hibernate.cfg.xml配置的驱动,url,用户名,连接池等 1.4 管理 xx.hbm.xml文件 Configuration cf =new Configuration(...

qq_18831003的博客 507

hibernate 学习笔记2

1.Criteria查询接口适用于组合多个限制条件来搜索一个查询集。 要使用Criteria,需要遵循以下步骤: *创建查询接口: Criteria criteria=session.createCriteria(User.class); *设置查询条件: criteria.add(Restrictions.gt(“age”,10); *查询数据: List...

a55684471的博客 200
上一篇: Hibernate笔记
下一篇: box2d_用户手册
focusjava
博客等级 码龄14年 127粉丝 528原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值