24H免费课程咨询  TEL:13401595960   QQ:1870218756  微信:13401595960(李老师)

东方博宜

网站首页 > 软件开发资讯 > Java开发

hibernate框架搭建及常见的基本操作

2017-09-12 16:57:34 东方博宜 阅读

1、框架

框架:对于某种设计模式的封装!

struts:实现了MVC设计模式

Jquery:对于常见的javascript效果和功能进行封装

Hibernate:实现了DAO(数据访问对象)的设计模式,封装了JDBC

 

XML文件的作用:存储数据,一般用来存储一些配置信息!

                常见的将来程序上线后可能会修改的内容,应该放在xml文件中,因为程序上线后,服务器上并没有java代码,只有class文件,而class文件不可以修改,因此修改起来不方便,而xml发布到服务器之后是可以在服务器上任意修改的!

 

 

2、入门案例

hibernate.cfg.xml:存储了数据库连接的基本信息(url、用户名、密码之类的信息)

 

A、配置数据库连接的基本信息:

第一步:配置子账户

建议采用子账户来连接数据库,而非root账户!

图片.png

图片.png

图片.png

图片.png


第二步:配置myeclipse的数据库连接源

图片.png

图片.png

 


 

B、添加hibernate框架

图片.png

图片.png

 


 

C、反转POJO类和ORM文件

POJO类:和数据库的表对应的那个类!

ORM文件:描述POJO类和数据库表对应关系的文件!(XML文件)

 

图片.png

 

问题:hibernatesessionweb项目中session有什么区别?

Hibernate中的session,是org.hibernate包中的Session类的对象,是一个数据库访问对象!

Web项目中的session,是HttpSession类的对象,是一个用来做缓存的对象!

 

案例:查询user表的所有数据!

/**

 * 对于User表访问的服务类

 */

public class UserService {

 

         /**

          * 获取表的所有数据

          * @return

          */

         public static List getList(){

                   //1、打开数据库连接,类似获取Connection

                   Session session = HibernateSessionFactory.getSession();

                   //2、创建查询对象,类似Statement

                   //hibernate是面向对象的查询模式,不能写sql要写hql语句(hibernate query language

                   //from User对象会自动映射为查询表

                   Query query = session.createQuery("from User");

                   //3、将查询结果封装为对象,将对象封装到List

                   List list = query.list();

                  

                   //关闭数据库连接

                   HibernateSessionFactory.closeSession();

                   return list;

         }

        

         public static void main(String[] args) {

                   List list = getList();

                   //遍历list

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

                            User user = (User) list.get(i);

                            System.out.println(user.getUid() + " " + user.getUsername() + " " + user.getTel());

                   }

         }

}

 

注意:hibernate是面向对象的查询模式,因此请不要直接查询user表,而是改为查询User对象,会自动映射到查询user表!

hibernate中,不写sql语句(select * from user;),而是改为写hql语句(from User),hql语句只是要求我们查询对象,而不能查询表!

 

3hibernate的访问原理

AHibernateSessionFactory

   作用:读取配置文件产生数据库访问对象Session的类

 

Bhibernate.cfg.xmlhibernate核心配置文件

   作用:存放了数据库连接的基本信息(url、用户名、密码)以及orm文件的位置!

       <mapping resource="com/crm/domain/User.hbm.xml" />

 

CUser.hbm.xml

   ORM文件,什么是ORM文件?

   Object RelationShip Mapping:对象关系映射文件,描述POJO类(和表对应类)和表的对应关系的文件!

 

   作用:描述POJO类(和表对应类)和表的对应关系!

DPOJO类:

   作用:和数据库的表对应的类,我们”from User”,查询这个类,通过ORM文件就可以映射到查询user表!

 图片.png


 


4hibernate的查询

A、子查询:hql添加where查询部分数据

         /**

          * 获取表的所有数据

          * @return

          */

         public static List getList(String hql){

                   Session session = HibernateSessionFactory.getSession();

                   Query query = session.createQuery(hql);

                   List list = query.list();

                   HibernateSessionFactory.closeSession();

                   return list;

         }

        

         public static void main(String[] args) {

                   List list = getList("from User where realname like '%%'");

                   //遍历list

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

                            User user = (User) list.get(i);

                            System.out.println(user.getUid() + " " + user.getUsername() + " " + user.getTel() + " " + user.getRealname());

                   }

         }

 

B、属性查询:hql语句查询部分属性(字段)

         /**

          * 获取表的所有数据

          * @return

          */

         public static List getList(String hql){

                   Session session = HibernateSessionFactory.getSession();

                   Query query = session.createQuery(hql);

                   List list = query.list();

                   HibernateSessionFactory.closeSession();

                   return list;

         }

        

         public static void main(String[] args) {

                   //如果查询部分属性,默认将结果封装为Object[],而非User对象

                   List list = getList("select uid,username,realname from User");

                   //遍历list

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

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

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

                   }

         }

 

C、实例化查询:查询属性,我们不希望返回Object[],而是希望返回User对象

第一步:在User类中提供一个希望封装的参数的构造方法!

         public User(Integer uid,String username,String realname){

                   this.uid = uid;

                   this.username = username;

                   this.realname = realname;

         }

 

第二步:在查询属性时,直接将属性通过构造方法封装为对象!

         /**

          * 获取表的所有数据

          * @return

          */

         public static List getList(String hql){

                   Session session = HibernateSessionFactory.getSession();

                   Query query = session.createQuery(hql);

                   List list = query.list();

                   HibernateSessionFactory.closeSession();

                   return list;

         }

        

         public static void main(String[] args) {

                   //查询部分属性,在查询时,将查询结果封装为对象(注意:User类要有这个构造方法)

                   List list = getList("select new User(uid,username,realname) from User");

                   //遍历list

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

                            User user = (User) list.get(i);

                            System.out.println(user.getUid() + " " + user.getUsername() + " " + user.getRealname());

                   }

         }

 

 

