Hibernate的增删查改完整版

Hibernate的增删查改(事务)

内容已更新
新添加了4个查询方法:
分页查询
排序查询
聚合函数查询
投影查询

1 Hibernate中的事务

1.1 设置事务隔离级别
Hibernate中事务的隔离级别都是用字节存储的
                           二进制      十进制
read uncommitted  读未提交   0001        1
read committed  读已提交     0010        2
repeatable read  重复读      0100        4    mysql默认级别
serializable 可串行化        1000        8

配置数据库的隔离级别直接写十进制的值即可
在主配置文件(hibernate.cfg.xml)中配置数据库的隔离级别
<property name="hibernate.connection.isolation">4</property>
1.2 Hibernate管理事务的方法
    //开启事务:
    Transcation t=  session.beginTranscation();
    try{
      //........写自己的代码(do som work....)
      //提交事务:
      t.commit();
    }catch(Exception e){
      //异常后:回滚事务
      if(t!=null){
         t.rollback();
      }
    }
1.3 Hibernate得到Session对象的方式
Configuration c= new Configuration();
c.Configure();//读hibernate.cfg.xml文件
SessionFactory factory= c.buildSessionFactory();
方式一:
factory.openSession();
方式二:
factory.getCurrentSession();
补充:要理解getCurrentSesssion()
//原理跟以前ThreadLocal<Connection>一样。
        /**
         * hibernate源码处理过程:
         * 1.SessionFactory(接口)
         * 2.该接口实现类(SessionFactoryImpl)
         * 3.(搜索)getCurrentSession() :
         * 方法如下:  配置的currentSessionContext值是thread(获取跟当前线程有管的session)
         * public Session getCurrentSession() throws HibernateException {
                if ( currentSessionContext == null ) {
                    throw new HibernateException( "No CurrentSessionContext configured!" );
                }
                return currentSessionContext.currentSession();
             } 

         * 4.查看currentSessionContext。 该变量是一个CurrentSessionContext接口的实例
         * 5.CurrentSessionContext接口实现类:ThreadLocalSessionContext:
         * 
         * ThreadLocal<Map>  sessionMap =new ThreadLocal<Map>();
         * 
         * 
              等价于:ThreadLocal<<factory,session>>  sessionMap =new ThreadLocal<<factory,session>>();
         * 
         * @SuppressWarnings({"unchecked"})
                private static void doBind(org.hibernate.Session session, SessionFactory factory) {
                    Map sessionMap = sessionMap();
                    if ( sessionMap == null ) {
                        sessionMap = new HashMap();
                        CONTEXT_TL.set( sessionMap);
                    }
                    sessionMap.put( factory, session);
                }
         */
1.4 openSession()和getCurrentSession()区别(重点)
 /*   
 * openSession()和getCurrentSession()   
 * 
 * 1.openSession()每次调用生成新的Session
 *   getCurrentSession()每次调用都使用的同一个session(与当前线程绑定的session)
 *  
 * 2.openSession()使用不需要配置
 *   getCurrentSession()必须要配置,在主配置文件hibernate.cfg.xml中配置
 *   <property name="hibernate.current_session_context_class">thread</property>
 * 3. openSession()使用之后可以关闭  
 *    getCurrentSession()不能关闭
 * 
 * 4.Session要线程安全建议使用getCurrentSession();  
 * 
 * 建议用getCurrentSession()
 */
1.5 HibernateUtils封装的工具类
package com.qf.utils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtils {
    private static SessionFactory sessionFactory=null;
    static {
        Configuration configuration = new Configuration();
        configuration.configure();
        sessionFactory = configuration.buildSessionFactory();
    }
    public static Session openSession() {
        return sessionFactory.openSession();
    }
    public static Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }
    //openSession产生的session要关闭
    public static void closeSession(Session session) {
          session.close();
    }
}

2.增删查改

2.1 增(插入)
@Test
    public void testInsert1() {
        //1.先得到
        Session session = HibernateUtils.getCurrentSession();
        Transaction t = session.beginTransaction();
        try {
            User user =new User();
            user.setUser_name("皮皮虾");
            user.setUser_pwd("123456");
            session.save(user);
            t.commit();
        } catch (Exception e) {
            // TODO: handle exception
            t.rollback();
        }

    }
    @Test
    public void testInsert2() {
        //1.先得到
        Session session = HibernateUtils.getCurrentSession();
        Transaction t = session.beginTransaction();
        try {
            User user =new User();
            user.setUser_name("皮皮虾1");
            user.setUser_pwd("1234567");
            //参数1:实体类名称
            session.save("User", user);
            t.commit();
        } catch (Exception e) {
            // TODO: handle exception
            t.rollback();
        }
    }
