编程(Java-Hibernate)
Mar 4

在项目中使用sqlite数据库和hibernate进行配置时报错如下:
org.hibernate.MappingException: No Dialect mapping for JDBC type: 0
解决方法如下:
import java.sql.Types;

import org.hibernate.Hibernate;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;

public class SQLiteDialect extends Dialect {
public SQLiteDialect() {
super();
registerColumnType(Types.BIT, "integer");
registerColumnType(Types.TINYINT, "tinyint");
registerColumnType(Types.SMALLINT, "smallint");
registerColumnType(Types.INTEGER, "integer");
registerColumnType(Types.BIGINT, "bigint");
registerColumnType(Types.FLOAT, "float");
registerColumnType(Types.REAL, "real");
registerColumnType(Types.DOUBLE, "double");
registerColumnType(Types.NUMERIC, "numeric");
registerColumnType(Types.DECIMAL, "decimal");
registerColumnType(Types.CHAR, "char");
registerColumnType(Types.VARCHAR, "varchar");
registerColumnType(Types.LONGVARCHAR, "longvarchar");
registerColumnType(Types.DATE, "date");
registerColumnType(Types.TIME, "time");
registerColumnType(Types.TIMESTAMP, "timestamp");
registerColumnType(Types.BINARY, "blob");
registerColumnType(Types.VARBINARY, "blob");
registerColumnType(Types.LONGVARBINARY, "blob");
registerColumnType(Types.BLOB, "blob");
registerColumnType(Types.CLOB, "clob");
registerColumnType(Types.BOOLEAN, "integer");
registerHibernateType(Types.NULL, "null");

registerFunction("concat", new VarArgsSQLFunction(Hibernate.STRING, "",
"||", ""));
registerFunction("mod", new SQLFunctionTemplate(Hibernate.INTEGER,
"?1 % ?2"));
registerFunction("substr", new StandardSQLFunction("substr",
Hibernate.STRING));
registerFunction("substring", new StandardSQLFunction("substr",
Hibernate.STRING));

}

public boolean supportsIdentityColumns() {
return true;
}
public boolean hasDataTypeInIdentityColumn() {
return false;
}
public String getIdentityColumnString() {
return "integer";
}
public String getIdentitySelectString() {
return "select last_insert_rowid()";
}
public boolean supportsLimit() {
return true;
}

protected String getLimitString(String query, boolean hasOffset) {
return new StringBuffer(query.length() + 20).append(query).append(
hasOffset ? " limit ? offset ?" : " limit ?").toString();
}

public boolean supportsTemporaryTables() {
return true;
}

public String getCreateTemporaryTableString() {
return "create temporary table if not exists";
}

public boolean dropTemporaryTableAfterUse() {
return false;
}

public boolean supportsCurrentTimestampSelection() {
return true;
}

public boolean isCurrentTimestampSelectStringCallable() {
return false;
}

public String getCurrentTimestampSelectString() {
return "select current_timestamp";
}

public boolean supportsUnionAll() {
return true;
}

public boolean hasAlterTable() {
return false;
}

public boolean dropConstraints() {
return false;
}

public String getAddColumnString() {
return "add column";
}

public String getForUpdateString() {
return "";
}

public boolean supportsOuterJoinForUpdate() {
return false;
}

public String getDropForeignKeyString() {
throw new UnsupportedOperationException(
"No drop foreign key syntax supported by SQLiteDialect");
}

public String getAddForeignKeyConstraintString(String constraintName,
String[] foreignKey, String referencedTable, String[] primaryKey,
boolean referencesPrimaryKey) {
throw new UnsupportedOperationException(
"No add foreign key syntax supported by SQLiteDialect");
}

public String getAddPrimaryKeyConstraintString(String constraintName) {
throw new UnsupportedOperationException(
"No add primary key syntax supported by SQLiteDialect");
}

public boolean supportsIfExistsBeforeTableName() {
return true;
}

public boolean supportsCascadeDelete() {
return false;
}
}

但是在使用中抛了一个异常

org.hibernate.MappingException: No Dialect mapping for JDBC type: 0
到java.sql.Types类里看了一下这个0的类型是指null

public final static int NULL = 0;

解决方法:
在这个类的构造方法里加一句
registerHibernateType(Types.NULL, "null");

Tags: ,
Mar 4

项目使用hibernate 偶尔会出现:HibernateQueryException: Unable to locate appropriate constructor on class
下面罗列一下常见的原因:
1、首先要检查在实体类中是否有构造器,例如:
package com.itlife365.Student

public class Student implements java.io.Serializable {
private String name;
private String sex;
private Integer age;

public Student() {}     //无参构造器

public Xiaoqi(String name,String sex, Integer age) {   //全参构造器
   this.name= name;
   this.sex= sex;
   this.age= age;
}

public String getName() {
   return name;
}

public void setName(String name) {
   this.name = name;
}

public String getSex() {
   return sex;
 }

public void setSex(String sex) {
   this.sex = sex;
 }

public Integer getAge() {
   return age;
 }

public void setAge(Integer age) {
   this.age = age;
 }
}

