Hibernate/MyBatis复习
1.脏检查是实务提交时候进行的
2.刷新缓存:刷新缓存就是进行脏检查
两种方式:
事务提交:commit();
session.flush();
3.关于HQL
from Dept 检索所有部门的信息
select d from cn.happy.entity.Dept d 检索所有部门的信息
select d from Dept d
4.详解HQL
setParameter( )方法用于绑定任意类型的参数
setParameter( )有重载的方法
setProperties( )有重载的方法
setProperties( )方法用于绑定命名参数
5.Dept.hbm.xml
<hibernate-mapping package="cn.jbit.hibernatedemo.entity"> <class name="Emp" table="EMP" schema="scott"> scott用户 <id name="empNo" column="EMPNO" type="int/java.lang.Integer"> <generator class="assigned"/> </id> <property name="salary" type="java.lang.Double" column="SAL"/> <property name="hireDate" type="java.util.Date"/> <many-to-one Emp多一方 name="dept" column="DEPTNO" class="Dept" /> </class> </hibernate-mapping>
--OOP程序端
public class Emp{ private Dept dept; }
---SQL端
DEPTNO
6.invere
解析:维护关联关系
true:自己不维护关联关系,对方维护
false:自己维护关联关系
7.延迟加载 lazy hibernate 3.6.10版 hibernate 5
分类
类级别 true(默认),false
一对多和多对多 true(default),false,extra(加强延迟加载)
多对一(没有set) proxy(default),no-proxy,false
8.component组件映射
<hibernate-mapping package="cn.happy.component"> <class name="EmpInfo" table="EMPINFO"> <id name="eid" column="EID"> <generator class="native"></generator> </id> <property name="ename" column="ENAME" type="string"></property> <component name="ehome" class="EmpHomeAddress"> <parent name="empinfo"/> <property name="ehomestreet" column="EHOMESTREET" type="string"></property> <property name="ehomecity" column="EHOMECITY" type="string"></property> <property name="ehomeprovince" column="EHOMEPROVINCE" type="string"></property> <property name="ehomezipcode" column="EHOMEZIPCODE" type="string"></property> </component> </class> </hibernate-mapping>
9.ExecutorType
public final enum org.apache.ibatis.session.ExecutorType { // Field descriptor #8 Lorg/apache/ibatis/session/ExecutorType; public static final enum org.apache.ibatis.session.ExecutorType SIMPLE; // Field descriptor #8 Lorg/apache/ibatis/session/ExecutorType; public static final enum org.apache.ibatis.session.ExecutorType REUSE; // Field descriptor #8 Lorg/apache/ibatis/session/ExecutorType; public static final enum org.apache.ibatis.session.ExecutorType BATCH; }
10.HQL的连接查询
inner join 或 join用于内连接
inner join fetch或 join fetch用于迫切内连接
left outer join fetch 或 left join fetch用于迫切左外连接
11.批量处理数据
方式一:
使用HQL语句
原理: executeUpdate
01.批量插入数据
@Test public void testInsert(){ Session session = HibernateUtil.getSession(); Transaction tx=session.beginTransaction(); String hql="insert into Dept(deptName) select d.deptName||d.deptNo from Dept d where d.deptNo>0"; session.createQuery(hql).executeUpdate(); tx.commit(); }
方式二:JDBCAPI
//使用JDBC API进行批量修改 public void testUpdateUseJDBC(){ Session session = HibernateUtil.getSession(); Transaction tx=session.beginTransaction(); Work work=new Work() { @Override public void execute(Connection connection) throws SQLException { String sql="update DEPTY2160New set deptName=? where deptNo>?"; PreparedStatement ps = connection.prepareStatement(sql); ps.setString(1, "财务部2"); ps.setInt(2, 1); ps.executeUpdate(); } }; session.doWork(work); tx.commit(); }
方式三: 使用Session进行批量操作
public void testAdd(){ Session session = HibernateUtil.getSession(); Transaction tx=session.beginTransaction(); Emp emp=null; for (int i = 0; i < 10000; i++) { emp=new Emp(i, "emp"+i); session.save(emp); if (i%30==0) { session.flush(); session.clear(); } } tx.commit(); }
little tip:
(1)使用HQL进行批量操作 数据库层面 executeUpdate()
(2)使用JDBC API进行批量操作 数据库层面
(3)使用Session进行批量操作 会进缓存
little tip2:
C.使用Session进行批量操作,数据会被加载到Session缓存,需注意刷新并清空缓存
D.使用Session进行批量操作,适用于需要通过代码处理的复杂的业务逻辑场景
12.HQL面向的是对象和属性,不是表和字段
关于HQL的聚合函数使用,说法正确的是(ABCD )。
select count(*) from Dept d用于统计部门个数
select sum(e.salary) from Emp e用于汇总员工工资总额
select max(e.hiredate) from Emp e用于找到最新入职的员工的入职时间
select min(e.hiredate) from Emp e用于找到最早入职的员工的入职时间
13.原生SQL查询和命名查询
Query query=session.createQuery(hql)
SQLQuery query=session.createSQLQuery(sql)
1.原生SQL查询
@Test //原生SQL执行 public void testClassicSQL(){ SQLQuery query = session.createSQLQuery("select * from deptY2160new").addEntity(Dept.class); List<Dept> list = query.list(); for (Dept dept : list) { System.out.println(dept.getDeptName()); } tx.commit(); }
2.命名查询
<!-- -原生SQL NullPointException --> <sql-query name="selectEmpByDetpNoClassicSQL"> <return alias="e" class="Emp" ></return> select {e.*} from EmpY2160new e where deptNo=:deptNo </sql-query>
测试类
public void testNamedClassicSQL(){ Query query = session.getNamedQuery("selectEmpByDetpNoClassicSQL"); List<Emp> list = query.setParameter("deptNo", 1).list(); /* for (Emp emp : list) { System.out.println(emp.getEmpName()); }*/ tx.commit(); }
14.Hibernate常见注解
@Id
@Column
@Table
@Entity
@GeneratedValue
@ManyToOne
@JoinColumn
/** * 部门类 * @author Happy 2016年1月17日19:40:56 * */ @Entity 标识一个类是 持久化类 @Table(name="DeptY2160") public class Dept { @Id 持久化类的标识 Hibernate_Session @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="seq_gen") 定义自己的序列生成器 @SequenceGenerator(name="seq_gen",sequenceName="SEQ_Num",allocationSize=1,initialValue=1) private Integer deptNo; private String deptName; @OneToMany(mappedBy="dept",cascade={CascadeType.ALL}) /* @Fetch(FetchMode.JOIN) @LazyCollection(LazyCollectionOption.FALSE)*/ private Set<Emp> emps=new HashSet<Emp>(); public Set<Emp> getEmps() { return emps; } public void setEmps(Set<Emp> emps) { this.emps = emps; } public Dept(Integer deptNo, String deptName) { this.deptNo = deptNo; this.deptName = deptName; } public Dept() { } public Integer getDeptNo() { return deptNo; } public void setDeptNo(Integer deptNo) { this.deptNo = deptNo; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } }
15.主键生成策略
@GeneratedValue用于定义主键值的生成策略 ,相当于native