2.2 修改
@Test
    public void testUpdate() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction t = session.beginTransaction();
        try {
            //根据唯一表示来修改
            User user =new User();
            user.setUser_id(1);
            user.setUser_name("皮皮虾2222");
            user.setUser_pwd("123456");
            session.update(user);
            t.commit();
        } catch (Exception e) {
            // TODO: handle exception
            t.rollback();
        }
    }
    @Test
    public void testSaveOrUpdate() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction t = session.beginTransaction();
        try {
            //根据唯一表示来修改
            User user =new User();
            user.setUser_id(4);
            //user.setUser_id(1);
            user.setUser_name("皮皮虾3333");
            user.setUser_pwd("1234564546");
            //saveOrUpdate()根据唯一标识主键id决定是save还是update()
            //能根据id查找到直接update
            //没有id执行 save.
            //如果设置了id,但是id在数据库中找不到,后台打印的是update,但是数据库中中插入了该数据
            session.saveOrUpdate(user);
            t.commit();
        } catch (Exception e) {
            // TODO: handle exception
            t.rollback();
        }
    }
2.3 删除
    @Test
    public void testDelete() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction t = session.beginTransaction();
        try {
            //根据唯一表示来修改
            User user =new User();
            user.setUser_id(1);
            session.delete(user);
            t.commit();
        } catch (Exception e) {
            // TODO: handle exception
            t.rollback();
        }
    }
2.4 查询
2.4.1 第一种方式:OID

​ 以oid(唯一标识)的形式进行查询(只能查询单条数据):

常见的:

//参数1:查询的类型:T.class 参数2:唯一标识id值
 session.find(T.class,id);
 session.get(T.class,id);
 session.load(T.class,id);
 示例:
 @Test
    public void  test() {
        //取Session
        Session session = HibernateUtils.getCurrentSession();
        Transaction t= session.beginTransaction();
        try {
            //参数1:查询的类型:T.class 参数2:唯一标识id值
            //User user = session.find(User.class, 2);
            //User user = session.get(User.class, 2);
            User user = session.load(User.class, 2);
            System.out.println("=2222==="+user);
            t.commit();
        } catch (Exception e) {
            // TODO: handle exception
            if (t!=null) {
                t.rollback();
            }
        }
    }
2.4.2 第二种方式:对象导航图查询

​ (常用于多表查询)

2.4.3 第三种方式:原生sql语句查询:

SQL(结构化查询语言 Structor Query Language)

Hibernate5.2以后用 session.createNativeQuery(sql语句);
Hibernate5.2以前用session.createSQLQuery(sql语句);
示例:  
public void test02() {
    //取session
    Session session = HibernateUtils.getCurrentSession();
    Transaction t= session.beginTransaction();
    try {
        //使用原生sql语句查询
        //查询所有
        //createNativeQuery是hibernate5.2版本之后建议用
        /*NativeQuery<User>  query=     
        session.createNativeQuery("select * from user", User.class);*/
       //createSQLQuery是Hibernate5.2版本之前使用的,但是目前或者将来不会使用了
     NativeQuery<User>  query=session.createSQLQuery("select * from user");
         //设置从第几个位置开始取数据
          query.setFirstResult(0);
          //设置每次最多取多少条数据
          query.setMaxResults(4);
          System.out.println("=--==="+query.list());
        t.commit();
    } catch (Exception e) {
        // TODO: handle exception
        if (t!=null) {
            t.rollback();
        }
    }
} 
 备注:  
//设置从第几个位置开始取数据
query.setFirstResult(0);
//设置每次最多取多少条数据
query.setMaxResults(4);
query.list()等价于query.getResultList() 得到查询的结果集合

原生sql的顺序及所有关键字及常见语句(mysql):

