一.使用HQL语句查询数据
1.查询所有对象记录
@Test
public void fun() {
//使用HQL查询所有User记录
Session session = HibernateUitl.getOpenSession();
Transaction transaction = session.beginTransaction();
String hql = "from com.commander.User";
Query<User> query = session.createQuery(hql);
//预见结果集
//多个就用list处理 单个就用uniqueResult处理
List<User> list = query.list();
System.out.println(list);
transaction.commit();
session.close();
}
预见结果集: 多个就用list处理 单个就用uniqueResult处理
hql语句中from后面写实体类的全类名 但是分页查询中直接写类名 但是在使用的时候还会传一个实体类名.class文件当做参数
2.用占位符
@Test
public void fun() {
//使用HQL查询所有User记录
Session session = HibernateUitl.getOpenSession();
Transaction transaction = session.beginTransaction();
String hql = "from com.commander.User where id=?";
Query<User> query = session.createQuery(hql);
query.setParameter(0, 3);
List<User> list = query.list();
System.out.println(list);
transaction.commit();
session.close();
}
3.冒号占位符
注意:冒号后面千万不要加空格!!!!!!
@Test
public void fun4() {
Session session = HibernateUitl.getOpenSession();
Transaction transaction = session.beginTransaction();
//冒号后面相当于是占位符的名字
//在替换时 直接使用冒号后面的名字即可
//冒号后面不要加空格
String hql = "from com.commander.User where username=:username and password=:password";
Query<User> query = session.createQuery(hql);
query.setParameter("username", "taylor");
query.setParameter("password", "456");
User user = query.uniqueResult();
System.out.println(user);
transaction.commit();
session.close();
}
4.分页查询
@Test
public void fun5() {
//使用HQL查询所有User记录
Session session = HibernateUitl.getOpenSession();
Transaction transaction = session.beginTransaction();
String hql = "from User ";
Query<User> query = session.createQuery(hql, User.class);
//添加分页
//limit first,max
query.setFirstResult(2);
query.setMaxResults(2);
List<User> list = query.list();
System.out.println(list);
transaction.commit();
session.close();
}
5.Criteria无语句查询
@Test
public void fun6() {
//使用HQL查询所有User记录
Session session = HibernateUitl.getOpenSession();
Transaction transaction = session.beginTransaction();
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.eq("id", 2));
User user = (User)criteria.uniqueResult();
System.out.println(user);
transaction.commit();
session.close();
}
二.多表间的实体类配置文件写法
1.一对多
for example:
@Test
public void fun1() {
Session session = HibernateUitl.getOpenSession();
Transaction transaction = session.beginTransaction();
//创建一个客户
Customer customer = new Customer();
customer.setCust_name("taylor");
//创建两个联系人
LinkMan linkMan1 = new LinkMan();
linkMan1.setLkm_name("swift");
LinkMan linkMan2 = new LinkMan();
linkMan2.setLkm_name("taylorSwift");
customer.getLinkMans().add(linkMan1);
customer.getLinkMans().add(linkMan2);
linkMan1.setCustomer(customer);
linkMan2.setCustomer(customer);
//保存到数据库 转成持久态
session.save(customer);
session.save(linkMan1);
session.save(linkMan2);
//将以上添加到数据库中
transaction.commit();
session.close();
}
一是客户 Customer
需要在实体类中加一个属性 来表示
注意:集合需要进行初始化
private Set<LinkMan> linkMans = new HashSet<>();
映射文件:
<!-- 配置一对多关系
name 表示实体类对象中的属性名
column 两张表联系的外键
class 与哪个类进行联系(一对多)
注意:两张表外键名必须一致 否则会多创建一个外键出来
-->
<!--
级联操作
作用:简化你的代码(量不大)
save-update 级联保存和更新
delete 级联删除
all save-update + delete
最好少用 最多用个save-update
-->
<!--
inverse(反转)
默认值是false 不放弃维护外键
true 放弃维护外键
作用: 提高效率
一对多的表关系 如果要放弃维护外键关系 只能是一的一方 放弃维护
-->
<set name="linkMans" cascade="save-update" inverse="true">
<key column="lkm_cust_id"></key>
<one-to-many class="LinkMan"/>
</set>
多是联系人 LinkMan
需要在实体类中加一个属性 来表示一对多的关系:
private Customer customer;
映射文件:
<!-- 配置多对一的关系
name 表示多对一对象的属性名
class 表示的是多对一对象的类
column 表示的是外键
注意:上面在配置property时 不要重复配置外键
-->
<many-to-one name="customer" class="Customer" column="lkm_cust_id"></many-to-one>
2.级联测试
hibernate在多对一操作时
默认是 两张表都会对外键进行维护
插入语句是 LinkMan在维护外键
更新语句是 Customer在维护外键
按照效率来说 Customer再一次维护外键多余
可以让Customer放弃维护外键
3.多对多
for example:
@Test
public void fun1() {
Session session = HibernateUitl.getOpenSession();
Transaction transaction = session.beginTransaction();
//创建两个员工
User user1 = new User();
User user2 = new User();
user1.setUser_name("taylor");
user2.setUser_name("swift");
//创建两个角色 保镖 保姆
Role role1 = new Role();
Role role2 = new Role();
role1.setRole_name("保姆");
role2.setRole_name("保镖");
//这两个员工 都既是保姆又是保镖
user1.getRoles().add(role1);
user1.getRoles().add(role2);
user2.getRoles().add(role1);
user2.getRoles().add(role2);
role1.getUsers().add(user1);
role1.getUsers().add(user2);
role2.getUsers().add(user1);
role2.getUsers().add(user2);
session.save(user1);
session.save(user2);
session.save(role1);
session.save(role2);
transaction.commit();
session.close();
}
User类的映射文件:
<!-- 配置多对多关系
name 容器的名字
table 中间表的名字
key column 中间引用我的id
many-to-many
column: 对应那个表的外键(引用的那个表的键)
class: 对应的那个表的类名
-->
<!--
多对多时必须注意 要有一方放弃对外键的维护
-->
<set name="roles" table="sys_user_role" inverse="true">
<key column="user_id"></key>
<many-to-many column="role_id" class="Role"></many-to-many>
</set>
Role类的映射文件:
<!-- 配置多对多关系 -->
<set name="users" table="sys_user_role">
<key column="role_id"></key>
<many-to-many class="User" column="user_id"></many-to-many>
</set>