private Session session = null;
private Transaction trans = null;
// 命令的执行顺序
@Test
public void testSessionOnFlush() {
User user = new User();
user.setUsername("李四");
user.setSex('男');
user.setAge(44);
user.setBirthday(new Date());
user.setSalary(548548.56);
// user.setId(5);
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// ...
User u = (User) session.get(User.class, 1);
// 不执行flush()方法在提交后的发出的sql语句的默认顺序就是:查、曾、改、删
// 执行flush()方法会提前发出sql语句,然后刷新缓存
u.setUsername("王麻子");
session.flush();
session.delete(session.get(User.class, 4));
session.flush();
session.save(user);
session.flush();
user = new User();
user.setUsername("赵六");
user.setSex('男');
user.setAge(44);
user.setBirthday(new Date());
user.setSalary(548548.56);
session.save(user);
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
close、clear及evict方法的区别
private Session session = null;
private Transaction trans = null;
// close()、clear()和evict()方法
@Test
public void testClearAndEvict() {
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
Query query = session
.createQuery("from com.alyshen.hibernate.domain.User");
List list = query.list();
// session.clear();//
// 清空缓存,查询出来的对象都变成离线、托管对象的了,拉入缓存则需要:session.update(user);
int i = 0;
for (User user : list) {
i++;
if (i == 5) {
session.evict(user);// 驱逐
}
user.setUsername(user.getUsername() + "_X");
// session.update(user);
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
//close();session直接被回收
HibernateUtil.closeSession(session);
}
}
get和load方法的区别
private Session session = null;
private Transaction trans = null;
// get()和load()方法的区别
@Test
public void testGetAndLoad() {
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// User user = (User) session.get(User.class, 11);
User user = (User) session.load(User.class, 11);
// 懒加载,创建的是一个对象的代理,如果查询出来为空则创建不了代理就抛异常
// 如果不需要懒加载,则可以在实体映射文件配置中配置:lazy="false",配置后跟使用get一样,
//只有在使用对象的时候,用对象的代理对象发出sql语句
System.out.println(user);
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
list和iterator方法的区别
private Session session = null;
private Transaction trans = null;
// list()和iterator()方法
@Test
public void testListAndIterator() {
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
Query query = session.createQuery("from User");
// list()全部查询出来,无法利用缓存
List list = query.list();
for (User user : list) {
System.out.println("用户名:" + user.getUsername());
}
// list = query.list();
//
// for (User user : list) {
// System.out.println("用户名:" + user.getUsername());
// }
// 先把所有id查询出来,然后有id去单个的查询,可以利用缓存
Iterator iter = query.iterate();
while (iter.hasNext()) {
User user = iter.next();
System.out.println("用户名:" + user.getUsername());
}
//理想是方式就是先用list查出来,再用的话就用iterate
// iter = query.iterate();
// while (iter.hasNext()) {
// User user = iter.next();
// System.out.println("用户名:" + user.getUsername());
// }
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
F. 主键生成策略
常用主键生成策略 User.hbm.xml
联合主键生成策略(不常用)
UserKey.java
public class UserKey implements Serializable {
private int id;
private String uuid;
/**
* 重写hashCode方法
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
return result;
}
/**
* 重写equals方法
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
UserKey other = (UserKey) obj;
if (id != other.id)
return false;
if (uuid == null) {
if (other.uuid != null)
return false;
} else if (!uuid.equals(other.uuid))
return false;
return true;
}
public UserKey(int id, String uuid) {
super();
this.id = id;
this.uuid = uuid;
}
public UserKey() {
super();
// TODO Auto-generated constructor stub
}
//各种set、get方法
……
}
private int id;
private String name;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ContactPerson other = (ContactPerson) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
//各种set、get方法
……
2) ContactPerson.hbm.xml
3) Group.java
private int id;
private String groupName;
private Set persons = new HashSet();
//各种set、get方法
……
4) Group.hbm.xml
5) 添加及查询
private Session session = null;
private Transaction trans = null;
/**
* 一对多单向关联——添加
*/
@Test
public void testOne2ManyAdd() {
Group group = new Group();
group.setGroupName("同学");
ContactPerson p1 = new ContactPerson();
p1.setName("张三");
ContactPerson p2 = new ContactPerson();
p2.setName("李四");
ContactPerson p3 = new ContactPerson();
p3.setName("王五");
group.addPerson(p1);
group.addPerson(p2);
group.addPerson(p3);
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
// 多余的更新sql语句没法去掉
session.save(p1);
session.save(p2);
session.save(p3);
session.save(group);
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
/**
* 一对多单向关联——查询数据
*/
@Test
public void testOne2ManyQuery() {
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
ContactPerson person = (ContactPerson) session.get(
ContactPerson.class, 1);
System.out.println(person.getName());
Group group = (Group) session.get(Group.class, 1);
Iterator iter = group.getPersons().iterator();
while (iter.hasNext()) {
System.out.println(iter.next().getName());
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
a) 一对多关联的重建和级联操作 1) 级联添加
private Session session = null;
private Transaction trans = null;
/**
* 一对多单向关联——级联添加
*/
@Test
public void testOne2ManyCascadeAdd2() {
Group group = new Group();
group.setGroupName("同事");
ContactPerson p1 = new ContactPerson();
p1.setName("王二");
ContactPerson p2 = new ContactPerson();
p2.setName("麻子");
ContactPerson p3 = new ContactPerson();
p3.setName("赵六");
group.addPerson(p1);
group.addPerson(p2);
group.addPerson(p3);
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
session.save(group);
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
2) 级联删除
private Session session = null;
private Transaction trans = null;
/**
* 一对多单向关联——级联删除
*/
@Test
public void testOne2ManyCascadeDelete() {
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
Group group = (Group) session.get(Group.class, 2);
session.delete(group);
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
3) 离线对象级联删除失效
private Session session = null;
private Transaction trans = null;
/**
* 一对多单向关联——离线对象级联删除失效
*/
@Test
public void testOne2ManyCascadeDelete2() {
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
Group group = new Group();
group.setId(1);// 创建离线对象
session.delete(group);
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
a) 一对多关联的延迟加载、修改、删除及清空 1) 不懒加载
private Session session = null;
private Transaction trans = null;
/**
* 一对多单向关联——不懒加载
*/
@Test
public void testOne2ManyLazyDoFalse() {
Group group = null;
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
group = (Group) session.get(Group.class, 2);
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
System.out.println(group.getGroupName());
for (ContactPerson person : group.getPersons()) {
System.out.println(person.getName());
}
}
2) 修改
private Session session = null;
private Transaction trans = null;
/**
* 一对多单向关联——修改
*/
@Test
public void testOne2ManyUpdate() {
Group group = null;
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
group = (Group) session.get(Group.class, 2);
ContactPerson person = (ContactPerson) session.get(
ContactPerson.class, 1);
group.addPerson(person);
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
System.out.println(group.getGroupName());
for (ContactPerson person : group.getPersons()) {
System.out.println(person.getName());
}
}
3) 从组里清除
private Session session = null;
private Transaction trans = null;
/**
* 一对多单向关联——从组里清除
*/
@Test
public void testOne2ManyRemove() {
Group group = null;
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
group = (Group) session.get(Group.class, 2);
ContactPerson person = (ContactPerson) session.get(
ContactPerson.class, 4);
group.getPersons().remove(person);
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
System.out.println(group.getGroupName());
for (ContactPerson person : group.getPersons()) {
System.out.println(person.getName());
}
}
4) 清空组
private Session session = null;
private Transaction trans = null;
/**
* 一对多单向关联——清空组
*/
@Test
public void testOne2ManyClear() {
Group group = null;
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
group = (Group) session.get(Group.class, 2);
group.getPersons().clear();
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
System.out.println(group.getGroupName());
for (ContactPerson person : group.getPersons()) {
System.out.println(person.getName());
}
}
b) 聪明的extra(推荐一对多延迟加载策略) 1) Group.hbm.xml
2) 测试Extra
private Session session = null;
private Transaction trans = null;
/**
* 这个测试Extra和普通延迟加载没区别
*/
@Test
public void testQuery() {
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
Group group = (Group) session.get(Group.class, 1);
System.out.println(group.getGroupName());
for (ContactPerson p : group.getPersons()) {
System.out.println(p.getName());
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
/**
* 这个测试Extra加载获取条数
*/
@Test
public void testQueryCount() {
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
Group group = (Group) session.get(Group.class, 1);
// 普通延迟加载就会把联系人全部查出来,再算大小
// 而extra加载直接去查条数
System.out.println(group.getGroupName() + "组里有联系人:"
+ group.getPersons().size() + "个!");
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
/**
* 这个测试Extra加载是否包含某个联系人
*/
@Test
public void testCheckContains() {
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
Group group = (Group) session.get(Group.class, 1);
ContactPerson p = new ContactPerson();
p.setId(3);
//普通懒加载加载为false,extra懒加载为true
System.out.println(group.getPersons().contains(p));
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
一对多双向关联
a) 一对多双向关联及inverse的用法 1) Group.java
private int id;
private String groupName;
private Set persons = new HashSet();
//各种set、get方法
……
2) Group.hbm.xml
3) ContactPerson.java
private int id;
private String name;
private Group group;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ContactPerson other = (ContactPerson) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
//各种set、get方法
……
4) ContactPerson.hbm.xml
5) 测试一对多双向关联
private Session session = null;
private Transaction trans = null;
/**
* 一对多双向关联,由一的一端维护数据,所以多的一端多了update语句
*/
@Test
public void testOne2ManyAdd() {
Group group = new Group();
group.setGroupName("同学");
ContactPerson p1 = new ContactPerson();
p1.setName("张三");
ContactPerson p2 = new ContactPerson();
p2.setName("李四");
ContactPerson p3 = new ContactPerson();
p3.setName("王五");
group.addPerson(p1);
group.addPerson(p2);
group.addPerson(p3);
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
session.save(group);
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
/**
* 一对多双向关联,由多的一端维护数据
*/
@Test
public void testOne2ManyAdd2() {
Group group = new Group();
group.setGroupName("同事");
ContactPerson p1 = new ContactPerson();
p1.setName("王二");
ContactPerson p2 = new ContactPerson();
p2.setName("麻子");
ContactPerson p3 = new ContactPerson();
p3.setName("赵六");
p1.setGroup(group);
p2.setGroup(group);
p3.setGroup(group);
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
session.save(p1);
session.save(p2);
session.save(p3);
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
6) inverse的用法
private Session session = null;
private Transaction trans = null;
/**
* 一对多双向关联,由两端维护数据,多了update语句
* ,set集合的inverse="true":一的一端放弃维护数据的统一,只有添加sql语句,
* 一的一端不再更新其他有关联的数据
*/
@Test
public void testOne2ManyAdd3() {
Group group = new Group();
group.setGroupName("朋友");
ContactPerson p1 = new ContactPerson();
p1.setName("李三");
ContactPerson p2 = new ContactPerson();
p2.setName("王五");
ContactPerson p3 = new ContactPerson();
p3.setName("赵七");
p1.setGroup(group);
p2.setGroup(group);
p3.setGroup(group);
group.addPerson(p1);
group.addPerson(p2);
group.addPerson(p3);
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
session.save(group);
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
b) 一对多双向关联重建及外键定义不一致导致的问题 1) 关联重建
private Session session = null;
private Transaction trans = null;
/**
* 测试一对多双向关联关联重建
*/
@Test
public void testOne2ManyQuery() {
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
Group group = (Group) session.get(Group.class, 2);
System.out.println(group.getGroupName() + "当中有元素:");
for (ContactPerson person : group.getPersons()) {
System.out.println(person.getName() + ",所属组:"
+ person.getGroup().getGroupName());
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
2) 外键定义不一致导致的问题
c) 一对多双向自关联 1) Employee.java
private int id;
private String name;
private Employee manager;
private Set puisnes = new HashSet();
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
//各种set、get方法
……
c) 集合映射(List集合) 1) Thing.java private int id; private String name; //各种set、get方法 2) Thing.hbm.xml
3) Person.java private int id; private String name; private List menu = new ArrayList (); private List things = new ArrayList (); //各种set、get方法 4) Person.hbm.xml
/**
* 测试集合Map映射添加
*/
@Test
public void testAdd() {
Person person = new Person();
person.setName("张三");
person.getImages().put("img1", "c:/image/1.jpg");
person.getImages().put("img2", "c:/image/2.jpg");
person.getImages().put("img3", "c:/image/3.jpg");
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
session.save(person);
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
/**
* 测试集合Map映射重建
*/
@Test
public void testQuery() {
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
Person person = (Person) session.get(Person.class, 1);
System.out.println(person.getName());
System.out.println(person.getImages().get("img1"));
/**
* 将map集合中所有元素的键放在一个set集合中,
* 然后遍历这个set集合根据每个键去取值
*/
Set keys = person.getImages().keySet();
for (String key : keys) {
System.out.println(person.getImages().get(key));
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
I. HQL(Hibernate Query Language)
HQL查询基本规则及查询方法
private Session session = null;
private Transaction trans = null;
/**
* hql查询
*/
@Test
public void testQuery() {
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
// String hql = "FROM com.alyshen.hibernate.domain.User";// 标准hql
// String hql = "FROM User";// 如果User在整个项目是唯一的
// String hql = "FROM User AS u";// 设置别名
// String hql = "FROM User u";// 设置别名
String hql = "Select u FROM User u";// 设置别名,加select
Query query = session.createQuery(hql);
List list = query.list();
for (User u : list) {
System.out.println(u.getUsername());
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
HQL条件参数查询
a) 硬编码
private Session session = null;
private Transaction trans = null;
/**
* hql参数查询(硬编码)
*/
@Test
public void testQuery() {
int max = 23;
int min = 10;
String param = "'%2%'";
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
// String hql = "Select u FROM User u WHERE u.id > 10 AND u.id < 23";
// String hql = "Select u FROM User u WHERE u.id BETWEEN 10 AND 23";
// BETWEEN:在……之间(包含数字)
String hql = "Select u FROM User u WHERE u.id BETWEEN " + min
+ " AND " + max + " AND u.username like " + param;
Query query = session.createQuery(hql);
List list = query.list();
for (User u : list) {
System.out.println(u.getUsername());
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
b) 匿名参数 private Session session = null; private Transaction trans = null; /** * hql参数查询(参数查询:匿名参数) */ @Test public void testQuery2() {
int max = 23;
int min = 10;
String param = "%2%";// 不需要单引号''了
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
String hql = "Select u FROM User u WHERE u.id BETWEEN ? AND ? AND u.username like ?";
Query query = session.createQuery(hql);
query.setParameter(0, min);
query.setParameter(1, max);
query.setParameter(2, param);
List list = query.list();
for (User u : list) {
System.out.println(u.getUsername());
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
c) 命名参数
private Session session = null;
private Transaction trans = null;
/**
* hql参数查询(参数查询:命名参数)
*/
@Test
public void testQuery3() {
int max = 23;
int min = 10;
String param = "%2%";// 不需要单引号''了
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
String hql = "Select u FROM User u WHERE u.id BETWEEN :min AND :max AND u.username like :param";
Query query = session.createQuery(hql);
query.setParameter("min", min);
query.setParameter("max", max);
query.setParameter("param", param);
List list = query.list();
for (User u : list) {
System.out.println(u.getUsername());
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
HQL集合类型的参数查询
private Session session = null; private Transaction trans = null;
/**
hql集合参数查询(命名参数) */ @Test public void testQuery() {
try { session = HibernateUtil.getSession(); trans = session.beginTransaction(); // ..... // String hql = "Select u FROM User u WHERE u.id IN(1,2,3,4,5,6,7)"; String hql = "Select u FROM User u WHERE u.id IN(:ids)";
List ids = new ArrayList();
ids.add(1);
ids.add(2);
ids.add(3);
ids.add(4);
ids.add(5);
ids.add(6);
ids.add(7);
Query query = session.createQuery(hql);
/**
* 不能使用普通的设置参数方法
*/
query.setParameterList("ids", ids);
List list = query.list();
for (User u : list) {
System.out.println(u.getId() + ":" + u.getUsername());
}
trans.commit();
try { session = HibernateUtil.getSession(); trans = session.beginTransaction(); // .....
// String hql = "Select u FROM User u WHERE u.username=NULL"; // =NULL:Hibernate容错处理,不建议
// String hql = "Select u FROM User u WHERE u.username IS NULL"; // String hql = "Select u FROM User u WHERE u.group.id IS NULL"; String hql = "Select u FROM User u WHERE u.group IS NULL";
Query query = session.createQuery(hql);
List list = query.list();
for (User u : list) {
System.out.println(u.getId() + ":" + u.getUsername());
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
hql聚合函数及uniqueResult() */ @Test public void testQuery() {
try { session = HibernateUtil.getSession(); trans = session.beginTransaction(); // .....
String hql = "Select COUNT(*) FROM User";
Query query = session.createQuery(hql);
// List list = query.list();
// System.out.println(list.get(0));
//当确定只有一条记录时用uniqueResult方法
Long c = (Long) query.uniqueResult();
System.out.println(c);
hql = "SELECT u FROM User u WHERE u.id = 115";
query = session.createQuery(hql);
User u = (User) query.uniqueResult();
System.out.println(u);
System.out.println(u.getUsername());
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
HQL分组聚合及having子句
private Session session = null; private Transaction trans = null; @Test public void testQuery() { try { session = HibernateUtil.getSession(); trans = session.beginTransaction(); // ..... /** * hql分组聚合函数 / // 使用投影,返回对象集合(包含u.group.groupName,COUNT()的对象数组) String hql = "Select u.group.groupName,COUNT(*) FROM User u GROUP BY u.group"; Query query = session.createQuery(hql);
// 一个字段包装成一个对象,一行字段包装成一个对象数组,
//将每行字段包装成的每个对象数组放入到list集合中
List objss = query.list();
for (Object[] objs : objss) {
System.out.println(objs[0] + ":" + objs[1]);
}
/**
* hql分组聚合条件
*/
// 使用投影,返回对象数组(包含u.group.groupName,COUNT(*)的对象数组)
// 聚合过的数据只能用HAVING,不能用WHERE
hql = "Select u.group.groupName,COUNT(*) FROM User u Group BY u.group HAVING COUNT(*)<90";
query = session.createQuery(hql);
// 一个字段包装成一个对象,一行字段包装成一个对象数组,
//将每行字段包装成的每个对象数组放入到list集合中
objss = query.list();
for (Object[] objs : objss) {
System.out.println(objs[0] + ":" + objs[1]);
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
/**
添加测试数据 */ @Test public void testAdd() {
Group g1 = new Group(); g1.setGroupName("一组"); Group g2 = new Group(); g2.setGroupName("二组"); Group g3 = new Group(); g3.setGroupName("三组"); Group g4 = new Group(); g4.setGroupName("四组"); Group g5 = new Group(); g5.setGroupName("五组");
try { session = HibernateUtil.getSession(); trans = session.beginTransaction(); // ..... for (int i = 0; i < 500; i++) { User user = new User(); user.setUsername("用户_" + new Random().nextInt(9999)); user.setPassword("密码_" + new Random().nextInt(9999)); if (i <= 50) { user.setGroup(g1); } else if (i <= 120) { user.setGroup(g2); } else if (i <= 200) { user.setGroup(g3); } else if (i < 300) { user.setGroup(g4); } else { user.setGroup(g5); } session.save(user); } trans.commit(); } catch (HibernateException e) { trans.rollback(); e.printStackTrace(); } finally { HibernateUtil.closeSession(session); } }
HQL投影查询
a) 投影查询 private Session session = null; private Transaction trans = null; @Test public void testQuery() { try { session = HibernateUtil.getSession(); trans = session.beginTransaction(); // .....
String hql = "Select u.id FROM User u";
Query query = session.createQuery(hql);
List ids = query.list();
for (Integer id : ids) {
System.out.println(id);
}
hql = "Select u.username FROM User u";
query = session.createQuery(hql);
List names = query.list();
for (String username : names) {
System.out.println(username);
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
b) 投影查询(多列) private Session session = null; private Transaction trans = null; @Test public void testQuery2() { try { session = HibernateUtil.getSession(); trans = session.beginTransaction(); // .....
String hql = "Select u.username,u.password FROM User u";
Query query = session.createQuery(hql);
// 一个字段包装成一个对象,一行字段包装成一个对象数组,
//将每行字段包装成的每个对象数组放入到list集合中
List objss = query.list();
for (Object[] objs : objss) {
for (Object obj : objs) {
System.out.print(obj);
}
System.out.println();
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
c) 对象化投影查询(多列) private Session session = null; private Transaction trans = null; @Test public void testQuery3() { try { session = HibernateUtil.getSession(); trans = session.beginTransaction(); // .....
// User类要有这个构造方法
String hql = "Select new User(u.username,u.password) FROM User u";
Query query = session.createQuery(hql);
// 返回你有查询出的字段,每一行字段包装成一个对象数组,多行就是一个list集合的对象数组
List users = query.list();
for (User user : users) {
System.out.println(user.getUsername() + ":"
+ user.getPassword());
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
HQL中的单行函数
private Session session = null; private Transaction trans = null; @Test public void testQuery() { String hql = null; try { session = HibernateUtil.getSession(); trans = session.beginTransaction(); // ..... // 绝对值:ABS(n)、开方:SQRT(n)、除法:MOD(dividend,divisor) hql = // 转大写,转小写 // "SELECT UPPER(u.username),LOWER(u.password) FROM User u";
//合并字符串:CONCAT(s1,s2);
//update t_user set username=CONCAT(username,'siJHKjkWSdxHJIOMhKJk'),passwo
// rd=CONCAT(password,'OyrBMDcswXZgKOAq');
// 截取,参数:要截取的字符串,位置,长度
// "SELECT SUBSTRING(u.username,2,3),LOWER(u.password) FROM User u";
// 求长度
// "SELECT LENGTH(u.username),LOWER(u.password) FROM User u";
// 求位置
// "SELECT LOCATE('户',u.username),LOWER(u.password) FROM User u";
// 求字节数
// "SELECT BIT_LENGTH(u.username),LOWER(u.password) FROM User u";
// "SELECT BIT_LENGTH(20),LOWER(u.password) FROM User u";
// 日期:CURRENT_DATE()、时间:CURRENT_TIME()、时间戳:CURRENT_TIMESTAMP()、
// "SELECT CURRENT_DATE(),CURRENT_TIMESTAMP() FROM User u";
// 得到时间的某一类型的值,SECOND(d)、分:MINUTE(d)、时:HOUR(d)、天:DAY(d)、月:MOUTH(d)、年:YEAR(d)、Date(d)、
// "SELECT DAY(CURRENT_DATE()),LOWER(u.password) FROM User u";
// 类型转换
// "SELECT CAST('2015-2-8' AS date),LOWER(u.password) FROM User u";
"SELECT CAST('25455' AS int),LOWER(u.password) FROM User u";
Query query = session.createQuery(hql);
List objs = query.list();
for (Object[] os : objs) {
System.out.println((Integer) os[0] + ":" + os[1]);
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
HQL分页查询和排序
private Session session = null; private Transaction trans = null; @Test public void testQuery() { String hql = null; try { session = HibernateUtil.getSession(); trans = session.beginTransaction(); // .....
// 查询所有用户并降序
hql = "SELECT u FROM User u ORDER BY u.id DESC";
Query query = session.createQuery(hql);
// 分页参数
query.setFirstResult(32);//从32条开始
query.setMaxResults(10);
List users = query.list();
for (User user : users) {
System.out.println(user.getId() + ":" + user.getUsername());
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
// 查询所有用户包括组的一些字段(使用cross join交叉连接,耗资源,不建议使用)
hql = "SELECT u.id,u.username FROM User u WHERE u.group.groupName LIKE '%二%'";
Query query = session.createQuery(hql);
List objs = query.list();
for (Object[] os : objs) {
System.out.println(os[0] + ":" + os[1]);
}
trans.commit();
// 这使用的还是交叉连接:cross join
// "SELECT u.id,u.username,g.id,g.groupName FROM User u,Group g";
// 使用的内链接:inner join
// "SELECT u.id,u.username,g.id,g.groupName FROM User u JOIN u.group g";
// 加参数
hql = "SELECT u.id,u.username,g.id,g.groupName FROM User u JOIN u.group g WHERE g.groupName LIKE '%二%'";
Query query = session.createQuery(hql);
List objs = query.list();
for (Object[] os : objs) {
System.out.println(os[0] + ":" + os[1] + "," + os[2] + ":"
+ os[3]);
}
trans.commit();
a) 添加测试数据 private Session session = null; private Transaction trans = null; @Test public void testAdd() {
Group g1 = new Group();
g1.setGroupName("一组");
Group g2 = new Group();
g2.setGroupName("二组");
Group g3 = new Group();
g3.setGroupName("三组");
Group g4 = new Group();
g4.setGroupName("四组");
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
for (int i = 0; i < 200; i++) {
User user = new User();
user.setUsername("用户_" + new Random().nextInt(9999));
user.setPassword("密码_" + new Random().nextInt(9999));
if (i <= 50) {
user.setGroup(g1);
} else if (i <= 80) {
user.setGroup(g2);
} else if (i <= 120) {
user.setGroup(g3);
} else if (i < 160) {
user.setGroup(g4);
}
session.save(user);
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
b) 显式左外链 private Session session = null; private Transaction trans = null; @Test public void testQuery() { String hql = null; try { session = HibernateUtil.getSession(); trans = session.beginTransaction(); // .....
// 左边的全部查出来:left outer join
hql = "SELECT u.id,u.username,g.groupName FROM User u LEFT JOIN u.group g";
Query query = session.createQuery(hql);
List objs = query.list();
for (Object[] os : objs) {
System.out.println(os[0] + ":" + os[1] + "," + os[2]);
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
c) 显式右外链 private Session session = null; private Transaction trans = null; @Test public void testQuery2() { String hql = null; try { session = HibernateUtil.getSession(); trans = session.beginTransaction(); // .....
// 右边的全部查出来:right outer join
hql = "SELECT u.id,u.username,g.groupName FROM Group g RIGHT JOIN g.users u";
Query query = session.createQuery(hql);
List objs = query.list();
for (Object[] os : objs) {
System.out.println(os[0] + ":" + os[1] + "," + os[2]);
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
HQL不相关子查询及相关子查询
a) 添加测试数据 private Session session = null; private Transaction trans = null; @Test public void testAdd() {
Group g1 = new Group();
g1.setGroupName("一组");
Group g2 = new Group();
g2.setGroupName("二组");
Group g3 = new Group();
g3.setGroupName("三组");
Group g4 = new Group();
g4.setGroupName("四组");
Group g5 = new Group();
g5.setGroupName("五组");
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
for (int i = 0; i < 200; i++) {
User user = new User();
user.setUsername("用户_" + new Random().nextInt(9999));
user.setPassword("密码_" + new Random().nextInt(9999));
if (i <= 50) {
user.setGroup(g1);
} else if (i <= 80) {
user.setGroup(g2);
} else if (i <= 120) {
user.setGroup(g3);
} else if (i < 160) {
user.setGroup(g4);
}
session.save(user);
}
session.save(g5);
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
b) 不相关子查询 private Session session = null; private Transaction trans = null; @Test public void testQuery() { String hql = null; try { session = HibernateUtil.getSession(); trans = session.beginTransaction(); // .....
// // 未分组的用户
// hql =
// "SELECT u.id,u.username FROM User u WHERE u.group.id IS NULL";
// 用户id是组id的用户
//子查询中没有引用查询中的引用就是不相关子查询
hql = "SELECT u.id,u.username FROM User u WHERE u.id IN( SELECT g.id FROM Group g)";
Query query = session.createQuery(hql);
List objs = query.list();
for (Object[] os : objs) {
System.out.println(os[0] + ":" + os[1]);
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
c) 相关子查询 private Session session = null; private Transaction trans = null; @Test public void testQuery2() { String hql = null; try { session = HibernateUtil.getSession(); trans = session.beginTransaction(); // .....
// 查询组中用户数大于35的组
// 在(SELECT COUNT(*) FROM g.users) 中引用g,叫相关子查询
// 在子查询中引用查询中的别名就是相关子查询
hql = "SELECT g FROM Group g WHERE(SELECT COUNT(*) FROM g.users) > 35";
Query query = session.createQuery(hql);
List groups = query.list();
for (Group group : groups) {
System.out.println(group.getId() + ":" + group.getGroupName());
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
HQL外置命名查询
a) User.hbm.xml
……
<[CDATA[ SELECT u FROM User u WHERE u.id < ? ]]>
b) 测试外置命名查询 @Test public void testSearchUser() { String hql = null; try { session = HibernateUtil.getSession(); trans = session.beginTransaction(); // .....
// hql = "SELECT u FROM User u WHERE u.id < ?";
// Query query = session.createQuery(hql);
// Query query = session.getNamedQuery("searchUser");
// query.setParameter(0, 20);
// List users = query.list();
// 这样也行
List users = session.getNamedQuery("searchUser")
.setParameter(0, 20).list();
for (User user : users) {
System.out.println(user.getId() + ":" + user.getUsername());
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
// 使用过滤器
session.enableFilter("queryFilter").setParameter("condition", 20);
hql = "SELECT u FROM User u";
List users = session.createQuery(hql).list();
for (User user : users) {
System.out.println(user.getId() + ":" + user.getUsername());
}
trans.commit();
@Test
public void testQuery() {
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
/**
* hibernate使用原生SQL查询出来的实体缓存不了,
* 有些sql语句hibernate写不了,只能用本地sql
*/
// // String sql = "select * from t_user";
//
// String sql = "select username,password from t_user";
//
// SQLQuery sqlquery = session.createSQLQuery(sql);
// List objs = sqlquery.list();
// for (Object[] os : objs) {
// System.out.println(os[0] + ":" + os[1]);
// }
/**
* 原生SQL查询(注册实体)
*/
String sql = "select * from t_user";
SQLQuery sqlquery = session.createSQLQuery(sql);
// 将查询到的结果封装到指定的实体
sqlquery.addEntity(User.class);
List users = sqlquery.list();
for (User user : users) {
System.out.println(user.toString());
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
L. hibernate的缓存机制
hibernate的缓存结构
内置缓存(不能取消,均由session管理,线程安全,不会有线程争论问题)一级缓存 session缓存储存: 普通属性 select u.id,u.username from User u sessionFactory内置缓存储存: 实体对象(session关闭,实体销毁) from User
外置缓存(可以配置,可以取消,容易出现线程安全的问题, 管理的时候,要注意隔离级别,数据库经常讲隔离级别,因为在hibernate二级缓存当中也会有幻象读) 二级缓存储存: 实体对象(共享,session关闭,实体还在,需要配置什么时候销毁,如果不配销毁时间,生 命周期应该跟这应用程序生命周期一样长) from User 查询缓存储存: 普通属性 select u.id,u.username from User u 实体对象 存实体ID 二级缓存和查询缓存都可以跟session去交互
一级缓存
a) 测试一级缓存 private Session session = null; private Transaction trans = null; @Test public void testOneLevelCache() {
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
// // 测试get // User user = (User) session.get(User.class, 1); // System.out.println(user.getUsername()); // // user = (User) session.get(User.class, 1); // System.out.println(user.getUsername()); // // 再次查询没有发出sql语句说明是使用 缓存中的数据
// 测试load
// User user = (User) session.load(User.class, 1); // System.out.println(user.getUsername()); // // user = (User) session.load(User.class, 1); // System.out.println(user.getUsername()); // // 再次查询没有发出sql语句说明是使用 缓存中的数据
// 测试list List users = session.createQuery("FROM User").list();
User user = (User) session.load(User.class, 1);
System.out.println(user.getUsername());
user = (User) session.load(User.class, 1);
System.out.println(user.getUsername());
// 所有数据查出来了之后再次查询没有发出sql语句说明是使用 缓存中的数据
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
b) session 关闭后该session所查出的数据也被销毁 private Session session = null; private Transaction trans = null; /** * 一级缓存 * 测试session关闭后数据是否还存在缓存中 */ @Test public void testOneLevelCache2() {
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
List users = session.createQuery("FROM User").list();
User user = (User) session.load(User.class, 1);
System.out.println(user.getUsername());
user = (User) session.get(User.class, 1);
System.out.println(user.getUsername());
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
List users = session.createQuery("FROM User").list();
// session 关闭之后数据也被销毁,
//所以重新打开session查询同样的数据会重新发出一条sql语句去查数据
User user = (User) session.load(User.class, 1);
System.out.println(user.getUsername());
user = (User) session.get(User.class, 1);
System.out.println(user.getUsername());
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
c) 一级缓存对list方法及iterator方法的作用 private Session session = null; private Transaction trans = null; @Test public void testCacheQuery() {
try {
session = HibernateUtil.getSession();
trans = session.beginTransaction();
// .....
// // 测试list // List users = session.createQuery("FROM User").list(); // for (User user : users) { // System.out.println(user.getUsername()); // } // // 这次查询时又发出了一条sql语句,说明没有使用缓存, // //list方法只会把数据放到缓存中,不会从缓存中取数据 // users = session.createQuery("FROM User").list(); // for (User user : users) { // System.out.println(user.getUsername()); // }
// // 测试iterate方法 // Iterator iter = session.createQuery("FROM User").iterate(); // while (iter.hasNext()) { // System.out.println(iter.next().getUsername()); // } // // 这次只查id,说明从缓存中取数据了,但是第一次查询发出了n+1条sql语句,消耗资源 // iter = session.createQuery("FROM User").iterate(); // while (iter.hasNext()) { // System.out.println(iter.next().getUsername()); // }
// 测试list方法和iterate方法的配合使用效率
List users = session.createQuery("FROM User").list();
for (User user : users) {
System.out.println(user.getUsername());
}
// 这次只查id,说明iterate方法从缓存中取数据了,
//利用list方法一次查询存入缓存,用iterate方法去缓存中提取,提高效率
Iterator iter = session.createQuery("FROM User").iterate();
while (iter.hasNext()) {
System.out.println(iter.next().getUsername());
}
trans.commit();
} catch (HibernateException e) {
trans.rollback();
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
二级缓存 a) 用到的包及文件 oscache-2.1.jar commons-logging-1.1.3.jar oscache.properties
web.xml报错
The content of element type "web-app" must match "(icon?,display-
name?,description?,distributable?,context-param*,filter*,filter-mapping*,listener*,servlet*,s
JUnit4:Test文档中的解释:
The Test annotation supports two optional parameters.
The first, expected, declares that a test method should throw an exception.
If it doesn't throw an exception or if it
借鉴网上的思路,用java实现:
public class NoIfWhile {
/**
* @param args
*
* find x=1+2+3+....n
*/
public static void main(String[] args) {
int n=10;
int re=find(n);
System.o
在Linux中执行.sh脚本,异常/bin/sh^M: bad interpreter: No such file or directory。
分析:这是不同系统编码格式引起的:在windows系统中编辑的.sh文件可能有不可见字符,所以在Linux系统下执行会报以上异常信息。
解决:
1)在windows下转换:
利用一些编辑器如UltraEdit或EditPlus等工具
Binary search tree works well for a wide variety of applications, but they have poor worst-case performance. Now we introduce a type of binary search tree where costs are guaranteed to be loga