异常描述如下;
1、在user.hbm.xml中配置如下<sql-query>
<!-- 如果sql-query放置在class里面,在引用时需加上包名和类名,即:com.summer.entity.User.mySQLquery -->
<sql-query name="mySQLquery">
<![CDATA[ select * from simpro_user]]>
</sql-query>
2、测试代码如下:
public static void getByNamedQuery(String queryName){
//queryName = "com.summer.entity.User.mySQLquery";
Session session = HibernateUtil.getSession();
Query q = session.getNamedQuery(queryName);
List<User> users = q.list();
System.out.println("=========start:NamedQuery===================");
for (Object user : users) {
System.out.println((User)user);
}
System.out.println("=========end:NamedQuery===================");
}
3、异常信息如下:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.summer.entity.User
4、解决方法如下:以下内容为hibernate命名查询学习总结:
一、什么是命名查询?
Hibernate允许在映射文件(xxx.hbm.xml,可以是实体类的映射文件,如User.hbm.xml,也可以是自定义的映射文件,如:namedSQL.hbm.xml)中定义字符串形式的查询语句,这种查询方式成为命名查询。然后在hibernate.cfg.xml中引入命名查询文件;
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration
PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@192.168.1.1:1521:ORCL</property>
<property name="connection.password">root</property>
<property name="connection.username">root</property>
<property name="dialect">org.hibernate.dialect.OracleDialect</property>
<property name="show_sql">true</property>
<!-- <property name="hbm2ddl.auto">update</property> -->
<!-- 二级缓存的配置 -->
<property name="cache.use_second_level_cache">true</property>
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<!--启动查询缓存:默认是关闭的。如:默认使用Query\Criteria查询不使用缓存的-->
<property name="cache.use_query_cache">true</property>
<!-- 输出统计信息 -->
<property name="generate_statistics">true</property>
<mapping resource="User.hbm.xml"/>
<!--配置映射的二级缓存-->
<class-cache usage="read-write" class="com.summer.entity.User"/>
</session-factory>
</hibernate-configuration>
二、使用命名查询有什么好处?
由于使用Hibernate的HQL常常需要在Java代码中写字符串查询语句,HQL混杂在代码之间,破坏代码可读性,通过使用命名查询,可以使业务逻辑和查询语句分离,使您专注于查询,而避免了 SQL 或者 HQL 代码分散于整个应用程序中的情况。
可以应用命名查询做复杂查询的处理
介绍下面几种方式:
方法一:在配置文件中<class/>标记的下面,声明查询语句
方法二:也可以在配置文件中<class/>标记的里面,声明查询语句, 但是java代码调用时需要指定(包+类+配置名)
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.summer.entity"
auto-import="true">
<class name="User" table="SIMPRO_USER">
<id name="id" column="USER_ID" type="java.lang.String">
<generator class="uuid.hex"></generator>
</id>
<property name="loginId" column="LOGIN_ID" type="java.lang.String" />
<property name="orgId" column="ORG_ID" type="java.lang.String" />
<property name="userName" column="USER_NAME" type="java.lang.String" />
<property name="password" column="PASSWORD" type="java.lang.String" />
<property name="email" column="EMAIL" type="java.lang.String" />
<property name="phoneNum" column="PHONE_NUM" type="java.lang.String" />
<property name="status" column="STATUS" type="java.lang.String" />
<!-- 方式一:如果sql-query放置在class里面,在引用时需加上包名和类名,即:com.summer.entity.User.mySQLquery -->
<query name="mySQLquery">
<![CDATA[ from User]]>
</query>
</class>
<!-- 方式二:若sql-query放置在class外面,则可以程序中直接引用,即:myNamedSQLquery -->
<query name="myNamedSQLquery">
<![CDATA[ from User]]>
</query>
</hibernate-mapping>
测试代码如下:
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import com.summer.entity.User;
import com.summer.util.HibernateUtil;
public class TestHibernate {
public static void main(String[] args) {
//命名查询:
getByNamedQuery("com.summer.entity.User.mySQLquery");
getByNamedQuery("myNamedSQLquery");
//原生SQL查询
getBySql("select * from simpro_user");
}
public static void getByNamedQuery(String queryName){
//queryName = "com.summer.entity.User.mySQLquery";
Session session = HibernateUtil.getSession();
Query q = session.getNamedQuery(queryName);
List<User> users = q.list();
System.out.println("=========start:NamedQuery===================");
for (Object user : users) {
System.out.println((User)user);
}
System.out.println("=========end:NamedQuery===================");
}
public static void getBySql(String sql){
Session session = HibernateUtil.getSession();
SQLQuery query = session.createSQLQuery(sql).addEntity(User.class);
List<User> users = query.list();
System.out.println("=========start:sqlQuery===================");
for (User user : users) {
System.out.println(user);
}
System.out.println("=========end:sqlQuery===================");
}
}
方法三:使用原生sql查询<sql-query>,使用此种方式必须把表所有的列写全才可以,否则会出现‘列名无效'的错误
,除非你使用return-scalar来设置字段类型。
<hibernate-mapping>
<class name="com.test.bean.Student" table="student" catalog="users">
<id name="id" type="integer">
<column name="id" />
<generator class="identity" />
</id>
<property name="name" type="string">
<column name="name" length="11" />
</property>
<property name="age" type="integer">
<column name="age" />
</property>
<property name="sex" type="string">
<column name="sex" length="2" />
</property>
</class>
<!-- 定义查询语句 -->
<sql-query name="findStudentByName">
<return alias="s" class="com.test.bean.Student">
</return>
<![CDATA[select {s.*} from student s where s.name = :name]]>
</sql-query>
</hibernate-mapping>
方法四:使用原生sql查询<sql-query>, 如果应用return-scalar来设置字段类型, 就可以实现查询部分字段。<hibernate-mapping>
<class name="com.test.bean.Student" table="student" catalog="users">
<id name="id" type="integer">
<column name="id" />
<generator class="identity" />
</id>
<property name="name" type="string">
<column name="name" length="11" />
</property>
<property name="age" type="integer">
<column name="age" />
</property>
<property name="sex" type="string">
<column name="sex" length="2" />
</property>
</class>
<!-- 定义查询语句 -->
<sql-query name="findStudentByName">
<return-scalar column="name" type="string"/>
<return-scalar column="age" type="integer"/>
<![CDATA[select s.name , s.age from student s where s.name = :name]]>
</sql-query>
</hibernate-mapping>
public List<Object[]> query(){
Session session = HibernateSessionFactory.getSession();
Query query = session.getNamedQuery("findStudentByName");
query.setString("name", "zhangsan");
List<Object[]> list = query.list();
return list;
}