2012年7月31日星期二

Hibernate面试要点

get和load的区别:
1>不存在对应记录时表现不一样
2>load返回的是代理对象(javassist.jar生成二进制码),等到真正用到对象的内容才会发出SQL语句
3>get直接从数据库加载,不会延迟
无论是get还是load,都会首先查找缓存(一级缓存),如果没有,才会去数据库查找,调用clear()方法,可以强制清除session缓存
调用flush()方法可以强制进行从内存到数据库的同步。

get和load方法:
即使加载:不管是否使用,马上加载(从数据库取出放入内存),如session.get()方法。不需要session一直打开状态
优点:响应速度快,效率高
缺点:占用资源多
延迟加载:代码执行后并不马上执行sql语句从数据库获取数据,而是在使用对象是才加载,如session.load()方法。
注意,如果使用延迟加载,session要一直 处于open状态,否则报异常
优点:占用资源少
缺点:响应速度慢

SessionFactory
1>用来管理Session
2>通常情况下每个应用只需要一个SessionFactory
3>除非要访问多个数据库的情况
4>关注两个方法即可
    i>openSession每次都是新的,需要close();
    ii>getCurrentSession从上下文找,如果有,用旧的,如果没有,创建新的
        a>用途,界定事务边界
        b>事务提交自动close;
        c>current_session_context_class(jta或者thread)

thread使用connection
<一>list和iterate的区别:
a>list取出所有
b>iterate取出id,等要用的时候再根据id取出对象
c>session中的list第二次发出,仍然会倒数据库查询
d>iterate第二次,首先找session级缓存
getCurrentSession()一定要在事务中使用!!!

<二>缓存问题
i:一级缓存:
session级别的缓存

ii:二级缓存:
SessionFactory级别缓存,可以跨Session级别访问
什么对象应该放在二级缓存?
1>经常被访问
2>改动不大
3>数量有限

怎么使用二级缓存?
第一步:打开二级缓存。
第二步:在hibernate文件里面配置如下信息:<这是使用ehcache实现>true org.hibernate.cache.EhCacheProvider 
第三步:添加ehcache.xml文件
第四步:在映射类文件中添加属性:
默认情况下,load会使用二级缓存,iterate会使用二级缓存。
list会默认往二级缓存添加数据,但是查询的时候不使用。

iii:查询缓存:
是指同样的,重复查询使用的缓存。
查询缓存依赖于二级缓存,所以,需要打开二级缓存。true 写程序的时候,需要调用:Query的setCachable(true);

缓存算法:LRU,LFU,FIFO(面试意义更大,实际当中很少用到)
1.Least Recently Used
2.Least Frequently Used(命中率低)
3.First Infirst Out
memoryStoreEvictionPolicy=”LRU”(ehcache)。

<三>事务的并发处理(面试的意义更大)
并发出现的问题:
1>第一类丢失更新
2>脏读
3>不可重复读
4>幻读

设置Hibernate的设置级别:
1:read-uncommitted
2:read-uncommitted
4:repeatable-read
8:serializable

1:表的别名:select stu from Student as stu where stu.stuName=’yinlei’;

2:返回单个数据:当Sql语句返回的只有一个数值时,可以使用query.uniqueResult();
如:select stu from Student as stu where stuId=1;

3:模糊查询:select stu from Student as stu where stu.stuName like ‘yinlei’;

4:select stu.stuId,stu.stuName from Student as stu返回的不是实体对象的list,而是

5:Object[]数组list

6:命名参数类似于PreparedStatement的功能,普通占位符,使用?,但小标中从0开始,而JDBC中从1开始
示例:
String hql = “select stu from Student as stu where stu.stuAge between ? and ?”;
Query query = session.createQuery(hql);
query.setInteger(0, 22);
query.setInteger(1, 23);
List stus = query.list();

当占位符较多时,容易混淆,这时可以使用hibernate提供的命名参数查询:
示例:
String hql = “select stu from Student as stu where stu.stuAge between :minAge and :maxAge and stu.stuName like :name”;
Query query = session.createQuery(hql);
query.setInteger(“minAge”, 21);
query.setInteger(“maxAge”, 23);
query.setString(“name”, “yinlei%”);
List stus = query.list();

聚合函数示例:
String hql = “select count(stu),max(stuAge),min(stuAge),avg(stuAge),sum(stuAge) from com.yinlei.Student as stu”;
Query query = session.createQuery(hql);
Object[] objs = (Object[]) query.uniqueResult();
for(Object object : objs ){
System.out.println(object);
}

Mysql分页语法很简单:select * from student limit (nowpage-1)*pagesize,pagesize

sqlserver分页:select top 3 from student where stuId not in(select top 0 stuId from student order by stuId) order by stuId;

Hibernate的分页方法:
String hql = “from Student”;
Query query = session.createQuery(hql);
query.setFirstResult((nowPage-1)*pageSize);
query.setMaxResults(pageSize);
List stus = query.list();
HQL可以执行查询删除修改新增操作,但是只要删除操作偶尔使用。
示例:
String queryString = “update Student set stuAge = stuAge+1″;
Query query = session.createQuery(queryString);
int rows = query.executeUpdate();
t.commit();
System.out.println(rows);

java的反射机制
Class
    getMethods()得到本类以及父类的所有方法
    getDeclaerMethods得到本类的所有方法
Method
    getName()得到方法名

没有评论:

发表评论