注意:显示hibernate底层的sql语句,在hibernate.cfg.xml中,添加如下配置

       <!-- 显示JDBC底层的sql语句 -->

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

 

5、根据ID查询单个对象

Aget查询

         /**

          * 根据id获取对象

          * @param id

          * @return

          */

         public static User getUser(int id){

                   Session session = HibernateSessionFactory.getSession();

                   User u = (User) session.get(User.class, id);

                   HibernateSessionFactory.closeSession();

                   return u;

         }

        

         /**

          * 根据id获取任何表的数据的对象(设计复用度较高的查询)

          * @param c

          * @param id

          * @return

          */

         public static Object getObj(Class c,int id){

                   Session session = HibernateSessionFactory.getSession();

                   Object obj = session.get(c, id);

                   HibernateSessionFactory.closeSession();

                   return obj;

         }

        

         public static void main(String[] args) {

//               User u = getUser(5);

                   User u = (User)getObj(User.class,5);

                   System.out.println(u.getUid() + " " + u.getUsername() + " " + u.getTel());

                  

                   Dept d = (Dept) getObj(Dept.class,3);

                   System.out.println(d.getDeptno() + " " + d.getDname());

         }

 

Bload查询

         /**

          * 根据id获取任何表的数据的对象

          * @param c

          * @param id

          * @return

          */

         public static Object loadObj(Class c,int id){

                   Session session = HibernateSessionFactory.getSession();

                   Object obj = session.load(c, id);

                   HibernateSessionFactory.closeSession();

                   return obj;

         }

        

         public static void main(String[] args) {

//               User u = getUser(5);

                   User u = (User)loadObj(User.class,5);

                   System.out.println(u);

//               System.out.println(u.getUid() + " " + u.getUsername() + " " + u.getTel());

                  

                  

         }

 

注意:load查询和get查询的区别?

Aload查询是基于延迟加载设计的,我们load时并不真正查询,而是要使用时才去查询

常见错误:

Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session

get查询,当get时就会真正查询!

 

问题:怎么解决这个load查询延迟加载的问题?

可以关闭load的延迟加载机制!

    <!-- lazy="false"关闭延迟加载机制 -->

<class name="com.crm.domain.User" table="user" catalog="crm" lazy="false">

 

</class>

 

Bload查询如果查询不到结果,则报出异常,get查询如果查询不到结果,则返回null

常见的load查询查询不到结果的异常:

Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.crm.domain.User#25]

 

6JDBC的事物管理

什么是事物?

一组动作同时成功或者失败,叫做一组事物!

比如:删除数据要记录日志,那么删除数据和记录日志这两个动作必须同时成功或者失败!

 

JDBC的事物管理是自动的,只要执行完sql会立即提交这条sql的事物!

 

JDBC如何做手动的事物管理?

A、关闭JDBC默认的事物管理

B、所有的sql都正常执行结束后,提交事物(相当于和数据库确认这几条sql都要执行)

C、如果有异常,撤销刚刚执行的所有动作

 

例子:

public class UserDao {

 

         /**

          * 执行多个sql语句,要同时成功或者失败

          *

          * @param sqls

          */

         public static void changeDatas(String[] sqls) {

                   Connection con = null;

                   Statement st = null;

 

                   try {

                            Class.forName("com.mysql.jdbc.Driver");

                            con = DriverManager.getConnection(

                                               "jdbc:mysql://127.0.0.1:3306/crm?characterEncoding=utf8",

                                               "java", "123456");

 

                            // 取消JDBC默认的自动事物管理

                            con.setAutoCommit(false);

 

                            st = con.createStatement();

 

                            // 分别执行不同的sql

                            for (int i = 0; i < sqls.length; i++) {

                                     st.executeUpdate(sqls[i]);

                            }

 

                            // 如果走到这句,说明sql语句都正常执行了

                            con.commit();// 提交事物

 

                   } catch (Exception e) {

                            e.printStackTrace();

                            // 如果到了这一句,说明sql语句执行有误,则撤销刚刚执行的所有sql的操作

                            try {

                                     con.rollback();// 回滚事物

                            } catch (Exception e2) {

                                     e2.printStackTrace();

                            }

                   } finally {

                            try {

                                     if (st != null) {

                                               st.close();

                                     }

 

                                     if (con != null) {

                                               con.close();

                                     }

                            } catch (Exception e) {

                                     e.printStackTrace();

                            }

                   }

         }

 

         public static void main(String[] args) {

                   String[] sqls = new String[2];

                   sqls[0] = "update user set realname='张晓明' where uid=16";

                   sqls[1] = "insert into user(username,password,realname) values('zhangwuji','123','金毛狮王')";

                   changeDatas(sqls);

         }

}

 

7、增加

注意:hibernate的事物管理是手动的,不会自动提交!

         /**

          * 保存数据

          * @param obj

          */

         public static void saveObj(Object obj){

                   Session session = HibernateSessionFactory.getSession();

                   //获取hibernate的事务管理器

                   Transaction ta = session.beginTransaction();

                   session.save(obj);

                   //提交事物

                   ta.commit();

                   HibernateSessionFactory.closeSession();

         }

        

         public static void main(String[] args) {

             User u = new User();

             u.setUsername("zhaomin");

             u.setRealname("赵敏");

             u.setPassword("123");

            

            

             //保存数据

             saveObj(u);

         }

 


Powered by 东方博宜教育咨询江苏有限公司  ©2008-2017 www.czos.cn