以下哪一个(EJB 3 JPA)
更好//查询
A)。 getEntityManager()。createQuery ("从用户o"中选择o);
//命名查询,其中findAllUser在实体级别定义
B)。的 getEntityManager()createNamedQuery (" User.findAllUser&#34); **
//原生查询
C)。 getEntityManager()。createNativeQuery (" SELECT * FROM TBLMUSER");
请解释一下哪种方法更好?
答案 0 :(得分:23)
它应该用于动态查询创建。
//Example dynamic query
StringBuilder builder = new StringBuilder("select e from Employee e");
if (empName != null) {
builder.append(" where e.name = ?");
}
getEntityManager().createQuery(builder.toString());
它就像一个常量变量,可以按名称重用。您应该在常见的数据库调用中使用它,例如"查找所有用户","按id"等查找。
这会创建一个完全依赖底层数据库的SQL脚本语言支持的查询。当需要复杂查询且JPQL语法不支持它时,它非常有用。
但是,如果底层数据库从一个数据库更改为另一个数据库,它可能会影响您的应用程序并需要更多工作。例如,如果您的开发环境是在MySQL中,并且您的生产环境使用的是Oracle。另外,如果存在多个结果,则返回的结果绑定可能很复杂。
答案 1 :(得分:1)
Native SQL不一定比Hibernate / JPA Query快。 Hibernate / JPA Query最终也被翻译成SQL。在某些情况下,可能会发生Hibernate / JPA不会生成最有效的语句,因此本机SQL可以更快 - 但使用本机SQL,您的应用程序会丢失从一个数据库到另一个数据库的可移植性,因此通常更好地调整Hibernate / JPA查询映射和HQL语句生成更高效的SQL语句。另一方面,本机SQL缺少Hibernate缓存 - 因此在某些情况下,本机SQL可能比Hibernate / JPA Query慢。
我没有性能,在大多数情况下,如果你加载所有列或只需要列,那么性能就无关紧要了。在数据库访问中,搜索行时会丢失时间,而不是在将数据传输到应用程序时。当您只阅读必要的列时。
答案 2 :(得分:0)
命名查询与查询相同。它们的名字只是为了让它们可以重复使用+它们可以在不同的地方声明,例如。在类映射,配置文件等(所以您可以更改查询而不更改actaul代码)
原生查询只是本机查询,你必须完成JPA Queries为你做的所有事情,例如。绑定和引用值等+它们使用DBMP独立语法(在您的情况下为JPQL),因此更改数据库系统(让saq从MySQL到Postgresql或H2)将需要更少的工作,因为它不(不总是)需要重写本机查询。
答案 3 :(得分:0)
对我来说,显然是前两个更好,即JPQL查询 - 第二个意味着实体管理器在加载持久性单元时将编译查询(并验证它们),而第一个只会在执行时产生错误时间。
您也可以在某些IDE中获得支持,它支持对象表示法(例如:select b from EntityA a left join a.entityB b
)以及对象关系映射(如集合,索引等)引入的其他一些奇怪的东西。
另一方面,在JPQL的角落情况下使用原始查询(如窗口函数,如select id, partition by (group_id) from table
)
答案 4 :(得分:0)
简单答案: 1)createQuery()-当您希望在运行时执行查询时。
2)createNamedQuery()-当您要发送常见的数据库调用,例如findBy<attribute>
,findAll
,..
3)createNativeQuery()-当您希望查询特定于数据库供应商时使用。这带来了 可移植性 的挑战。