• hibernate之SQL查询


    一、SQL查询简介

    使用SQL查询可以利用某些数据库的特性,或者将原有的JDBC应用迁移到hibernate应用上,也可能需要使用原生的SQL查询。查询步骤如下:

    1、获取hibernate session对象

    2、编写SQL语句

    3、以SQL语句作为参数,调用Session的createSQLQuery()方法创建查询对象

    4、调用SQLQuery对象的addScalar()huoaddEntity()方法将选出的结果与标量值或实体进行关联,分别用于进行标量查询或实体查询

    5、如果SQL语句有参数,则调用Query的setXxx()方法为参数赋值

    6、调用Query的list()方法或uniqueResult()方法返回查询的结果集

    二、SQL查询

    1、标量查询

    标量查询会获得数据表列对应的Object数组组成的List,hibernate会默认通过ResultSetMetadata来判定所返回数据列的实际顺序和类型,但这样的默认处理会降低程序性能,因此在代码书写时建议明确返回值类型

            String sql = "select * from sql_student";
                SQLQuery q = session.createSQLQuery(sql)
                        .addScalar("id", StandardBasicTypes.LONG)//明确返回值类型,属性名称必须和表中列名相同
                        .addScalar("sname", StandardBasicTypes.STRING)
                        .addScalar("teacher_id", StandardBasicTypes.LONG);
                List list = q.list();
                for(Object ob : list) {
                    Object[] ob1 = (Object[]) ob;
                    System.out.println(ob1[0] + " | " + ob1[1] + " | " + ob1[2]);
                }

    多表查询

    String sql = "select t.tid, t.tname,s.sid,s.sname from sql_teacher t, sql_student s WHERE t.tid = s.teacher_id";
                SQLQuery q = session.createSQLQuery(sql)
                        .addScalar("t.tid", StandardBasicTypes.LONG)//明确返回值类型,属性名称必须和表中列名相同
                        .addScalar("t.tname", StandardBasicTypes.STRING)
                        .addScalar("s.sid", StandardBasicTypes.LONG)
                        .addScalar("s.sname", StandardBasicTypes.STRING);
                List list = q.list();
                for(Object ob : list) {
                    Object[] ob1 = (Object[]) ob;
                    System.out.println(ob1[0] + " " + ob1[1] + " | " + ob1[2] + " " + ob1[3]);
                }

    2、实体查询

    如果查询返回了某个数据表的全部数据列,且该数据表有对应的持久化类映射,就可用实体查询将查询结果转换成实体

            String sql = "select * from sql_student";
                SQLQuery q = session.createSQLQuery(sql)
                        .addEntity(SQLStudent.class);//程序必须选出所有数据列才可被转换成持久化实体
                List<SQLStudent> list = q.list();
                for(SQLStudent s : list) {
                    System.out.println(s.getId() + " | " + s.getSname()+ " | " + s.getSqlTeacher().getName());
                }

    多表查询(使用这种查询,如果两张表中有相同字段,则得到这两字段值均为顺序在前的字段的值,解决办法是将表中名称相同字段名称做区别)

            String sql = "SELECT s.*,t.*  FROM sql_teacher t,sql_student s WHERE s.teacher_id = t.tid";
                SQLQuery sqlQuery = session.createSQLQuery(sql)
                        .addEntity("t", SQLTeacher.class)
                        .addEntity("s", SQLStudent.class);
                List list = sqlQuery.list();
                for (Object obj : list) {
                    Object[] objects = (Object[]) obj;
                    SQLTeacher sqlTeacher = (SQLTeacher) objects[0];
                    SQLStudent sqlStudent = (SQLStudent) objects[1];
                    System.out.println(sqlTeacher.getId() + " " + sqlTeacher.getTname() + " | " + sqlStudent.getId() + " " + sqlStudent.getSname());
                }

    3、关联查询

            String sql = "SELECT t.*,s.* FROM sql_teacher t LEFT JOIN sql_student s ON t.tid = s.teacher_id";
                SQLQuery sqlQuery = session.createSQLQuery(sql)
                        .addEntity("t", SQLTeacher.class)
                        .addEntity("s", SQLStudent.class);
                List list = sqlQuery.list();
                for (Object obj : list) {
                    Object[] objects = (Object[]) obj;
                    SQLTeacher sqlTeacher = (SQLTeacher) objects[0];
                    SQLStudent sqlStudent = (SQLStudent) objects[1];
                    System.out.println(sqlTeacher.getId() + " " + sqlTeacher.getTname() + " | " + sqlStudent.getId() + " " + sqlStudent.getSname());
                }

    注意:两个表中字段名称不能重复,否则得到结果的相同名称字段的值会出现混淆(只取顺序排在前面的字段值)

    测试实体类

    @Entity
    @Table(name = "sql_teacher")
    public class SQLTeacher {
        @Id
        @GeneratedValue
        @Column(name = "tid")
        private Long id;
        @Column(name = "tname")
        private String tname;
        @OneToMany(targetEntity = SQLStudent.class, mappedBy = "sqlTeacher")
        private Set<SQLStudent> sqlStudents = new HashSet<SQLStudent>();
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getTname() {
            return tname;
        }
    
        public void setTname(String tname) {
            this.tname = tname;
        }
    
        public Set<SQLStudent> getSqlStudents() {
            return sqlStudents;
        }
    
        public void setSqlStudents(Set<SQLStudent> sqlStudents) {
            this.sqlStudents = sqlStudents;
        }
    }
    @Entity
    @Table(name = "sql_student")
    public class SQLStudent {
        @Id
        @GeneratedValue
        @Column(name = "sid")
        private Long id;
        @Column(name = "sname")
        private String sname;
        @ManyToOne(targetEntity = SQLTeacher.class)
        @JoinColumn(name = "teacher_id", referencedColumnName = "tid", nullable = false)
        private SQLTeacher sqlTeacher;
        //@Column(name = "teacher_id")
        //private Long teacherId;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getSname() {
            return sname;
        }
    
        public void setSname(String sname) {
            this.sname = sname;
        }
    
        public SQLTeacher getSqlTeacher() {
            return sqlTeacher;
        }
    
        public void setSqlTeacher(SQLTeacher sqlTeacher) {
            this.sqlTeacher = sqlTeacher;
        }
    
        /*public Long getTeacherId() {
            return teacherId;
        }
    
        public void setTeacherId(Long teacherId) {
            this.teacherId = teacherId;
        }*/
    }

    测试类

    public class SQLController {
        public static void main(String[] args) {
            Configuration cf = new Configuration().configure();
            SessionFactory sf = cf.buildSessionFactory();
            Session session = sf.openSession();
            Transaction ts = session.beginTransaction();
            try {
                SQLTeacher t = new SQLTeacher();
                t.setTname("teacher 3");
                Serializable id = session.save(t);
                t = (SQLTeacher) session.get(SQLTeacher.class, id);
    
                SQLStudent s1 = new SQLStudent();
                s1.setSname("student 1");
                s1.setSqlTeacher(t);
    
                SQLStudent s2 = new SQLStudent();
                s2.setSname("student 2");
                s2.setSqlTeacher(t);
    
                SQLStudent s3 = new SQLStudent();
                s3.setSname("student 3");
                s3.setSqlTeacher(t);
    
                session.save(s1);
                session.save(s2);
                session.save(s3);
                ts.commit();
            } finally {
                session.close();
                sf.close();
            }
        }
    }

     代码下载:https://github.com/shaoyesun/hibernate_study.git

  • 相关阅读:
    获取非行间样式
    获取非行间样式
    prompt 方法显示输入对话框
    comfirm 方法显示对话框
    移动端页面常见问题及解决方案
    原生js怎样获取后台端口数据
    canvas描绘渐变的矩形
    cookie 的增加,销毁,读取
    canvas 绘制图形
    数组的排序,去重复
  • 原文地址:https://www.cnblogs.com/sunjf/p/hibernate_SQL.html
Copyright © 2020-2023  润新知