1、java三大框架struts2和hibernate和spring学习笔记hibernate学习笔记: 首先了解hibernate的配置文件,hibernate配置文件里面配置了与数据库打交道的一些信息,包括数据源,与一些数据库的相关类的配置,drivermanager等等,还设置了实体类与数据库表的映射,那么,在运行程序的时候,首先就要先加载hibernate的配置文件,整个hibernate的配置文件里面的内容首先包含在hibernate-configuration里面,其次,在hibernateconfiguration里面又包装了一层sessionfactory,那么当获得了hibern
2、ate-configuration之后,若要生成相应的实体类的表,就要导出相应的表,配置文件里面也配置了相应的语句,之后,若要对数据库表进行增删改查等操作,在获得了hibernate-configuration之后,就要建立一个相应的sessionfactory,当建立了sessionfactory之后,就要建立与数据库的会话机制,那就是在sessionfactory这个工厂里面打开一个session来保持这个通话。对数据库进行一些基本的操作。采用session的load方法加载数据: 采用session的load方式加载数据,参数为相应的实体类,和对应的表中的id主键值,来加载相应的数据。s
3、ession的load方法支持一级缓存,也就是session级缓存,当查询上来相应的数据时,如果再接着查询,则首先从session级缓存中查询看有没有相应的数据,如果有,就不去数据库存取,不发相应的sql语句。第二:session的load方法支持延迟加载,只有在真正用到数据的时候,load方法才去数据库查询相应的数据只有真正用到数据的时候才发sql语句。采用session的get方法加载数据 session的get方法首先不支持延迟加载,当执行session的get方法时,不管是否用到数据,get方法都发出sql语句查询相应的数据,加载上来。同样的session的get方法和load方法一样
4、,都支持一级缓存,都首先去缓存里读数据,如果有的话,直接加载数据,如果一级缓存中没有,那么发sql语句,去数据库中查找相应的数据。在对数据库进行某些变动的处理时,如修改,删除等操作,一定要开启事务,保持数据的一致性 在做删除与修改数据库的时候,一定要开启事务的管理,因为事务保持了数据操作的一致性。而在查询加载数据的时候,并不需要开启事务,因为加载,查询数据,不对数据进行相应的修改操作无需一致性,而在修改,删除时一定要开启事务,以达到保持数据的一致性。采用session的createQuery方法加载数据时: 查询单个的属性条件,采用直接根据条件查询,或者采用顺序占位符?来查询当采取顺序占位符?
5、时,得调用query的setParameter的方法,其中里面的参数解释为:第一参数表示的是第一个问号的下标,如果为0,则表示为第一个?号,第二个参数为?的实际值,对应的是实体表中的某个字段的值,若第一个?代表的是id,那么第二个参数则是表中的id字段的某个值这样就能根据具体的值把相应的内容加载上来,这样加载上来的信息为一个list集合。除了采用顺序占位符才传递参数外,还可以使用引用占位符,引用占位符:参数名,也就是给hql语句中的条件中的字段另起个别名而已,之后调用query的setParameter方法,参数表示为:第一个参数表示hql语句中的条件的别名,第二个参数为别名条件的值。根据这样
6、就能把相应的数据加载上来。返回一个list集合One2one唯一外键关联映射是多对一关联映射的特例可以采用标签,指定多的一端的unique=true,这样就限制了多的一端的多重性为一,通过这种手段映射一对一唯一外键关联例如一个人对应一个身份证号,在person一端配置 idcard一端无需配置One2one唯一外键双向关联映射,如上面例子需要在另一端(idcard),添加标签,指示hibernate如何加载其关联对象,默认根据主键加载person,外键关联映射中,因为两个实体采用的是person的外键维护的关系,所以不能指定主键加载person,而要根据person的外键加载,所以采用如下映射
7、方式: person端配置与上面配置一致one2one单向主键关联映射,只需配置一个文件就可以 以下为例,无论配置user还是idcard,只需按下面的user配置完成即可one2one双向主键关联映射,配置过程(另外在one2one配置中,不在任何一个表中添加多余的字段) 例如一个user对应一个idcard,那么在user.hbm.xml配置文件中 idcard 因为myeclipse默认了cacsde属性,所以在存储任何一方时,都会自动的把另一方给加载上来在idcard.hbm.xml配置文件中 many2one单向配置过程与one2many返回来的道理一样例如user和group,多个
8、用户对应一个组,many2one映射,在user.hbm.xml文件中如下配置:在group中无需任何配置,其中下面的标签,自动在多的一端添加一个column的值的一个字段此时也就是在user这个表中添加一个groupid这个字段指向group表的主键 idcard many2one双向就是反过来的one2many双向,还是以上为例那么在group中添加一个set集合来容纳user,group.hbm.xml配置文件如下: many2many,单向映射,配置过程例如,一个用户user可以拥有多个角色role,那么所以,在user用户一端设置一个set集合用来装载role,又因为是many2ma
9、ny,在前面的one2many中说过,会在many的一端自动添加一个字段来指向one的一端那么对于many2many来说,都是many一端,不存在one的一端,这时就要利用set标签里面的一个table属性来建立一个连接两个many端的中间表,配置如下:对于单向来说,那么在user一端的配置如下: idcard many2many双向映射配置,以上为例,一个user多个role,一个role有多个user,那么在role端也同样存在一个set集合用来装载user,那么role端配置文件的时候,因为role与user要产生一个中间表,所以在set标签里面的table属性值对应一个表里面的字段映射
10、要成为互相映射,也就是,在user一端的set标签里面,key的column为userid,那么在role中的many2many标签中的column为userid成互相对应的状态,反过来一样,所以user配置还跟上面的配置一样,role端的配置如下: 多对多双向关联,由于各自都含有包含对方引用的Set集合,那么在各自的配置文件里面就要配置set这个标签并且set集合里的内容在数据库中生成相应的表,并且在给表命名时,必须双方的名字一样,而且里面的字段也要一样否则的话,关联不上 在many-to-many class=com.ms.school.user.User 里面指定要关联的表是哪个实体查询
11、中的-统计查询: hql语句为:例如查询user里面有多少个元素用户 /Long count = (Long)session.createQuery(select count(*) from User).uniqueResult(); List users = session.createQuery(select count(*) from User).list(); Long count = (Long)users.get(0);实体查询中的-多个属性查询: 多个属性查询,返回的是个对象数组形式,两个属性组成两个元素的数组 /在获取值的时候,只能是对象数组形式获取, /也可以在hql语句中直
12、接new一个user对象,把属性id,name传进去 /此时必须在实体类中含有有参数的构造函数,这样,多属性查询返回的就是具体的查得表的对应的实体类对象, /例如下面的User; List users = session.createQuery(select id,name from User).list(); for(Iterator ite = users.iterator();ite.hasNext();) Object user = (Object)ite.next(); System.out.println(user0+-+user1); System.out.println(-);
13、 List userss = session.createQuery(select new User(id,name) from User).list(); for(Iterator ite = userss.iterator();ite.hasNext();) User user = (User)ite.next(); System.out.println(user.getId()+-+user.getName(); 实体查询中的-拼字符串查询: 采用拼字符串形式来查询实体类中的属性值,常用在模糊查询中例如:查询名字里面带有符号B的所有名字 /采用【%字符%】这种形式来查询表中符合条件的元素
14、,其中在hql语句中采用单引号括起来 List users = session.createQuery(select u.name from User u where u.name like %B%).list(); for(Iterator ite = users.iterator();ite.hasNext();) String name = (String)ite.next(); System.out.println(name); System.out.println(-); List userss = session.createQuery(select u.id,u.name fro
15、m User u where u.name like %B%).list(); for(Iterator ite = userss.iterator();ite.hasNext();) Object user = (Object)ite.next(); System.out.println(user0+-+user1); System.out.println(-); /采用?来传递参数,然后调用query的setparameter方法,指定问号的位置是什么值,也可以采用别名来传递参数,如下面例子 List usersss = session.createQuery(select u.id,u.
16、name from User u where u.name like ?) .setParameter(0, %B%) .list(); for(Iterator ite = usersss.iterator();ite.hasNext();) Object user = (Object)ite.next(); System.out.println(user0+-+user1); System.out.println(-); /也可以采用别名来传递参数,如下面例子,参数的别名为my,在设置参数时,采用key-value形式来设置相应的参数值 List userssss = session.cr
17、eateQuery(select u.id,u.name from User u where u.name like :my) .setParameter(my, %B%) .list(); for(Iterator ite = userssss.iterator();ite.hasNext();) Object user = (Object)ite.next(); System.out.println(user0+-+user1); System.out.println(-); /也可以采用复合参数别名来传递参数,如下面例子,参数s.name的别名为my,s.id的别名位myid, /在设置
18、参数时,采用key-value形式来设置相应的参数值 List usersssss = session.createQuery(select u.id,u.name from User u where u.name like :my and + u.id like :myid) .setParameter(my, %B%) .setParameter(myid, 1) .list(); for(Iterator ite = usersssss.iterator();ite.hasNext();) Object user = (Object)ite.next(); System.out.prin
19、tln(user0+-+user1); 实体查询中的-分页查询: 采用分页查询,把查询的结果进行分页,避免元素多而造成的页面拥挤 /采用分页查询方式,首先调用query的setfirstresult,表明数据从下标为几的元素开始, /然后调用setmaxresus,表明每页显示多少数据 /*Query query = session.createQuery(from User); query.setFirstResult(0); query.setMaxResults(3); List users = query.list();*/ List users = session.createQuery(from User).setFirstResult(1).setMaxResults(2).list(); System.out.println(-); for(Iterator ite = users.iterator();ite.hasNext();) User user = (User)ite.next(
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1