休眠中的 CRUD 给出 table 未映射异常

CRUD in hibernate giving table not mapped exception

我正在尝试在 hibernate.However 中实施 CRUD 操作,但出现 "Table not mapped" 错误。而且,Query 即将在我的代码中弃用。 据我所知,table的映射是这样实现的only.Then,这里有什么问题吗?

代码

public void deleteTeacher(String name) {
    Transaction tx = null;
    Session session = Utility.getSessionFactory().openSession();
    tx = session.beginTransaction();
    Query query = session.createQuery("from vi where name=" + name);
    //Teacher teacher=(Teacher)session.get(Teacher.class, name);
    Teacher teacher = (Teacher) query.getSingleResult();
    session.delete(teacher);
    session.getTransaction().commit();
    session.close();
}

错误

Exception in thread "main" java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: vi is not mapped [from vi where name=Aayushi]
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:131)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:162)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:658)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:102)
    at DAO.deleteTeacher(DAO.java:45)
    at MainClass.main(MainClass.java:37)
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: vi is not mapped [from vi where name=Aayushi]
    at org.hibernate.hql.internal.ast.QuerySyntaxException.generateQueryException(QuerySyntaxException.java:79)
    at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:217)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:141)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153)
    at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:541)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:650)
    ... 3 more
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: vi is not mapped
    at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:171)
    at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:91)
    at org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:79)
    at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:324)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3696)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3585)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:720)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:576)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:313)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:261)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:266)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:189)
    ... 9 more

而配置类是

teacher.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>

<hibernate-mapping>
    <class name="Teacher" table="vi">

        <composite-id>
            <key-property name="name" column="name"  />
            <key-property name="subject" column="subject" length="10" />
        </composite-id>


    </class>
</hibernate-mapping> 

在 HQL 中,您必须使用 class 个名称,而不是 table 个名称,因此您的查询必须是:

"from Teacher where name="+Name

你还应该使用参数绑定,以防止SQL注入

字符串应介于 '' 之间,因此您的查询应如下所示:

Query query=session.createQuery("from vi where name='" + name + "');

但为了避免任何语法错误或 SQL 注入,您必须使用:

Query query = session.createQuery("from vi where name=:name");
query.setParameter("name", name);

编辑

为什么你根本不使用:

//no need to select your object before you delete it
//Query query = session.createQuery("from vi where name=" + name);
//Teacher teacher=(Teacher)session.get(Teacher.class, name);
//Teacher teacher = (Teacher) query.getSingleResult();

//just make a delete query directly
String hql = "DELETE FROM vi WHERE name= :name";
Query query = session.createQuery(hql);
query.setParameter("name", name);
int result = query.executeUpdate();

避免在删除之前select,如果结果为空,可能会导致此错误。

根据您的模型,您在这里做出了一些糟糕的假设。您的 Teacher 模型使用 namesubject 的复合键,但您的代码假定按名称定位 Teacher 会获得单行结果,而这只是'它永远是真的。

您需要调整您的数据模型并强制 name 在所有 Teacher 实体中保持唯一,这在现实世界中同样没有意义,或者修改您的删除解释这一点的代码。

以下代码采用 Hibernate 5.2,因此可能需要进行一些小的调整,但无论如何前提都完全相同:

final List<Teacher> teachers = session
   .createQuery( "FROM Teacher t WHERE t.name = :name", Teacher.class )
   .setParameter( "name", teacherName )
   .getResultList();

for ( Teacher teacher : teachers ) {
  session.remove( teacher );
}

@YCF_L关于删除之前的select的观点,其实是不是如果您的代码考虑了查询结果 可以 为空的事实,则会出现问题。但是因为按照上面的真实场景,多个老师 可以 有相同的名字,它不会给你一个错误,因为 returned List<> 会在跳过删除 for 循环时为空,或者包含值并执行删除 for 循环。

如前所述,如果您愿意,您可以盲目执行删除而不获取数据,这样看起来会非常相似。

int deleteCount = session
  .createQuery( "DELETE FROM Teacher t WHERE t.name = :name" )
  .setParameter( "name", teacherName )
  .executeUpdate();

在这种情况下,您可以使用 return 值 deleteCount 来记录有多少教师被删除,或者如果该值可能 不是 [=42],则执行一些特定代码=]如你所料。

最后,虽然其他人指出了使用参数绑定来避免 SQL 注入的好处,但由于许多其他原因,参数绑定也很重要。

例如,绑定参数 SQL 可以由您的数据库进行优化、规划和缓存,并在以后的查询中重复使用。当您直接将实际值引入 SQL 时,大多数数据库平台会按原样缓存查询,因此只有在使用相同参数提供与之前完全相同的 SQL 时才能获得此好处。