ORM(对象关系映射;Object Relational Mapping)
OID(对象标识符 Object identifier)
简记:
将域模型表示的对象映射到关系数据库模型表示的数据库,不需要操作对应的表,只需要操作表对应的实体类对象
- 类对应表
- 属性对应字段
- 对象对应记录
优劣:
通过orm思想来操作实体类对象时,不需要复杂的SQL语句,只需要操作实体类对象;
防注入(SQL语句 select * from user where name =" or 1=1 -- and password=");or 1=1用户名等于或1=1,那么这条语句一定成功
劣:不太容易处理复杂查询语句;性能较直接用SQL差
主键生成方式:(mysql不支持序列(sequence),oracle不支持自增长(identity))
通过id元素的generator子元素进行配置,常见的
increment:由Hibernate从数据库中取出主键的最大值(每个session只取1次),以该值为基础,每次增量为1,在内存中生成主键,不依赖于底层的数据库,因此可以跨数据库。
idnetity:
assigned:主键由外部程序负责生成,在 save() 之前必须指定一个。Hibernate不负责维护主键生成。与Hibernate和底层数据库都无关,可以跨数据库。在存储对象前,必须要使用主键的setter方法给主键赋值,至于这个值怎么生成,完全由自己决定,这种方法应该尽量避免。
级联属性:
cascade,常用于多方,关联一方进行级联操作(ps:保存了多方的一位,顺带也能保存一方):all none save-update delete
维护关联关系(一对多):
inverse,常用于一方放弃维护外键(ps:一方为true则让多方来维护)false
一般来说,如果添加一个班级,添加一个学生,没设置inverse的时候,sql打印会出现班级insert,学生insert,班级update(多了班级update)
设置了inverse=true后,班级不再管理,只需要session.save(学生),sql打印会出现班级insert,学生insert(没了班级update)
session获取方式:
opensession,不需要配置,需要手动关闭
getcurrentsession需要配置,不需要手动关闭
Hibernate(批量修改不适用于hibernate)
概念:
- 完成将对象持久化类 的 持久层框架(在一定周期内保持不变就是持久化,持久化是针对时间来说的。数据库中的数据就是持久化了的数据,只要你不去删除或修改。)
- 能建立对象和关系之间的映射,一种自动orm的结构
- 对jdbc的封装,轻量级框架
实体类对象:
配置:
- 通过标准注册服务实例生成器(StandardServiceRegistryBuilder)来生成标准注册服务实例(StandardServiceRegistry)
- 根据标准注册服务创建一个MetadataSources实例(元数据资源集)
- 创建sessionfactory工厂(实现sessionfactory接口)
- 获得session/打开sessioin(获得session√,因为opensession需要手动的关闭session)
standardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
private static SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
return.sessionFactory.openSession;
一级缓存(Session缓存):
当使用session调用get/load/find/query等查询方法时,先查询缓存区查询,没有再查询数据库,查询出来的数据,默认在session缓存存在一份,再从缓存区返回;
一级缓存不可卸载,只要使用了session,肯定用到session缓存;
二级缓存:sessionfactory缓存可以做到多个session共享数据,是应用级别缓存,可以缓存整个应用的持久化类对象
即使关闭当前session对象,新建的session对象仍然可以使用
缓存清理:
- transation.commit();会先清理缓存,再数据库提交
- session.flush();会清理缓存
- session查询,若缓存对象有变则清理缓存
检索策略:
类级别:立即检索(get)和延迟检索(load)
关联级别:立即检索和延迟检索、迫切左外连接
数据源属性配置:
加载驱动:<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
url:<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate?characterEncoding=UTF-8</property>
username:<property name="hibernate.connection.username">root</property>
password:<property name="hibernate.connection.password">123456</property>
检索方式:
HQL:
query常用五个方法:
query.setParameter、query.setFirstResult、query.setMaxResults、query.list()、query.uniqueResult()
HQL(hibernate query language)检索方式:使用面向对象的hql查询语言(query接口是HQL查询接口,提供各种查询功能)
-
//条件查询(具名 where name=:name) Query query= session.createQuery("from Department where name=?"); query.setParameter(0, "后勤部");
-
//分页查询 Query query= session.createQuery("from Department"); query.setFirstResult(0);//起始行数据,从0开始 query.setMaxResults(3);//每页显示几条数据
-
//聚合查询(查总数,返回类型可强转为long) Query query= session.createQuery("select count(id) from Department");
-
//投影查询----查询局部字段 (返回object数组,无法转成对象) Query query= session.createQuery("select name,telephone from Employee"); (返回Employee对象,利用HQL动态构造实例的功能对平面数据进行封装) Query query= session.createQuery("select new Employee(name,telephone) from Employee");
-
//删除&&添加&&查询&&修改 session.delete(department);&&session.save(department);&&session.load(Department.class,1);&&session.executeUpdate();
- query.uniqueResult();&&query.list();
QBC:
QBC(query by criteria按条件查询)检索方式:使用qbcAPI来检索对象,该API封装了基于字符串形式的查询语言,提供了更加面向对象的接口
-
//全名查询 Criteria ce=session.createCriteria(Department.class);
-
//条件查询 Criteria ce=session.createCriteria(Employee.class); //添加查询条件(Restrictions-限制) //ce.add(Restrictions.like("name", "%小%")); //多个条件 ce.add(Restrictions.and(Restrictions.like("name", "%小%"),Restrictions.like("telephone", "%6%")));
-
//分页查询 Criteria ce=session.createCriteria(Employee.class); ce.setFirstResult(0);//起始行数据,从0开始 ce.setMaxResults(5);//每页显示几条数据
-
//聚合查询----查询数据总数(返回的是long对象) Criteria ce=session.createCriteria(Department.class); //ce.setProjection(Projections.count("id")); ce.setProjection(Projections.max("id"));//Projections-投影
-
//投影查询----查询局部字段 Criteria ce=session.createCriteria(Employee.class); ProjectionList plist=Projections.projectionList(); plist.add(Property.forName("name")); plist.add(Property.forName("telephone")); ce.setProjection(plist);
Criteria criteria =session.createCriteria(Student.class);
criteria.add(Restrictions.and(Restrictions.eq("name", student.getName()),Restrictions.eq("password", student.getPassword())));
Student u=(Student)criteria.uniqueResult();
u.setPassword(password);
u.setBirthday(birthday);
session.update(u);
SQL:
SQL(本地检索方式):使用本地数据库的sql语句来查询
- PreparedStatement ps=this.connection.prepareStatement("insert into admin(loginName)"+"values(?,?,?)");
ps.setString(1, admin.getLoginName());
ps.execute(); - PreparedStatement ps=this.connection.prepareStatement("delect from admin where loginName=?");
ps.setString(1, loginName);
ps.execute(); - PreparedStatement ps=this.connection.prepareStatement("select * from coursearrange where arrangeNo=?");
ps.setString(1, arrangeNo);
rs=ps.executeQuery(); - PreparedStatement ps = this.connection.prepareStatement("update course set courseNo=?where courseNo=?");
ps.setString(1, course.getCourseNo()); ps.setString(7, course.getCourseNo());
ps.executeUpdate();