• Hibernate使用原生SQL语句进行无关联多表查询


    背景:有两个表:CpCg与CpGg需要进行多表查询

    因为CpGg表设计到与另外的表也有联系,因此师兄没有关联此两个表,只是用字段进行逻辑关联,CpGg表的cp字段与CpCg表的id字段逻辑关联

    首先确保hibernate配置文件配置完成,配置文件如下:(一些与本人项目相关的关键字段已隐去)

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
        <session-factory>
        <!-- 指定连接数据库所用的驱动 -->
            <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
            <!-- 指定连接数据库的url,其中hibernate是本应用连接的数据库名 -->
            <property name="connection.url">jdbc:mysql://localhost/efoer</property>
            <!-- 指定连接数据库的用户名 -->
            <property name="connection.username">root</property>
            <!-- 指定连接数据库的密码 -->
            <property name="connection.password">123</property>
            <!-- 指定连接池里最大连接数 -->
            <property name="hibernate.c3p0.max_size">20</property>
            <!-- 指定连接池里最小连接数 -->
            <property name="hibernate.c3p0.min_size">1</property>
            <!-- 指定连接池里连接的超时时长 -->
            <property name="hibernate.c3p0.timeout">5000</property>
            <!-- 指定连接池里最大缓存多少个Statement对象 -->
            <property name="hibernate.c3p0.max_statements">100</property>
            <property name="hibernate.c3p0.idle_test_period">3000</property>
            <property name="hibernate.c3p0.acquire_increment">2</property>
            <property name="hibernate.c3p0.validate">true</property>
            <!-- 指定数据库方言 -->
            <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
            <!-- 根据需要自动创建数据库 -->
            <property name="hbm2ddl.auto">update</property>
            <!-- 显示Hibernate持久化操作所生成的SQL -->
            <property name="show_sql">true</property>
            <!-- 将SQL脚本进行格式化后再输出 -->
            <property name="hibernate.format_sql">true</property>
            <!-- 罗列所有持久化类的类名 -->
            <mapping class="com.efoer.model.CgLb"/>
                    
                    <!--这里是我所有的数据实体名,不一一罗列了-->
        
            
        </session-factory>
    </hibernate-configuration>

    配置完成后,新建一个包,命名为Util,在此包下创建一个类:HibernateUtil.java。此类代码如下:

    package util;
    
    import org.hibernate.*;
    import org.hibernate.cfg.*;
    import org.hibernate.service.*;
    import org.hibernate.boot.registry.*;
    
    public class HibernateUtil
    {
        public static final SessionFactory sessionFactory;
    
        static
        {
            try
            {
                
                Configuration cfg = new Configuration()
                    .configure();
                
                ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                    .applySettings(cfg.getProperties()).build();
                sessionFactory = cfg.buildSessionFactory(serviceRegistry);
            }
            catch (Throwable ex)
            {
                System.err.println("Initial SessionFactory creation failed." + ex);
                throw new ExceptionInInitializerError(ex);
            }
        }
    
    
        public static final ThreadLocal<Session> session
            = new ThreadLocal<Session>();
    
        public static Session currentSession()
            throws HibernateException
        {
            Session s = session.get();
        
            if (s == null)
            {
                s = sessionFactory.openSession();
                
                session.set(s);
            }
            return s;
        }
    
        public static void closeSession()
            throws HibernateException
        {
            Session s = session.get();
            if (s != null)
                s.close();
            session.set(null);
        }
    }

    完成以上工作以后开始在对应的controller里面写sql语句

        @RequestMapping(value="/page",method=RequestMethod.GET)
        public String getRole( Model model){
            
            //打开Session和事务
            Session session=util.HibernateUtil.currentSession();
            Transaction tx=session.beginTransaction();
            String sqlString="select s.id,s.pp,s.cd,s.mc,s.lb,s.sj,s.zt,s.jc,e.id,e.cp,e.gg,e.hh,e.tm,e.cz,e.bz,e.dpcc,e.bzcc,e.sl,e.sj,e.cj,e.zt "
                    +"from cp_cg s, cp_gg e "
                    +"where s.id=e.cp "
                    +"and s.zt=2";
            List list=session.createSQLQuery(sqlString)
                    //指定将从S表查询得到的记录行转为CpCg实体
                    .addEntity("s",CpCg.class)
                    //指定将从e表查询得到的记录行转为CpGg实体
                    .addEntity("e", CpGg.class)
                    .list();
            //提交事务,关闭Session
            tx.commit();
            util.HibernateUtil.closeSession();
            //因为数据已经全部被选出,故程序可以遍历列表中的数据
            
    //在控制台输出字段,为了方便自己查看查询结果
            for(Object ele:list){
                Object[] objs = (Object[])ele;
                CpCg s=(CpCg)objs[0];
                CpGg e=(CpGg)objs[1];
                System.out.println(s.getCd()+s.getMc()+s.getPp()+"	"
                        +e.getHh()+e.getTm()+e.getSl());
                model.addAttribute("cd", s.getCd());
         
            }
            //为了把数据传给前台
            model.addAttribute("list", list);
            return "/page/pm/index";
        }

    个人理解:这里关联的两个表查询的,并且查询完成后将记录行转为了两个对应的实体,因此查询出来的list里的每条记录相当于由两个实体对象拼凑而成,list[0]存放的CpCg,list[1]存放的CpGg

    所以在前台取值出来的时候list[0]取出的是CpCg对象,list[1]取出的是CpGg对象。代码如下:

    <c:forEach items="${list}" var="list">
           <ul>
                   <li class="cpjl-1-head-1"><span>${list[0].id}</span></li>
                   <li class="cpjl-1-head-2"><span>${list[0].pp}</span></li>
                   <li class="cpjl-1-head-3"><span>${list[0].cd}</span></li>
                   <li class="cpjl-1-head-4"><span>${list[0].mc}</span></li>
                   <li class="cpjl-1-head-5"><span>${list[0].jc}</span></li>
                   <li class="cpjl-1-head-6"><span>${list[1].gg}</span></li>
                   <li class="cpjl-1-head-7"><span>${list[1].hh}</span></li>
                   <li class="cpjl-1-head-8"><span>${list[1].tm}</span></li>
                    <li class="cpjl-1-head-9"><span>${list[1].cz}</span></li>
                </ul>
    </c:forEach>

    但为什么查询出来的list的数据是这么存放的,个人还没想明白。希望有明白的小伙伴看到后一解本人困惑,不胜感激

  • 相关阅读:
    属性与字段的区别
    修改LVDS支持1024*600分辨率
    Altium designer 10如何设置标题栏
    嵌入式C开发人员的最好的0x10道笔试题
    进程线程及堆栈关系的总结
    GDB调试
    c语言
    如何使用autotools生成Makefile
    ubuntu NFS
    Ubuntu安装配置TFTP服务
  • 原文地址:https://www.cnblogs.com/whutwxj/p/5777149.html
Copyright © 2020-2023  润新知