sql语句的书写顺序: 
 select * from 表名
              where  条件
              group by 列名
              having  条件
              order by  列名 asc/desc
              limit start,size  
 1.having和where比较
      where 在分组前过滤,
      having在分组后过滤,可以加聚合函数(max,min,sum.count.avg),不能独立出现,必须分组后调用
 2.sql执行顺序:  
      from 表名
      where 条件
      group by 列名
      having  条件
      order by  列名 asc/desc
      limit start,size     
      select
  3.模糊查询 like  %代表任意字符  _代表一个字符   ,如果like后的值是字符串一定要用单引号
2.4.4 第四种方式:HQL查询(Hibernate Query Language) 重点重点来学
     基于面向对象思想来查询。查询的是对象和对象的属性.
     关键字不区分大小写。类和属性等区分大小写
 以下方法获取多条数据:
 query.list()  query.getResultList()
 以下方法获取单条数据:
 query.uniqueResult()
1.基础查询
@Test
    public void test01() {
        //取Session
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        try {
//查询User表的所有数据
//从User类中找出所有的映射内容
//基本语法:from  包名+类名(如果整个程序中只有这么一个类,直接省略包名,默认查找该类)
//String HQL="from com.qf.domain.User";
String HQL="from User";//理解:找类其实找的是该类映射的数据库表的信息
//参数1:HQL语句 参数2:结果类型
            Query<User> query = session.createQuery(HQL, User.class);
            List<User> list = query.list();
            System.out.println("=="+list);
            transaction.commit();
        } catch (Exception e) {
            // TODO: handle exception
            if (transaction!=null) {
                transaction.rollback();
            }
        }
    }
2.别名查询
  //2.给类起别名查询
    @Test
    public void test02() {
        //取Session
                Session session = HibernateUtils.getCurrentSession();
                Transaction transaction = session.beginTransaction();
                try {
//根据类别名来查询数据
//s是User类的别名,查询User类中的所有内容。select User类中的所有成员变量 from User
//简化版:select  s   from User s  s代表整个User类,查询User类的所有
                    String HQL="select  s   from User s";
                    Query<User> query = session.createQuery(HQL, User.class);
                    System.out.println("===="+query.list());
                    transaction.commit();
                } catch (Exception e) {
                    // TODO: handle exception
                    if (transaction!=null) {
                        transaction.rollback();
                    }
                }
    }
3.条件查询

​ 方式一:?号占位,使用setParameter(position, value)赋值,位置从0开始

@Test
    public void test03() {
        //取Session
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        try {
            String HQL="from com.qf.domain.User where user_id =? ";
            Query<User> query = session.createQuery(HQL, User.class);
            //参数1:?号的位置,从0开始
            //参数2:value赋值
            query.setParameter(0, 2);
            System.out.println(query.uniqueResult());
            transaction.commit();
        } catch (Exception e) {
            // TODO: handle exception
            if (transaction!=null) {
                transaction.rollback();
            }
        }
    }

​ 方式二:属性名称占位,使用setParameter(name,value)赋值

    @Test
    public void test04() {
               //取Session
                Session session = HibernateUtils.getCurrentSession();
                Transaction transaction = session.beginTransaction();
                try {
                //:user_id表示占位
                String HQL="from com.qf.domain.User where user_id=:user_id";
                Query<User> query =     session.createQuery(HQL, User.class);
                //参数1:表示属性名 ,参数2:属性名对应的值
                query.setParameter("user_id", 2);
                System.out.println("--===-----"+query.uniqueResult());
                transaction.commit();
                } catch (Exception e) {
                    // TODO: handle exception
                    if (transaction!=null) {
                        transaction.rollback();
                    }
                }
    }
4.分页查询
注意:在HQL中进行分页使用setFirstResult()和setMaxResult()进行分页数据填充,limit关键不要用。
//1.分页查询
    @Test
    public void  TestByPage() {
        Session  session = HibernateUtils.getCurrentSession();
        Transaction t = session.beginTransaction();
        try {
            //根据面向对象思想,基于类的对象和属性查找。
            String hql="from com.qf.domain.Person";
            Query<Person> query = session.createQuery(hql, Person.class);
            query.setFirstResult(0);
            //设置最多能查询到的数据的条数
            query.setMaxResults(2);
            System.out.println(query.list());
            t.commit();
        } catch (Exception e) {
            // TODO: handle exception
            if (t!=null) {
                t.rollback();
            }
        }
    }
