Hibernate的增删查改完整版

来源:互联网 发布:威少西部决赛数据 编辑:程序博客网 时间:2024/06/08 03:50

Hibernate的增删查改(事务)

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

1 Hibernate中的事务

1.1 设置事务隔离级别

Hibernate中事务的隔离级别都是用字节存储的                           二进制      十进制read uncommitted  读未提交   0001        1read committed  读已提交     0010        2repeatable 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();                        }                    }                }
原创粉丝点击