1.补充关于
- 使用persist的时候 如果主键是自增长则不能赋值,会报错,使用save不存在这种情况
auto-import:才表示的是 这个表示的是自动导入 如果我们设置为true了 那么在后面的HQL查询语句中 就直接写类名就可以了,如果是设置false了 那么后面的查询就必须要写类的全路径
写一个crud的帮助类
public class HibernateUtile { // 增 public static void save(Object object) { Session session=HFUtils.getSession(); session.beginTransaction(); session.persist(object); HFUtils.closeSession(); } //删除 public static void delete(Object object) { Session session=HFUtils.getSession(); session.beginTransaction(); session.delete(object); HFUtils.closeSession(); } //改 public static void update(Object object) { Session session=HFUtils.getSession(); session.beginTransaction(); session.delete(object); HFUtils.closeSession(); } //查询 public static <T>T query(int id,Class clazz) { Session session=HFUtils.getSession(); session.beginTransaction(); T t=(T) session.get(clazz, id); session.close(); return t; }
}
HibernateUtils的编写
/** * 对hibernate 的帮助类对重复代码的抽取 * * */ public class HFUtils { private static SessionFactory factory=null; //定义的是一个线程的局部变量,这个变量用来唯一的标识一个线程 private static ThreadLocal<Session> threadLocal=new ThreadLocal<Session>(); static{ factory=new Configuration().configure("config/hibernate.cfg.xml").buildSessionFactory(); } //获取session public static Session getSession() { //从线程中获取是否session Session session=threadLocal.get(); if (session!=null) { return session; } //没有session的处理方法 session=factory.openSession(); threadLocal.set(session); return session; } //关闭资源 public static void closeSession() { Session session = threadLocal.get(); if (session!=null) { session.getTransaction().commit(); session.close(); threadLocal.remove(); } } }
2. 复合主键
什么是复合主键
一个表中一个字段不能唯一标识某条记录需要多条才能标识记录,这就称为符合主键
如何使用复合主键
1. 将主键属性单独抽取成实体并提供get 和set 方法并且要序列化 2. 在实际使用的实体中声明 主键变量 3. 在映射文件中编写实体的配置文件
3.映射
集合映射:比如我们在淘宝中买东西一个账号能对应多个地址
1. set list map 三种集合的配置分别如下:
1. Set集合的配置
<!--接下来我们应该配置的是我们的集合映射 set集合-->
<set name="addresses" table="t_address">
<!--这里的这个key相当于是要配置外键 那么这个外键 是会自动的映射到当前的class的主键-->
<!-- 下面的这个 u_id 会自动的映射成上面的主键的id值-->
<key column="u_id"></key>
<!--下面的这个列专门用来存放地址
下面记住因为是集合所以集合中的数据的数据类型必须要写 否则报错
-->
<element column="address" type="java.lang.String"></element>
</set>
2. List集合配置
<!--接下来我们应该配置的是我们的集合映射 list集合-->
<list name="addresses" table="t_address_list">
<!--配置的是我们的外键-->
<key column="u_id"></key>
<!--下面就是和set集合唯一区别 下面这个配置表示的是排序的列-->
<list-index column="indexs"></list-index>
<!--配置的是实质映射的字段-->
<element column="address" type="java.lang.String"></element>
</list>
3. map集合配置
<!--下面就是map集合的映射-->
<!--调用的哪个map 生成表名-->
<map name="addresses" table="t_address_map">
<key column="u_id"></key>
<!--对应的键值-->
<map-key column="keys_001" type="java.lang.String"></map-key>
<!--对应的值-->
<element column="address" type="java.lang.String"></element>
</map>
3.1注意事项
- 在使用集合映射的必须指定这个集合中的数据类型
- 在使用list集合必须指定这个list序号不然会报错
- 在使用map集合的时候需要加上key的映射字段
- 在集合中key表示这个集合引用的外键这个外键是自动完成映射的外键会主动的映射到实体的主键中
4.一对多映射和多对一映射
1. 一对多的映射
<!--下面就配置的是一对多的集合映射-->
<set name="emps" table="t_employee" cascade="save-update,delete">
<!--集合中的外键会自动的映射到上面的主键-->
<key column="dept_id"></key>
<one-to-many class="Employ"/>
</set>
2. 多对一的关系
<many-to-one name="dept" class="Dept" column="dept_id"></many-to-one>
3. 在实际的开发中不需要两边都配置 你需要哪一方无维护这个关系那么你就配置谁
4.1级联
级联的问题 cascade
<set name="emps" table="t_employee" cascade="save-update"> <!--集合中的外键会自动的映射到上面的主键--> <key column="dept_id"></key> <one-to-many class="Employ"/> </set> cascade:级联 级联有三种 :save-update 级联的保存和更新 delete 级联的删除 all(前面两个家伙的并集) 级联的保存和更新是可以用的 但是在开发中一般情况下 级联的删除是不会用到的 因为他会影响到多张表