5.排序查询
//注意:排序后的名称是属性名称  order by后跟的是属性名
//2.排序查询:
    @Test
    public void  TestByOrder() {
        Session  session = HibernateUtils.getCurrentSession();
        Transaction t = session.beginTransaction();
        try {
            //根据面向对象思想,基于类的对象和属性查找。
            //uuid类型的主键可以排序
            String hql="from com.qf.domain.Person order by IDCard  desc";
            Query<Person> query = session.createQuery(hql, Person.class);
            System.out.println(query.list());
            t.commit();
        } catch (Exception e) {
            // TODO: handle exception
            if (t!=null) {
                t.rollback();
            }
        }
    }
6.聚合函数查询
结论: sum和count结果类型都是Long
      max和min结果类型和所求列的类型一致
      avg结果类型是Double
@Test
    public  void test03() {
        Session  session = HibernateUtils.getCurrentSession();
        Transaction t = session.beginTransaction();
        try {
            //1.sum:结果类型是Long,跟所求列的类型无关
            //String hql1="select sum(age) from com.qf.domain.Person";
            //Query<Long> query = session.createQuery(hql1,Long.class);

            //2.max,min结果类型跟所求的列的类型有关。
            String hql2="select max(age) from com.qf.domain.Person";
            String hql3="select min(age) from com.qf.domain.Person";
            //Query<Integer> query = session.createQuery(hql4,Integer.class);

            //3.avg结果类型是Dobule,跟所求的列的类型无关
            String hql4="select avg(age) from com.qf.domain.Person";
            //Query<Double> query = session.createQuery(hql5,Double.class);

            //4.count结果类型是Long,跟所求的列的类型无关
            String hql5="select count(*) from com.qf.domain.Person";
            Query<Long> query = session.createQuery(hql5,Long.class);
            System.out.println("====="+query.uniqueResult());
            t.commit();
        } catch (Exception e) {
            // TODO: handle exception
            System.out.println("-------"+e.getMessage());
            if (t!=null) {
                t.rollback();
            }
        }
    }
7.投影查询
//投影查询:
//需求:前面查询的都是查询所有列。表示扫描整个表。
//实际情况中,可能只关注表中的其中几个列,并不是所有。 如果这种情况再去扫描整个表查数据,效率低下。
//1.查询Person类中的名称列name
    @Test    
    public  void  test0001() {
        Session  session = HibernateUtils.getCurrentSession();
        Transaction t = session.beginTransaction();
        try {
            //该语句中的name是属性名
            String hql="select name from com.qf.domain.Person";
            Query<String> query = session.createQuery(hql, String.class);
            System.out.println(query.list());
            t.commit();
        } catch (Exception e) {
            // TODO: handle exception
            System.out.println("-------"+e.getMessage());
            if (t!=null) {
                t.rollback();
            }
        }
    }
//2.查询Person类中的名称列name,address,查询多个列,返回结果类型是Object[]类型
        @Test
        public  void  test0002() {
            Session  session = HibernateUtils.getCurrentSession();
            Transaction t = session.beginTransaction();
            try {
                //该语句中的name是属性名
                String hql="select name,address from com.qf.domain.Person";
                Query<Object[]> query = session.createQuery(hql, Object[].class);
                //list: 30个  list的每一项Object[] ========name,address
                for (int i = 0; i <query.list().size(); i++) {
                    Object[] objects = query.list().get(i);
                    System.out.println(objects[0]+"==="+objects[1]);
                }
                t.commit();
            } catch (Exception e) {
                // TODO: handle exception
                System.out.println("-------"+e.getMessage());
                if (t!=null) {
                    t.rollback();
                }
            }
        }

