zoukankan      html  css  js  c++  java
  • hibernate Day2

    Day2
    1 实体类编写规则
    (1 ) 实体类中的属性是私有属性
    (2) 私有属性要生成get与set方法
    (3) 实体类中有属性作为唯一值(一般使用id值)
    (4) 实体类属性建议不要使用基本数据类型, 应当使用基本数据类型的包装类
    int ----> Integer
    为什么建议我们使用包装类呢?
    比如表示学生的分数, 如 int score;
    -- 如果学生得了0分, int score=0;
    -- 如果学生没有参加考试, 那么用int score=0; 不能准确表示学生是否参考试
    -- 如果使用 Integer score;这样就要以解决缺考的问题 Integer score=null;
    2 hibernate主键生成策略
    (1 ) hibernate中要求实体类里面有一个属性作为唯一值, 对应表的主键, 主键可以有不同的生成策略
    (2) hibernate中主键生成策略有很多种
    (3) 在generator标签的class属性取值有多种,表示了不同的主键生成策略
    http://blog.csdn.net/wenzhihui_201 0/article/details/1 3769827
    -- native : 根据使用的数据库帮助我们选择哪个值
    CREATE TABLE `t_person` (
    `uid` int(1 1 ) NOT NULL AUTO_INCREMENT,
    `uname` varchar(255) DEFAULT NULL,
    `pword` varchar(255) DEFAULT NULL,
    `addr` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`uid`)
    )-
    - uuid : 由hibernate帮助我们生成相应的UUID值
    >使用uuid生成策略, 那么实体类的id类型必须是String
    CREATE TABLE `t_person` (
    `uid` varchar(255) NOT NULL,
    `uname` varchar(255) DEFAULT NULL,
    `pword` varchar(255) DEFAULT NULL,
    `addr` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`uid`)
    )
    3 实体类操作n
    (1 ) CRUD操作
    -- 添加操作
    -- 根据 id 查询返回一个对象
    表中的现有的数据, 可以手动添加, 或通过session.save()方法添加
    @Test
    public void getPersonById(){
    // 1 获取SessionFactory
    SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
    // 2 获取session
    Session session=sessionFactory.openSession();
    // 3 开启事务
    Transaction tx=session.beginTransaction();
    // 4 根据id查询 调用session中的get方法
    // Session.get(Class<Person> clazz, Serializable id)
    // Class<Person> clazz : 类的class对象
    // Serializable id : id值, 注意要求这个id类型是可序列化的
    Person p1 =session.get(Person.class, 1 );
    System.out.println(p1 );
    // 5 提交事务
    tx.commit();
    // 6 关闭连接
    session.close();
    sessionFactory.close();
    }-
    - 更新对象
    先根据id查询到对象, 再更新对象
    @Test
    public void updatePerson(){
    // 1 获取SessionFactory
    SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
    // 2 获取session
    Session session=sessionFactory.openSession();
    // 3 开启事务
    Transaction tx=session.beginTransaction();
    // 4.1 根据id查询 调用session中的get方法
    Person p1 =session.get(Person.class, 2);
    // 4.2 修改对象信息
    p1 .setUname("张天明");
    p1 .setPword("1 2345");
    p1 .setAddr("中国南京");
    // 4.3 调用 session的update()方法修改
    // 修改过程, 到person表中, 根据id找到指定对象, 然后执行update语句完成修改
    session.update(p1 );
    // 5 提交事务
    tx.commit();
    // 6 关闭连接
    session.close();
    sessionFactory.close();
    }
    方法执行后显示的SQL语句
    结果对比
    -- 删除对象
    @Test
    public void deletePerson(){
    // 1 获取SessionFactory
    SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
    // 2 获取session
    Session session=sessionFactory.openSession();
    // 3 开启事务
    Transaction tx=session.beginTransaction();
    // 4 删除操作
    // 第一种方式(常用的方式)
    // 4.1 根据id查询 调用session中的get方法
    Person p3=session.get(Person.class, 3);
    // 4.2 对查询到的对象执行删除操作
    session.delete(p3);
    // 第二种方式(不常用)
    // Person p2=new Person();
    // p2.setUid(2);
    // session.delete(2);
    // 5 提交事务
    tx.commit();
    // 6 关闭连接
    session.close();
    sessionFactory.close();
    }
    结果查看
    -- 添加或更新操作
    @Test
    public void saveOrUpdate_Person(){
    // 1 获取SessionFactory
    SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
    // 2 获取session
    Session session=sessionFactory.openSession();
    // 3 开启事务
    Transaction tx=session.beginTransaction();
    // 4 添加操作
    Person person=new Person();
    // 添加时是不用给uid的, 但是我现在给了,而且是且中已经存在的
    person.setUid(1 );
    person.setUname("东方不败");
    person.setPword("5201 31 4");
    person.setAddr("黑木崖");
    // 执行添加
    session.save(person);
    // 5 提交事务
    tx.commit();
    // 6 关闭连接
    session.close();
    sessionFactory.close();
    }
    // 4 添加操作
    Person person=new Person();
    // 添加时是不用给uid的, 但是我现在给了,而且是且中已经存在的
    person.setUid(1 );
    person.setUname("东方不败");
    person.setPword("5201 31 4");
    person.setAddr("黑木崖");
    // 执行添加
    session.save(person);
    上面的save操作并不是更新, 而是执行了保存操作, 且它能够自动处理id的问题
    @Test
    public void save_Update_Person(){
    // 1 获取SessionFactory
    SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
    // 2 获取session
    Session session=sessionFactory.openSession();
    // 3 开启事务
    Transaction tx=session.beginTransaction();
    // 4 添加操作
    Person person=new Person();
    // 添加时是不用给uid的, 但是我现在给了,而且是且中已经存在的
    person.setUid(1 );
    person.setUname("东方不败");
    //person.setPword("5201 31 4");
    person.setAddr("黑木崖");
    // 执行修改操作
    // 现在一般是先查再改, 我们也可以直接创建对象, 然后直接改, 但要给出准确的id
    // 要注意了, 执行修改是对一个对象所有属性进行修改, 如果你有部分属性没有设置, 那么会置null
    session.update(person);
    // 5 提交事务
    tx.commit();
    // 6 关闭连接
    session.close();
    sessionFactory.close();
    }
    这是执行前后的结果比对
    (2) 实体类对象状态(概念)
    实体类状态有三种
    --瞬时态:对象里面没有id值, 对象与session没有关联,一般是做添加操作
    --持久态:对象有id值, 对象与seesion有关联
    --托管态:对象有id值, 但对象与session没有关联
    (3) saveOrUpdate方法;实现添加、 实现修改
    --该方法很简单, 它会根据对象不同的状态做相应的操作
    @Test
    public void saveOrUpdate_Person(){
    // 1 获取SessionFactory
    SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
    // 2 获取session
    Session session=sessionFactory.openSession();
    // 3 开启事务
    Transaction tx=session.beginTransaction();
    // 4 添加操作
    Person person=new Person();
    // 添加时是不用给uid的, 但是我现在给了,而且是且中已经存在的
    person.setUname("小龙女");
    person.setPword("5201 31 4");
    person.setAddr("古墓");
    // 由于person是瞬时态, 那么saveOrUpdate()这时是做insert操作
    session.saveOrUpdate(person);
    Person p1 =session.get(Person.class, 1 );
    p1 .setUname("杨过");
    p1 .setPword("1 31 4520");
    p1 .setAddr("古墓");
    // 由于p1 是持久态, 那么saveOrUpdate()这时是做update操作
    session.saveOrUpdate(p1 );
    Person p2=new Person();
    p2.setUid(2);
    p2.setUname("乔峰");
    p2.setPword("778899");
    p2.setAddr("大辽");
    // 由于p2是托管态, 那么saveOrUpdate()这时是做update操作
    session.saveOrUpdate(p2);
    // 5 提交事务
    tx.commit();
    // 6 关闭连接
    session.close();
    sessionFactory.close();
    }
    操作结果
    4 hibernate的一级缓存
    (1 ) 什么是缓存
    -- 数据存到数据库里面, 数据库本身就是文件系统, 使用流的方式操作文件效率不高
    -- 把数据存到内存里面, 不需要使用流方式, 可以直接读取内存中数据
    -- 把数据放到内存中, 提高读取效率
    (2) hibernate缓存
    -- hibernate框架中提供很多优化方式, hibernate的缓存就是一个优化方式
    -- hibernate缓存特点
    第一类 hibernate一级缓存
    > hibernate一级缓存默认打开
    > hibernate一级缓存使用范围(有点类似于web阶段的requestScope,seeionScope)
    一级缓存就是从session创建到session关闭的范围
    > hibernate一级缓存中, 存储的数据必须是持久态的数据, 瞬时态与托管态的数据不会存储到一级缓存中
    第二类 hibernate二级缓存
    > 目前已经不使用了, 替代技术redis
    > 二级缓存默认不是打开的, 需要通过配置打开
    > 二级缓存使用范围, 是SessionFactory范围( 项目范围)
    (3) 验证一级缓存存在
    验证方式:
    > 首先根据uid=1 查询, 返回对象 ( 查询数据库, 会有sql输出)
    > 其次再根据uid=1 查询, 又会返回对象 (瞧一瞧会不会有sql 输出)
    控制台输出
    (4) 一级缓存执行过程
    // 4 验证一级缓存
    // 根据uid进行第一次查询,是否有sql语句输出
    Person p1 =session.get(Person.class, 1 );
    System.out.println(p1 );
    // 再根据uid进行第二次查询,是否有sql语句输出
    Person p2=session.get(Person.class, 1 );
    System.out.println(p2);
    步骤:
    -- 首先查询一级缓存, 查询一级缓存如果没发现有相应的数据, 就去执行数据库查询
    -- 查询数据库后, 会把查询得到的结果放到一级缓存中
    -- 第二次进行查询时, 也会首先进行一级缓存查询, 这时发现数据已经在一级缓存中了, 直接取出就结果, 不会
    再做数据库的查询
    注意: 一级缓存中并不是存储某个对象, 而是把对象的属性值给存到缓存中, 当我们进行第二次查询时, 返回的
    p2,其实是用之前存放的属性值给重新构建出来的一个新的对象噢, 这一点大家了解
    (4) hibernate一级缓存特性
    > 持久态会自动更新数据库
    @Test
    public void persistentUpdate(){
    // 1 获取SessionFactory
    SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
    // 2 获取session
    Session session=sessionFactory.openSession();
    // 3 开启事务
    Transaction tx=session.beginTransaction();
    // 4 持久态更新数据库
    Person p5=session.get(Person.class, 5);
    // 更新对象信息
    p5.setUname("小师妹");
    p5.setAddr("华山");
    // 写入数据库,由于p5是持久态的, 所以下面的update方法调用可以省去
    // session.update(p5);
    // 5 提交事务
    tx.commit();
    // 6 关闭连接
    session.close();
    sessionFactory.close();
    }
    > 持久态会自动更新数据库的执行过程(了解)
    5 hibernate的事务操作
    (1 ) 什么是事务
    数据库事务(Database Transaction) , 是指作为单个逻辑工作单元执行的一系列操作, 要么完全地执行, 要么完全地不执行。 事务
    处理可以确保除非事务性单元内的所有操作都成功完成, 否则不会永久更新面向数据的资源。
    http://baike.baidu.com/link?url=89WXbjUBGS86Qy9G2ynAxr97mBbnDHVmauvYQ_EGJ65CupbnF2TwUZiH9XvfhXuxEQUy9xBbJYWgnw_On8TJLRCbpXOuNQdHuLqJDlotPKjR_rPeBFHTmUmMAOVFDeEIKfSsUmimPHm2V5-F4r-dq
    http://www.cnblogs.com/fjdingsd/p/5273008.html
    hibernate设置事务隔离级别 http://www.cnblogs.com/jerryxing/archive/201 2/04/24/2468999.html
    (2) 事务代码规则写法(重点掌握)
    > 结构
    try{
    开启事务
    处理代码
    提交事务
    }c
    atch(){
    回滚事务
    }f
    inally{
    释放资源
    }
    @Test
    public void addPerson_Standard() {
    SessionFactory sessionFactory = null;
    Session session = null;
    Transaction tx = null;
    try {
    sessionFactory = HibernateUtils.getSessionFactory();
    // 使用SessionFactory创建session对象
    // 类似于jdbc连接, 只是这个地方hibernate做了封装
    session = sessionFactory.openSession();
    // 开启事务
    tx = session.beginTransaction();
    // 添加功能
    Person person = new Person();
    person.setUname("韦小宝");
    person.setPword("weixiaobao");
    person.setAddr("紫禁城");
    // 调用session对象的实现方法,完成添加
    session.save(person);
    // 可以模拟一个异常
    int a=1 0/0;
    // 提交事务
    tx.commit();
    } catch (Exception e) {
    // 输出异常
    e.printStackTrace();
    // 有异常, 则回滚事务
    if(tx!=null){
    tx.rollback();
    }
    } finally {
    //关闭资源
    if(session!=null && session.isOpen()){
    session.close();
    }if
    (sessionFactory!=null && !sessionFactory.isClosed()){
    sessionFactory.close();
    }
    }
    }(2
    ) hibernate绑定session(重点掌握)
    > session类似于jdbc的connection, 为了安全可以使用threadLocal
    > hibernate已经帮助我们实现了与本地线程的绑定的session
    > 获取与本地线程绑定的session
    第一步 在hibernate核心配置文件中配置
    <!-- 本地线程绑定的session -->
    <property name="hibernate.current_session_context_class">thread</property>
    第二步 调用SessionFactory里面的方法得到
    public class HibernateUtils {
    private static SessionFactory sessionFactory = null;
    private HibernateUtils() {
    }s
    tatic{
    if (sessionFactory == null) {
    Configuration cfg = new Configuration();
    cfg.configure();
    sessionFactory = cfg.buildSessionFactory();
    }
    }p
    ublic static SessionFactory getSessionFactory() {
    return sessionFactory;
    }p
    ublic static Session getLocalSessioin(){
    // 直接返回与本地线程绑定的session
    return sessionFactory.getCurrentSession();
    }
    }@
    Test
    public void addPerson_Standard2() {
    Session session = null;
    Transaction tx = null;
    try {
    // 通过工具类获取本地session
    session = HibernateUtils.getLocalSessioin();
    // 开启事务
    tx = session.beginTransaction();
    // 添加功能
    Person person = new Person();
    person.setUname("韦小宝");
    person.setPword("weixiaobao");
    person.setAddr("紫禁城");
    // 调用session对象的实现方法,完成添加
    session.save(person);
    // 提交事务
    tx.commit();
    } catch (Exception e) {
    // 输出异常
    e.printStackTrace();
    // 有异常, 则回滚事务
    if(tx!=null){
    tx.rollback();
    }
    } finally {
    // 关闭资源(如果session是与本地线程绑定的, 那么它会自动关闭, 这个地方就用关闭了, 这么写也可以)
    if(session!=null && session.isOpen()){
    session.close();
    }/
    / 注意在web项目中SessionFactory对象是不用关闭的, 因为它是大家共用的
    }
    }
    6 hibernate的其他的api(查询)
    (1 ) Query对象
    > 使用Query对象, 不需要写sql语句, 我们要写hql语句
    -- hql : hibernate query language, hibernate框架提供的查询语言, 这个hql和sql语句很相似
    -- hql与sql的区别
    >> 使用sql操作的是表和字段
    >> 使用hql操作的是实体类和属性
    -- 查询所有hql语句
    >> from 实体类名称
    -- Query对象的使用
    >> 创建Query对象
    >> 调用Query对象方法得到结果
    @Test
    public void personQuery() {
    Session session = null;
    Transaction tx = null;
    try {
    // 得到与本地线程绑定的session
    session = HibernateUtils.getLocalSessioin();
    // 开启事务
    tx = session.beginTransaction();
    // 查询person表的hql
    String hql = "from Person";
    // 创建Query对象
    Query query = session.createQuery(hql);
    // 通过Query对象得到查询结果
    List<Person> persons = query.list();
    // 遍历输出查询结果
    for (Person p : persons) {
    System.out.println(p);
    }//
    提交事务
    tx.commit();
    } catch (Exception e) {
    // 有异常回滚
    if(tx!=null){
    tx.rollback();
    }
    } finally {
    // 释放资源(当前的session是本地线程session, 可以不用下面语句)
    if(session!=null && session.isOpen()){
    session.close();
    }
    }
    }
    (2) Criteria对象
    > 也可以使用这个对象进行查询操作, 但是使用这个对象时, 不需要写hql, 直接调用方法就可以实现
    > 实现过程
    -- 使用session对象的createCriteria(类名.class)创建Criteria对象
    -- 调用criteria对象的list()方法返回结果集
    (3) SQLQuery对象
    > 使用hibernate时候, 我们也可以调用原始的sql语句, 它就是通过SQLQuery对象
    >实现过程
    -- 创建SQLQuery对象
    -- 调用SQLQuery对象的方法得到结果
    调试的结果
    输出结果
    怎么样能得到同上样直接返回一个List集合, 且集合中每一个都是Person类的对象呢?


  • 相关阅读:
    ansible 通过堡垒机/跳板机 访问目标机器需求实战(ssh agent forward)
    运维标准化与流程化建设
    运维与自动化运维发展方向
    文件atime未变问题的研究
    ansible 任务委派 delegate_to
    ansible 调优
    windows中安装模拟器后修改模拟器中的hosts方法
    负载均衡服务器主要考量三个指标
    DRBD+NFS+Keepalived高可用环境
    sshpass
  • 原文地址:https://www.cnblogs.com/1020182600HENG/p/7421176.html
Copyright © 2011-2022 走看看