2、如果有上面两个构造器,再检查变量是否匹配,不要写错了
3、然后要注意,变量类型是否匹配,比如,上面的age变量类型为:Integer,写成 int 可能会有问题。所以要注意long和Long,boolean和Boolean等等,最好写成long型
4、查询时有几个参数,你的构造器要对应相应的参数。'
5、与对象对应的映射文件xxx.hbm.xml中配置类型与类的实体类型是否有差异、不同。
6、hibernate中date对应的java的数据类型不能为:java.sql.Date ,只能为java.util.Date

Tags:
Mar 4
最近在做项目中使用到hibernate 的new map 的用法,这里记录一下:
//HQL-Map 语法demo
String hql = " select new map(usr.name as userName, usr.password as password) from User usr";
Query query = session.createQuery(hql);
List list = query.list();
Map goods =(Map)list.get(0);

// 实例:
public Object findByCid(String cid){
StringBuffer sbString = new StringBuffer();

sbString.append( " select new map( cid as cid , count(cid) as count)from Registration group by cid");
List list = baseService.find(sbString.toString());
System.out.println("**********");
for(Iterator ite = list.iterator();ite.hasNext();){
HashMap map = (HashMap)ite.next();
String cid2 = (String)map.get("cid");
Long count = (Long)map.get("count");
System.out.println("**********cid="+cid2);
System.out.println("**********count="+count);
}

return 1;

}

注意:模型model中 无需在添加自动,但是 Registration 必须是类名称 而不是表名称,查找的语句 必须有别名,才能获取的到值。
from 前面没有空格

参考:http://hi.baidu.com/tianfu_xue/blog/item/e16b1e1fdc8b620d314e15e4.html

http://hi.baidu.com/suofang/blog/item/0947291f754a4cd2a78669c0.html的介绍

Tags:
Feb 12

Hibernate 可以实现分页查询,例如:
从第100条开始取出10条记录

Query q = session.createQuery("from Student as s");
q.setFirstResult(100);
q.setMaxResults(10);
List l = q.list();
上面的语句我们在项目中一般封装在基础服务里面,供调用。

那么Hibernate底层如何实现分页的呢?实际上Hibernate的查询定义在net.sf.hibernate.loader.Loader这个类里面,仔细阅读该类代码,就可以把问题彻底搞清楚。

Hibernate2.0.3的Loader源代码第480行以下:

if (useLimit) sql = dialect.getLimitString(sql);
PreparedStatement st = session.getBatcher().prepareQueryStatement(sql, scrollable);

然后来看net.sf.hibernate.dialect.MySQLDialect:

public boolean supportsLimit() {
return true;
}
public String getLimitString(String sql) {
StringBuffer pagingSelect = new StringBuffer(100);
pagingSelect.append(sql);
pagingSelect.append(" limit ?, ?"); // mysql 分页查询的格式
return pagingSelect.toString();
}

再来看net.sf.hibernate.dialect.Oracle9Dialect:

public boolean supportsLimit() {
return true;
}

public String getLimitString(String sql) {
StringBuffer pagingSelect = new StringBuffer(100);
pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
pagingSelect.append(sql);
pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
return pagingSelect.toString();
}

Oracle采用嵌套3层的查询语句结合rownum来实现分页,这在Oracle上是最快的方式,如果只是一层或者两层的查询语句的rownum不能支持order by。
除此之外,Interbase,PostgreSQL,HSQL也支持分页的sql语句,在相应的Dialect里面,大家自行参考。
如果数据库不支持分页的SQL语句,那么根据在配置文件里面
#hibernate.jdbc.use_scrollable_resultset true
默认是true,如果你不指定为false,那么Hibernate会使用JDBC2.0的scrollable result来实现分页,使用ResultSet的absolute方法直接移到查询起点,如果不支持的话,使用循环语句,rs.next一点点的移过 去。
可见使用Hibernate,在进行查询分页的操作上,是具有非常大的灵活性,Hibernate会首先尝试用特定数据库的分页sql,如果没用,再尝试Scrollable,如果不行,最后采用rset.next()移动的办法。
在查询分页代码中使用Hibernate的一大好处是,既兼顾了查询分页的性能,同时又保证了代码在不同的数据库之间的可移植性。

Tags:
Feb 11

Hibernate中的HQL问题
org.hibernate.hql.ast.QuerySyntaxException: student is not mapped. [from student]
Caused by:
org.hibernate.hql.ast.QuerySyntaxException: student is not mapped. [from student]

原因student应为Student
HQL查询的是个类,首字母要大写,如from Student
如果是小写的student,Hibernate则不会找到相应的类来进行处理,可推断出HQL查询语句是区分大小写的,要求表名,字段名要与相匹配的类,属性同名,而且要严格保持一致,包括大小写,而SQL语句是不区分大小写的.
转换的语句为:
Hibernate: select student0_.id as id1_, student0_.name as name1_, student0_.sex as sex1_, student0_.tel as tel1_, student0_.age as age1_, student0_.email as email1_, student0_.pwd as pwd1_, student0_.userGroup as userGroup1_, student0_.education as education1_, student0_.CuserId as CuserId1_, student0_.UuserId as UuserId1_, student0_.CreateDateTime as CreateD12_1_, student0_.LastUpdateTime as LastUpd13_1_ from student student0_ where 1=1

可以分析出Hibernate是通过Java反射机制来完成动态转换这一功能的

Tags:
分页: 1/3 第一页 1 2 3 下页 最后页 [ 显示模式: 摘要 | 列表 ]