//3.查询Person类中的名称列name,address  改进,返回值是指定的实体类类型Person(必须具有new Person(name,address)有参的构造方法)
                @Test
                public  void  test0003() {
                    Session  session = HibernateUtils.getCurrentSession();
                    Transaction t = session.beginTransaction();
                    try {
                        //该语句中的name是属性名
                        String hql="select new Person(name,address) from com.qf.domain.Person";
                        Query<Person> query = session.createQuery(hql, Person.class);
                        System.out.println(query.list());
                        t.commit();
                    } catch (Exception e) {
                        // TODO: handle exception
                        System.out.println("-------"+e.getMessage());
                        if (t!=null) {
                            t.rollback();
                        }
                    }
                }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 小程序增删查改是指在小程序中使用Spring Boot框架实现增加(Create)、删除(Delete)、查询(Retrieve)和更新(Update)操作。 首先,在小程序的开发中,我们可以使用Spring Boot框架进行后台业务逻辑的处理。通过Spring Boot的特性,我们可以轻松实现对数据的增删查改操作。 对于增加操作,我们可以使用Spring Boot提供的注解和标签,如`@PostMapping`和`@RequestBody`来实现向数据库中插入新的数据。通过接收小程序端传来的数据,我们可以将这些数据保存到数据库中。 对于删除操作,我们可以使用`@DeleteMapping`和`@PathVariable`来删除数据库中的数据。在小程序端,我们可以通过点击按钮或其他方式触发删除操作。然后,通过发送请求到后台,指定需要删除的数据的唯一标识,后台可以根据该标识在数据库中删除相应的数据。 对于查询操作,我们可以使用`@GetMapping`和`@PathVariable`来查询数据库中的数据。小程序端可以通过发送请求到后台,并传入相应的查询条件,后台可以根据条件从数据库中查询出符合条件的数据,然后将查询结果返回给小程序端。 对于更新操作,我们可以使用`@PutMapping`和`@RequestBody`来更新数据库中的数据。小程序端可以通过发送请求到后台,并传入需要更新的数据,后台可以根据数据的唯一标识,在数据库中找到对应的数据进行更新。 总的来说,通过使用Spring Boot框架,我们可以方便地实现小程序中的增删查改操作。小程序端发送请求到后台,后台根据不同的请求类型和参数,进行相应的数据库操作。这样,我们可以轻松地进行数据的管理和操作。 ### 回答2: 小程序增删查改是指在一个使用Spring Boot框架开发的小程序中,实现对数据的增加、删除、查询和修改的功能。 首先,增加数据是指向数据库中添加新的数据记录。在小程序中,通常需要与前端界面交互,通过用户输入的数据,将数据传递到后端服务器。在Spring Boot中,可以使用ORM框架(如MyBatis或Hibernate)来操作数据库,通过定义实体类和Mapper接口,将数据插入到数据库中。 其次,删除数据是指从数据库中删除特定的数据记录。在小程序中,用户可能需要删除自己的数据或系统不再需要的数据。通过传递特定的标识符或条件,可以从数据库中筛选出需要删除的数据,并执行相应的删除操作。 接着,查询数据是指从数据库中获取特定的数据记录。在小程序中,通常需要根据一些条件,从数据库中检索需要的数据,然后将其展示给用户。在Spring Boot中,可以使用SQL语句或使用框架提供的方法(如MyBatis的Mapper接口或Spring Data JPA)来执行查询操作,返回符合条件的数据。 最后,修改数据是指对数据库中的数据记录进行更新。在小程序中,用户可能需要修改自己的数据或系统需要更新某些数据。通过传递特定的标识符或条件,可以从数据库中筛选出需要更新的数据记录,并执行相应的更新操作。 综上所述,小程序增删查改是通过Spring Boot框架实现对数据库中数据的增加、删除、查询和修改的功能。通过与前端界面交互,将用户输入的数据传递到后端服务器进行相应的操作,从而实现对数据的操作和管理。 ### 回答3: 小程序增删查改是指在使用Spring Boot后台开发时,对于小程序的数据进行增加、删除、查询和修改操作。下面分别介绍这几个操作的实现方式: 1. 增加:通过设计合适的数据库模型,定义相应的实体类,并使用Spring Boot提供的JPA或MyBatis等持久化框架,创建对应的Repository或Mapper接口。通过调用这些接口的方法,可以实现往数据库中增加新的数据。 2. 删除:同样通过调用Repository或Mapper接口的方法,利用传递的参数或查询条件来删除数据库中的数据。可以支持按照特定的条件删除单个或多个数据。 3. 查询:通过Repository或Mapper接口提供的查询方法,实现对小程序数据的查询。可以根据不同的需求使用不同的查询方式,如根据条件查询、分页查询等。 4. 修改:同样通过调用Repository或Mapper接口的方法,传递需要修改的对象或参数来更新数据库中对应的数据。 以上即为小程序增删查改在Spring Boot中的实现方式。通过使用Spring Boot提供的持久化框架,我们可以方便地进行数据库操作,提高了开发效率。同时,Spring Boot还提供了许多其他功能,如事务管理、异常处理等,可以帮助我们更好地完成小程序的开发工作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值