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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM