hibernate5版本测试
1 Session接口
几个常用的方法
-
save , persist 保存数据 persist在事务外不会产生insert语句(不会进行提交)
而save就算不处理事务也能提交 (hibernate5是这样的,在session关闭后会提交) -
delete 删除对象
-
update 更新对象
-
get 查询对象(根据ID),会立即访问数据库
-
load 查询对象(根据ID), 返回的是代理对象,不会立即访问数据库,懒加载
-
saveOrUpdate 保存或更新(在目前的测试中对象没有id就是保存,有id就是修改), merge (调用merge以后,对象是脱管的)
-
lock 把对象变成持久对象,但不会同步对象的状态
//例子 get 和load的不同之处
public static void main(String[] args) {
AdminInfo admin =getAdmin(1);
System.out.println(admin); // could not initialize proxy [com.beans.AdminInfo#1] - no Session
}
public static AdminInfo getAdmin(int id) {
try {
Session s=HibUtil.getSession();
AdminInfo admin=s.load(AdminInfo.class, id);
// Hibernate.initialize(admin); //让它去把代理对象对应的数据查出来Hibernate.initialize(admin); //让它去把代理对象对应的数据查出来
return admin;
}finally {
HibUtil.closeSession();
}
}
load方法,返回的是代理对象(并不是直的立即去查询数据库),如果在session之外再用到这个查询出来的对象,由于
没有了session,这个代理对象不能再进行数据库连接查询,所以出错
2 对象状态
–瞬时 (transien): 数据库中没有数据与之对应,超过作用域就会失效,就会被垃圾回收器回收,
通常,刚new出来的对象,处于这样的状态, 与Session无关
–持久 (persistent): 数据库中有数据与之对应,与session相关联,而且session没有关闭,事务没有提交
持久态的对象,如果内容发生改变,在事务提交后,会反映到数据库端
–脱管 (detached): 数据库有数据与之对应,但没有session与之相关,脱管对象的改变,不会影响到数据库
static void save() {
AdminInfo admin=new AdminInfo();
admin.setAdminName("rootabc");
admin.setPassword("123"); //这时对象处理 瞬时 态
Session s =HibUtil.getSession();
Transaction tx=s.beginTransaction();
s.persist(admin); //对象处理 持久 态
admin.setAdminName("李婧");
admin.setNote("这是备注");
tx.commit();
HibUtil.closeSession();
admin.setAdminName("lastname"); //对象处理脱管 态
}
最后的结果是: 李婧 123 这是备注
3,HQL语句查询
在5版本以后 用query.Query这个包 这个query带泛型
public AdminInfo login(String adminName,String passsword) {
try {
Session s=HibUtil.getSession();
String hql="from AdminInfo where adminName=?1 and password =?2 ";
Query <AdminInfo>q =s.createQuery(hql,AdminInfo.class);
q.setParameter(1, adminName);
q.setParameter(2, passsword);
AdminInfo admin=q.uniqueResult();
return admin;
} finally {
HibUtil.closeSession();
}
}
hql:
- //select * 不用写
- //from后面跟的是类名不能是表名
- //后面的字段也是类中的属性名,不是表中字段名
- //adminName=?1 and password =?2 "; ? 后面要加上1, 2 这个标志 (JAP规范)
- //q.setParameter(1, adminName); //前面的1 或2 等要和上面的标志对上
- //q.setParameter(2, passsword);实测发现,如果上面写成 0, 1 下面也可以按 0, 1 去查询
- uniqueResult 这个方法,当查不到数据的时候,得到的null 如果查出来的数据,多于一条,则出异常 query did not return a unique result: 2
- AdminInfo admin =q.getSingleResult(); 也可以用这个方法查询,当结果多于一条的时候,和上面的错误相同 ,如果没有查询到结果的时候 ,将出错 No entity found for query
- 对于hql 也可以用别名的方式传参
String hql="from AdminInfo where adminName=:aname and password =:pwd "; //select * 不用写 from后面跟的是类名不能是表名
Query <AdminInfo>q =s.createQuery(hql,AdminInfo.class);
q.setParameter("aname", adminName);
q.setParameter("pwd", passsword);
可以使用 setFirstResult 和 setMaxResults 进行结果集过滤,实现分页功能
public List<AdminInfo> getAdminList(int beginRow,int pageSize){
try {
Session s=HibUtil.getSession();
String hql="from AdminInfo";
Query <AdminInfo>q =s.createQuery(hql,AdminInfo.class);
q.setFirstResult(beginRow);
q.setMaxResults(pageSize);
// return q.list();
return q.getResultList();
} finally {
HibUtil.closeSession();
}
}
public static void main(String[] args) {
AdminDao dao=new AdminDao();
List<AdminInfo > adminList=dao.getAdminList(2,3);
for(AdminInfo a: adminList) {
System.out.println(a);
}
}
//查询数据条数
public int getAdminCount() {
try {
Session s=HibUtil.getSession();
Query <Long>q=s.createQuery("select count(*) from AdminInfo",Long.class); //后对是对象名
return new Integer(q.uniqueResult()+"");
} finally {
HibUtil.closeSession();
}
}
//删除
public void deleteByName() {
try {
Session s=HibUtil.getSession();
Query <?>q=s.createQuery("delete from AdminInfo where adminName=?0");
q.setParameter(0, "hibernate用户一");
Transaction tx=s.beginTransaction();
q.executeUpdate();
tx.commit();
} finally {
HibUtil.closeSession();
}
}
其他的一些query写法
// 使where
Query q=s.createQuery("from AdminInfo where id not between 10 and 20");
//查询id不在10 到20之间的
// 使用in
Query q=s.createQuery("from AdminInfo where AdminName in('张三','李四','王五')");
//只要在这个('张三','李四','王五')集合中含有的,就查出来
// 使用 like
Query q=s.createQuery("from AdminInfo where AdminName like %赵%");
// 查询名字中含有赵的所有用户
// 使用 null
Query q=s.createQuery("from AdminInfo where note is null");
//查询所有备注为null的用户
// 使用 and
Query q=s.createQuery("from AdminInfo where note is null and id<5");
//查询备注信息是null而且id<5的用户
// 执行删除
Query q=s.createQuery("from AdminInfo where password is null");
3 Criteria接口
1 Criteria接口
public AdminInfo getLoginAdmin(String name,String password) {
try {
Session s=HibUtil.getSession();
Criteria c=s.createCriteria(AdminInfo.class);
c.add(Restrictions.eq("adminName", name));
c.add(Restrictions.eq("password", password));
return (AdminInfo) c.uniqueResult();
} finally {
HibUtil.closeSession();
}
}
public static void main(String[] args) {
AdminDao dao=new AdminDao();
AdminInfo admin=dao.getLoginAdmin("admin" , "123");
System.out.println(admin);
在hibernate5中 s.createCriteria 这样的方式不推荐使用了
推荐我们用 JPA CriteriaQuery
//查询所有,相当于select * from adminInfo
public static void test01() {
try {
Session s=HibUtil.getSession();
CriteriaBuilder builder= s.getCriteriaBuilder();
//获取 CriteriaQuery对象
CriteriaQuery <AdminInfo>createQuery= builder.createQuery(AdminInfo.class);
//指定根条件
createQuery.from(AdminInfo.class);
//执行查询
List<AdminInfo> adminList=s.createQuery(createQuery).list();
for(AdminInfo a:adminList ) {
System.out.println(a);
}
} finally {
HibUtil.closeSession();
}
}
//多条件查询 select * from adminInfo where adminName=xxxx and id >1
public static void test02() {
try {
Session s=HibUtil.getSession();
CriteriaBuilder builder= s.getCriteriaBuilder();
//获取 CriteriaQuery对象
CriteriaQuery <AdminInfo>createQuery= builder.createQuery(AdminInfo.class);
//指定根条件
Root<AdminInfo> root =createQuery.from(AdminInfo.class);
//创建两个查询条件
Predicate p1= builder.equal(root.get("adminName"),"admin");
Predicate p2 =builder.gt(root.get("id"),1);
//将查询条件放到where方法中
createQuery.where(p1,p2 );
//执行查询
List<AdminInfo> adminList=s.createQuery(createQuery).list();
for(AdminInfo a:adminList ) {
System.out.println(a);
}
} finally {
HibUtil.closeSession();
}
}
// 这个是带or 条件的 select * from t where (adminName=admin and id>1) or (note=垃圾)
public static void test03() {
try {
Session s=HibUtil.getSession();
CriteriaBuilder builder= s.getCriteriaBuilder();
//获取 CriteriaQuery对象
CriteriaQuery <AdminInfo>createQuery= builder.createQuery(AdminInfo.class);
//指定根条件
Root<AdminInfo> root =createQuery.from(AdminInfo.class);
//创建两个查询条件
Predicate p1 =builder.equal(root.get("adminName"),"admin");
Predicate p2 =builder.gt(root.get("id"),1);
Predicate p3 =builder.equal(root.get("adminName"), "垃圾");
//将查询条件放到where方法中
createQuery.where( builder.or ( builder.and(p1,p2) , p3) );
//执行查询
List<AdminInfo> adminList=s.createQuery(createQuery).list();
for(AdminInfo a:adminList ) {
System.out.println(a);
}
} finally {
HibUtil.closeSession();
}
}
//查询所有雇员,按id降序排序,名字升序排序
public static void test04() {
Session s=HibUtil.getSession();
CriteriaBuilder builder = s.getCriteriaBuilder();
//1. 获取CriteriaQuery对象
CriteriaQuery<AdminInfo> criteria = criteriaBuilder.createQuery(AdminInfo.class);
//2. 指定根条件
Root<AdminInfo> root = criteria.from(AdminInfo.class);
//3. 设置orderBy的字段,可同时对多个字段进行排序
criteria.orderBy(builder.desc(root.get("id")), builder.asc(root.get("adminName")));
//4. 执行查询并返回结果
List<AdminInfo> list = s.createQuery(criteria).list();
for (AdminInfo a : list) {
System.out.println(a);
}
....
}
//查询所有带分页的
public static void test05() {
Session s=HibUtil.getSession();
CriteriaBuilder builder = s.getCriteriaBuilder();
//1. 获取CriteriaQuery对象
CriteriaQuery<AdminInfo> criteria = builder.createQuery(AdminInfo.class);
//2. 指定根条件
Root<AdminInfo> root = criteria.from(AdminInfo.class);
//3. 设置orderBy的字段
criteria.orderBy(builder.desc(root.get("id")));
List<AdminInfo> list = s.createQuery(criteria).setFirstResult(0).setMaxResults(5).list();
for (AdminInfo a : list) {
System.out.println(a);
}
...
}
4 使用sql进行查询
//例一
static List<AdminInfo> getAdminList(){
try {
Session s=HibUtil.getSession();
String sql="select * from adminInfo"; //注意,它就是以前我们用的sql语句,后面的 adminInfo 是表名
/* 这是过去的写法,废弃了
SQLQuery<AdminInfo> q=s.createSQLQuery(sql).addEntity(AdminInfo.class);
q.list();
*/
NativeQuery<AdminInfo> q= s.createNativeQuery(sql,AdminInfo.class);
return q.list();
} finally {
HibUtil.closeSession();
}
}
//例二
static List<AdminInfo> getAdminList2(){
try {
Session s=HibUtil.getSession();
String sql="select * from adminInfo where adminName=? and password=?" ;
//这里可以用命名参数
NativeQuery<AdminInfo> q= s.createNativeQuery(sql,AdminInfo.class);
q.setParameter(1, "admin");
q.setParameter(2, "123");
q.setFirstResult(0);
q.setMaxResults(5);
return q.getResultList();
} finally {
HibUtil.closeSession();
}
}
//例三 关联查询
public static void main(String[] args) {
List<Object[]> obljectList= getNiguList3();
for(Object [] row:obljectList) {
for(Object filedValue:row) {
System.out.print(filedValue +" ");
}
System.out.println();
}
}
static List<Object[]> getNiguList3() {
try {
Session s=HibUtil.getSession();
String sql="select a.id,a.fahao , b.name from nigu a left join niguan b on a.niguan_id=b.id";
NativeQuery q=s.createSQLQuery(sql);
return q.list();
} finally {
HibUtil.closeSession();
}
}
//例四 使用Dto进行数据传输
public static void main(String[] args) {
List<NiguDto> niguList= getNiguList4();
for(NiguDto n:niguList) {
System.out.println(n.getId() + " " + n.getFahao()+ " " + n.getName() );
}
}
//使用Dto进行数据传输
static List<NiguDto> getNiguList4(){
try {
Session s=HibUtil.getSession();
String sql="select a.id,a.fahao , b.name from nigu a left join niguan b on a.niguan_id=b.id";
Query q=s.createSQLQuery(sql);
q.setResultTransformer(Transformers.aliasToBean(NiguDto.class));
//进行数据传输对象的处理
return q.list();
} finally {
HibUtil.closeSession();
}
}
public class NiguDto extends Nigu{
private String name; //关联到的其他的表中的数据
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
上面的设计还是比较符合正常人类的思维的,而且NiguDto 不需要配置映射文件
但TMD败家的hibernate5 ,居然把上面的一些API给废弃了
//例五 使用 session 的 doWork 的方式
static void test() {
Work work = new Work() {
public void execute(Connection connection) throws SQLException {
PreparedStatement stm = connection.prepareStatement("select * from AdminInfo");
ResultSet rs = stm.executeQuery();
while (rs.next()) {
System.out.print(rs.getInt("id") + " ");
System.out.print(rs.getString("adminName") + " ");
System.out.println(rs.getString("password"));
}
}
};
try {
Session s = HibUtil.getSession();
s.doWork(work);
} finally {
HibUtil.closeSession();
}
}
//例 使用 doWork 的方式,有返回值的处理
public static void main(String[] args) {
List<AdminInfo> list =getAdminlist5();
for(AdminInfo a :list) {
System.out.println(a);
}
}
static List<AdminInfo> getAdminlist5(){
List<AdminInfo> adminList=new ArrayList<AdminInfo>();
Work work = new Work() {
public void execute(Connection connection) throws SQLException {
PreparedStatement stm = connection.prepareStatement("select * from AdminInfo");
ResultSet rs = stm.executeQuery();
while (rs.next()) {
AdminInfo admin=new AdminInfo();
admin.setId(rs.getInt("id"));
admin.setAdminName(rs.getString("adminName"));
admin.setPassword(admin.getPassword());
admin.setNote(rs.getString("note"));
adminList.add(admin);
}
}
};
try {
Session s = HibUtil.getSession();
s.doWork(work);
} finally {
HibUtil.closeSession();
}
return adminList;
}
附:多条件查询
public static void main(String[] args) {
List<AdminInfo> list =getAdminList6("admin",null);
for(AdminInfo a :list) {
System.out.println(a);
}
}
static List<AdminInfo> getAdminList6(String adminName,String password) {
try {
Session s = HibUtil.getSession();
String hql="from AdminInfo where 1=1 ";
if(adminName!=null) {
hql+=" and adminName='"+adminName+"'" ;
}
if(password!=null) {
hql+=" and password='"+password+"'" ;
}
Query<AdminInfo> q =s.createQuery(hql,AdminInfo.class);
return q.getResultList();
} finally {
HibUtil.closeSession();
}
}
标题 5 DetacheCriteria
//控制层
public class AdminController {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
System.out.println("输入账号");
String adminName=scan.next();
System.out.println("输入备注");
String note=scan.next();
DetachedCriteria dc=DetachedCriteria.forClass(AdminInfo.class);
if(adminName!=null && !"".equals(adminName)) {
dc.add(Restrictions.eq("adminName",adminName));
}
if(note!=null && !"".equals(note) ) {
dc.add(Restrictions.eq("note",note));
}
List<AdminInfo> adminList=new AdminDao().searchAdmin(dc);
for(AdminInfo a: adminList) {
System.out.println(a);
}
}
}
/**
* @param dc 离线的Criteria(离线指的就是它不和session 相关)
* @return
*/
public List<AdminInfo> searchAdmin(DetachedCriteria dc) {
try {
Session s=HibUtil.getSession();
Criteria c=dc.getExecutableCriteria(s);
return c.list();
}finally {
HibUtil.closeSession();
}
}