zoukankan      html  css  js  c++  java
  • Hibernate下的增删改查

    概述:

    关系--对象映射的中间件,属于开源ORM框架,是我们业务逻辑层中的调用数据库的中间件
    

    演变:

    jdbc---hibernater---mybatis
    

    hibernate和mybatis区别?

    1:hiberanter学习的难度要比mybatis要大,复杂度要高
    2:hibernate不需要写sql语句,自动生成,而mybatis需要写sql语句进行数据操作
    3:hibernate支持分页(API),而mybatis不支持分页(那是属于插件)
    4:hibernate支持事务处理,而mybaits不支持事务处理(Spring)
    5:hibernate支持一级缓存、二级缓存和查询缓存,而mybaits本身没有缓存(加载第三方缓存技术)
    

    环境搭建步骤:

    1:导包
      <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.3.3.Final</version>
        </dependency>
    
    2:加载配置文件hibernate.cfg.xml(数据库连接信息)
    3:需要增加映射文件(写的不是sql语句,写的是实体entity和表table中的字段、类型对应关系)
    

    数据库工具类:

    public class HibernateUitls {
    
        public static Session getSession() {
            // 获取数据库的连接工厂
            // 从工厂中获取连接session
            Configuration config = new Configuration();
            config.configure("hibernate.cfg.xml");
            SessionFactory sf = config.buildSessionFactory();// 获取工厂
            Session session = sf.openSession();
            return session;
        }
    }

    增删改查操作

    /**
     * 测试hibernate增删改查
    * @author lisi
    * @date 2018年8月20日
     */
    public class HibernateTest {
    
    
        /**
         * 查询操作---读操作
         */
        @Test
        public void query(){
    
            Session session = HibernateUitls.getSession();
            Note note = session.get(Note.class, 63);//根据主键查询
            if (note != null) {
                System.out.println(note.getContext());
            }
        }
    
        /**
         * 增加---写操作
         */
        @Test
        public void save(){
            Session session = HibernateUitls.getSession();
    
            Note note = new Note();
            note.setId(3000);
            note.setContext("java20增加测试数1");
            note.setLikeCount(10);
            note.setUserId(1);
            note.setPublishTime(new Date(System.currentTimeMillis()));
    
            Transaction ts = session.beginTransaction();//开启事务处理
    
            session.save(note);//保存数据
            ts.commit();//提交事物--
            session.close();//关闭连接 
        }
    
    
        /**
         * 修改数据
         */
        @Test
        public void update(){
    
            Session session = HibernateUitls.getSession();
    
    //      Note note = new Note();
            Note note = session.get(Note.class, 3000);
            //note.setId(3000);
            note.setContext("java20增加测试数2");
            Transaction ts = session.beginTransaction();//开启事务处理
            session.update(note);
            ts.commit();//提交事物--
            session.close();//关闭连接 
    
        }
    
        /**
         * 删除操作
         *  1:先查询数据是否存在
         *  2:如果存在,则删除,不存在,则不执行delete
         *  3:hibernate做的安全设置
         */
        @Test
        public void delete(){
    
            Session session = HibernateUitls.getSession();
    
            Note note = new Note();
            note.setId(3000);
            Transaction ts = session.beginTransaction();//开启事务处理
            session.delete(note);
            ts.commit();//提交事物--
            session.close();//关闭连接 
        }
    
    }

    Hibernate主键管理

    策略生成的位置配置:

    <id name="id" type="integer" column="id">
        <generator class="identity"></generator>
    </id>

    1.sequence 序列

    主要用于oracle数据库
    

    2.identity 主键自增

    主要用于mysql、SqlServer
    主键自增
    

    3.native

    自动识别当前数据库的类型
    如果数据库为oracle,则默认的ID生成策略为sequence
    如果数据库为mysql等,则默认的ID生成策略为identity
    

    4.increment

    代表当前数据库表的主键ID,查询数据库ID最大值+1
    

    5.uuid/hilo

    采用UUID和hilo的算法,生成一个字符串,当成主键ID
    

    6.assigned

    是hibernate默认的主键生成策略,增加set方法

    Hibernate查询操作

    • SQL:面向结构的查询 Structured Query Language(结构化)

      select * from note 或者 SELECT * FROM NOTE

    • HQL:面向对象的查询 hibernater query language(对象化)

      select userid(实体类中的属性名称) from Note(实体类名)

    HQL和SQL区别?

    - HQL是面向对象的查询,SQL是面向结构化的查询
    - HQL查询时候对查询属性大小写比较敏感,SQL在查询的时候对属性的大小写依赖于我们的配置
    - HQL支持count、sum、avg等,但是HQL不支持类型转换,比如日期转换、字符串转换
    - HQL不建议使用left join,而SQL可以无条件的使用
    - HQL在做查询的时候,如果是查询所有字段信息,则可以省略select *,直接使用from  实体类名
    - HQL在查询的时候,使用的是类名和属性名,SQL查询的时候,使用的表名和字段名
    - HQL和SQL在使用上,或者处理业务上,HQL只能进行简单操作,SQL可以进行复杂操作
    

    结构化:

    HQL查询

    普通查询
    
    1:查询所有的数据
    
    2:根据条件进行查询
    
    3:分页条件
    
    4:统计个数
    

    代码如下:

    /**
     * hibernate普通查询
    * @author lisi
    * @date 2018年8月21日
     */
    public class HQLTest {
    
    
        /**
         * 查询所有的数据
         */
        @Test
        public void query(){
            Session session = HibernateUitls.getSession();
            String hql = "from Note";//注意:这里的Note不是你的数据库表名,而是你的实体类名
            Query query = session.createQuery(hql);
            List<Note> list = query.list();//获取查询结果集
            //list.isEmpty()    只会判断list中的数据是否为空
            //list != null && list.size() > 0  判断的是对象list是否存在,并且判断list中是否有数据
            if (list != null && list.size() > 0) {
                for (int i = 0; i < list.size(); i++) {
                    System.out.println("内容为:" + list.get(i).getContext());
                }
            }
        }
    
        /**
         * 根据条件查询
         *  select * from note where userId = 3
         */
        @Test
        public void test2(){
            Session session = HibernateUitls.getSession();
    
            //jpa-style
            //String hql = "from Note where userId=?0";//?代表占位符,占位符下标是从0开始
            String hql = "from Note where userId = :userid";
            Query query = session.createQuery(hql);
    //      query.setInteger(0, 3);
    //      query.setParameter(0, 3);
            query.setParameter("userid", 3);
    
            List<Note> list = query.list();//获取查询结果集
            if (list != null && list.size() > 0) {
                for (int i = 0; i < list.size(); i++) {
                    System.out.println("内容为:" + list.get(i).getContext());
                }
            }
        }
    
        /**
         * 分页查询
         * 
         *  select * from note limit 0,3;
         */
        @Test
        public void test3(){
            Session session = HibernateUitls.getSession();
            String hql = "from Note";
    
            Query query = session.createQuery(hql);
    
            query.setFirstResult(1);//分页条件limit的第一个参数,下标是从0开始
            query.setMaxResults(3);//分页条件limit的第二个参数,代表需要查询的条数
    
            List<Note> list = query.list();//获取查询结果集
            if (list != null && list.size() > 0) {
                for (int i = 0; i < list.size(); i++) {
                    System.out.println("内容为:" + list.get(i).getId());
                }
            }
        }
    
    
        /**
         * 统计个数
         *  select count(1) from note
         */
        @Test
        public void test4(){
            Session session = HibernateUitls.getSession();
            String hql = "select count(0) from Note";
            Query query = session.createQuery(hql);
            Long count = (Long) query.uniqueResult();
            System.out.println("统计个数为:" + count);
        }
    }

    Criteria查询

    多条件查询、可以根据实体类属性的字段、排序、分组、分页、统计个数、and、or等
    

    示例代码:

    /**
     * 多条件查询
    * @author likang
    * @date 2018年8月21日
     */
    public class CriteriaTest {
    
    
        /**
         * select * from note;
         */
        @Test
        public void test1(){
            Session session = HibernateUitls.getSession();
            Criteria criteria = session.createCriteria(Note.class);
            List<Note> list = criteria.list();
            if (list != null && list.size() > 0) {
                for (int i = 0; i < list.size(); i++) {
                    System.out.println("内容为:" + list.get(i).getContext());
                }
            }
        }
    
        /**
         * select * from note where userId = 3;
         * select * from note where userId = 2 and id = 2005;
         * select * from note where userId = 2 or id = 2005;
         * select * from note where userId = 2 or id = 2005 order by id desc/asc;
         */
        @Test
        public void test2(){
            Session session = HibernateUitls.getSession();
            Criteria criteria = session.createCriteria(Note.class);
    //      criteria.add(Restrictions.eq("userId", 2));
    //      criteria.add(Restrictions.eq("id", 2005));
            criteria.add(Restrictions.or(Restrictions.eq("userId", 2), Restrictions.eq("id", 2005)));
    //      criteria.addOrder(Order.desc("id"));
            criteria.addOrder(Order.asc("id"));
    
            List<Note> list = criteria.list();
            if (list != null && list.size() > 0) {
                for (int i = 0; i < list.size(); i++) {
                    System.out.println("内容为:" + list.get(i).getContext());
                }
            }
        }
    
        /**
         * hibernate5新特性写法:
         *  select * from note where userId = 3;
         */
        @Test
        public void test3(){
            Session session = HibernateUitls.getSession();
            CriteriaBuilder crb = session.getCriteriaBuilder();
            CriteriaQuery<Note> criteria = crb.createQuery(Note.class);
            Root<Note> root = criteria.from(Note.class);
            criteria.where(crb.equal(root.get("userId"), 1));
            Query<Note> query = session.createQuery(criteria);
            List<Note> list = query.list();
            if (list != null && list.size() > 0) {
                for (int i = 0; i < list.size(); i++) {
                    System.out.println("内容为:" + list.get(i).getContext());
                }
            }
        }
    }

    NativeSQL查询

    原生查询、支持sql语句的查询
    

    示例代码:

    /**
     * 原生sql语句查询
    * @author lisi
    * @date 2018年8月21日
     */
    public class NativeSQLTest {
    
    
        @Test
        public void test1(){
            Session session = HibernateUitls.getSession();
            String sql = "select * from note";
    //      SQLQuery query = session.createSQLQuery(sql);
    //      List<Object[]> list = query.list();
    //      if (list != null && list.size() > 0) {
    //          for (Object[] obj : list) {
    //              System.out.println(obj[1]);
    //          }
    //      }
    
            SQLQuery query = session.createSQLQuery(sql);
            query.addEntity(Note.class);//在进行遍历之前,提前进行数据映射转换
            List<Note> list = query.list();
            if (list != null && list.size() > 0) {
                for (int i = 0; i < list.size(); i++) {
                    System.out.println("内容为:" + list.get(i).getContext());
                }
            }
        }
    
    
        /**
         * hibernate5新特性写法:
         */
        @Test
        public void test2(){
            Session session = HibernateUitls.getSession();
            String sql = "select * from note where userId = 3";
            NativeQuery query = session.createNativeQuery(sql);
    
            query.addEntity(Note.class);//在进行遍历之前,提前进行数据映射转换
            List<Note> list = query.list();
            if (list != null && list.size() > 0) {
                for (int i = 0; i < list.size(); i++) {
                    System.out.println("内容为:" + list.get(i).getContext());
                }
            }
        }
    
    }

    Hibernate注解应用

    类上面注解:

    @Entity
    @Table(name="note")
    

    方法属性注解:

    @Id
    @Column(name="数据库中字段主键")
    @GeneratedValue(generator="identity")
    private int id;//主键
    
    其它字段:
    
        @Column(name="数据库中字段名称")
    

    修改hibernate.cfg.xml配置文件:

    <mapping class="com.xdl.entity.Note"/>
    

    Hibernate特性

    延迟加载

    hibernate中的API,有一些是具有延迟加载的特性,对象在调用的时候,才会进行数据加载(什么时候调用,什么时候加载)
    
    get、list方法,不具有延迟加载特性
    load、find方法,具有延迟加载特性
    

    问题:

        ...... no session
    

    问题请求:

    接口请求--->web.xml--->action--->service--->dao(session关闭)--->view
    

    解决:

    接口请求--->web.xml--->action--->service--->dao(session不关闭)--->view--->关闭session(事务spring)
    

    缓存(性能优化)

    缓存:对象在第一次使用的时候,是进行数据加载(需要查询数据库),下一次查询同样条件的数据,则直接从缓存中获取,而并发查询数据库(速度快、减轻数据库服务器压力)
    
    • 一级缓存

      自动开启,不需要做任何的配置和修改 特点: session独享

    • 二级缓存

      特定: session共享

    • 查询缓存

    持久化(session)

    • 临时状态

      可以被JVM进行垃圾回收

    • 持久化状态

      不能更直接被JVM回收,可以先变成其它两种状态之后,才会进行垃圾回收

    • 游离状态

      可以被JVM进行垃圾回收

    Spring+Hibernate整合

    整合结构:

    整合步骤:

    1:导包
        hibernate-core
    2:导入spring包
    
    3:加载spring和hibernate配置文件
    
    4:在spring的配置文件中,增加数据库的连接信息和事务管理
    
    5:将原来的工程进行改造---jdbc实现类注释,增加一个hibernate实现类
    
    6:实现接口方法
    
    7:部署、启动、访问
    

    核心代码:

    applicationContext.xml:
    <!-- 加载hibernateTemplate -->
        <bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
            <property name="sessionFactory" ref="sessionFactory"></property>
        </bean>
    
        <!-- 加载sessionFacotory -->
        <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
            <property name="dataSource" ref="c3p0"></property>
            <property name="configLocations" value="classpath:hibernate.cfg.xml"></property>
        </bean>
    
        <!-- 处理事务 -->
        <bean id="txManger" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory"/>
        </bean>
        <!-- 事务支持注解驱动 -->
        <!-- proxy-target-class:属性默认为false,则代表是使用jdk本身的代理(静态代理)
            true:则代表使用的是cglib代理(动态代理模式)
         -->
        <tx:annotation-driven transaction-manager="txManger" proxy-target-class="true"/>
    
    
    HibernateServiceImpl.java:
     @Repository
        public class HibernateServiceImpl implements INoteService{
    
            @Resource
            private HibernateTemplate hibernateTemplate;
    
            @Override
            public List<Note> queryNoteList(int userid) {
                DetachedCriteria dCriteria = DetachedCriteria.forClass(Note.class);
                dCriteria.add(Restrictions.eq("userId", userid));
                List<Note> list = (List<Note>) hibernateTemplate.findByCriteria(dCriteria);
                String hql = "from Note where userId=:userId";
                List<Note> list1 = (List<Note>) hibernateTemplate.findByNamedParam(hql, "userId", userid);
                return list1;
            }
    
            @Override
            public int deleteNotesById(int id) {
                Note note = hibernateTemplate.get(Note.class, id);
                if (note != null) {
                    hibernateTemplate.delete(note);
                    return 1;
                }
                return 0;
            }
        }
    
    如果有删除操作,需要在删除的action的类头上加上标注,将只读模式关闭
    @Transactional(readOnly=false)//将只读模式进行关闭
    DeleteAction.java:
  • 相关阅读:
    全局变量、函数、文件基本操作、冒泡排序
    元组,字符串,集合,文件操作
    Python使用小技巧
    pycharm
    postman和charles
    将博客搬至CSDN
    垃圾陷阱
    codevs 1139 观光公交
    1159 最大全0子矩阵
    NOI 193棋盘分割.cpp
  • 原文地址:https://www.cnblogs.com/hx1098/p/9514456.html
Copyright © 2011-2022 走看看