Jpajpa sql 返回对象象必须是与Entity类么

台前幕后 的BLOG
用户名:台前幕后
文章数:14
访问量:24393
注册日期:
阅读量:5863
阅读量:12276
阅读量:418061
阅读量:1106001
51CTO推荐博文
参考:  1、  2、&  在JPA 2.0 中我们可以使用entityManager.createNativeQuery()来执行原生的SQL语句。但当我们查询结果没有对应的实体类时,query.getResultList()返回的是一个List&Object[]&,也就是说每行的数据被作为一个对象数组返回。常见的用法是这样的:public&void&testQuery(){
Query&query&=&entityManager.createNativeQuery("select&id,&message,created&"
+&"from&message&");
List&Object[]&&rows&=&query.getResultList();
for&(Object[]&row&:&rows)&{
("id&=&"&+&row[0]);
("message&=&"&+&row[1]);
("created&=&"&+&row[2]);
}但这样用会使代码非常不容易让人理解, 究竟下标为n的元素到底是什么?不去数查询语句是不知道的,而且一旦查询语句的select部分的顺序被调整,Java代码也要一起调整。这时候我们想如果返回的是Map的话,用起来会清晰的多。  可惜的是JPA的API中并没有提供这样的设置。其实很多JPA的底层实现都是支持返回Map对象的。例如:  EclipseLink 的 query.setHint(QueryHints.RESULT_TYPE, ResultType.Map);  Hibernate 的 query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);  OpenJPA 的&QueryImpl&impl = q.unwrap(QueryImpl.class);&impl.setResultClass(Map.class);  如果项目中用的是其他的ORM实现,可以在代码中选中Query按Ctrl+T 查看具体的实现类,在实现类中有设置返回类型为Map的方法。所以,如果我们想要返回Map并且确定底层用的是某一种JPA的实现时我们可以退而求其次, 牺牲跨实现的特性来满足我们的需求:&  1)、Hibernate&:public&void&testQuery()&{
Query&q&=&entityManager.createNativeQuery("select&*&from&message");
//&将结果转化为&Map&tableKey,&keyValue&
query.unwrap(org.hibernate.SQLQuery.class)
.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
List&Map&String,&Object&&&list&=&q.getResultList();
for&(Map&String,&Object&&m&:&list)&{
("m:&"&+&m);
}  2)、OpenJPApublic&void&testQuery()&{
Query&q&=&entityManager.createNativeQuery("select&*&from&message");
QueryImpl&impl&=&q.unwrap(QueryImpl.class);
impl.setResultClass(Map.class);
("q:&"&+&q);
List&list&=&q.getResultList();
for&(Map&m&:&list)&{
("m:&"&+&m);
了这篇文章
类别:┆阅读(0)┆评论(0)JPA entity继承策略 - 苹果超人| - ITeye技术网站
博客分类:
JPA支持3种类型的继承形式:
1.Single Table Strategy ,单表策略,一张表包含基类与子类的所有数据,很多情况下都是采用这样的冗余设计,通过一个discriminator来区分。
2.Table Per Class Strategy ,每个子类对应一张表,每张表都拥有基类的属性,基类不会生成表。
3.Join Strategy ,仍然是每个子类对应一张表,但此表中不包含基类的属性,仅仅是此子类的扩展属性,共享基类的属性。
下面是SingleTable的一个小例子:
基类:
package com.kevin.ejb.
import javax.persistence.DiscriminatorC
import javax.persistence.DiscriminatorT
import javax.persistence.E
import javax.persistence.GeneratedV
import javax.persistence.GenerationT
import javax.persistence.Id;
import javax.persistence.I
import javax.persistence.InheritanceT
import javax.persistence.T
@Table(name = "t_animal")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "animalType", discriminatorType = DiscriminatorType.STRING)
public class Animal {
@GeneratedValue(strategy = GenerationType.AUTO)
public int getId() {
public void setId(int id) {
public String getName() {
public void setName(String name) {
this.name =
public String getSex() {
public void setSex(String sex) {
this.sex =
子类:
package com.kevin.ejb.
import javax.persistence.DiscriminatorC
import javax.persistence.DiscriminatorT
import javax.persistence.DiscriminatorV
import javax.persistence.E
import javax.persistence.I
import javax.persistence.InheritanceT
import javax.persistence.T
@Table(name = "t_cat")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue(value = "cat")
public class Cat extends Animal {
public String getNickname() {
public void setNickname(String nickname) {
this.nickname =
子类:
package com.kevin.ejb.
import javax.persistence.DiscriminatorC
import javax.persistence.DiscriminatorT
import javax.persistence.DiscriminatorV
import javax.persistence.E
import javax.persistence.I
import javax.persistence.InheritanceT
import javax.persistence.T
@Table(name = "t_dog")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue(value = "dog")
public class Dog extends Animal {
public String getAddress() {
public void setAddress(String address) {
this.address =
生成的数据库表:
浏览: 122701 次
来自: 上海
新手来学习...
[color=orange][/color]
[align=center][size=x-large][im ...1256人阅读
java(29)
一个普通POJO类通过标注@Entity可以映射成为持久化的类,可持久化的类可以对应数据库中的数据.
首先我们先来看一个很简单的POJO类,Student表示学生,有两个属性,一个是stuId,为实体的唯一标识,一个是stuName,为学生的姓名,Student类的代码如下:
public class Student {
public Student(){
public Student(Integer stuId,String stuName){
this.stuId=stuId;
this.stuName=stuN
* 唯一标识
private Integer stuId;
public Integer getStuId() {
return stuId;
public void setStuId(Integer stuId) {
this.stuId = stuId;
* 学生姓名
private String stuN
public String getStuName() {
return stuN
public void setStuName(String stuName) {
this.stuName = stuN
以上是符合javaBean样式的类,符合javaBean风格主要有以下几个关键点
类属性必须为private的,外界获得和设置属性值必须通过getter和setter方法
方法和Setter方法必须是public的.
Getter方法和Setter方法和命名符合Java方法的命名规范:
T getProperty()
Void setProperty(T t)
了解了普通的POJO类之后,在hibernate中,我们知道是使用xml配置文件,把entity的属性保存到数据库中,而且每一个entity类就需要建立一个xml,针对小型的系统,建立的实体不多的时候,hibernate还可以解决,一旦entity类超过10个以上,xml的泛滥和后期的维护与扩展,就是一个很大问题,针对entity类和xml过多情况,可以使用JPA的映射实体注解@Entity解决.
标注@Entity
注解的类,表示该类是一个可持久化的实体.当在容器中时,服务器将会加载所有标注了@Entity注解的实体类,而且每一个实体至少有一个主键(Primary
Key),这个时候就可以用注解@Id来表示.例如Student类标注成实体后:
package tgb.tanghuan.
import java.io.S
import javax.persistence.E
import javax.persistence.Id;
public class Student implements Serializable{
public Student(){
public Student(Integer stuId,String stuName){
this.stuId=stuId;
this.stuName=stuN
* 唯一标识
private Integer stuId;
public Integer getStuId() {
return stuId;
public void setStuId(Integer stuId) {
this.stuId = stuId;
* 学生姓名
private String stuN
public String getStuName() {
return stuN
public void setStuName(String stuName) {
this.stuName = stuN
若要使Entity支持可序
public class Student implements Serializable{
虽然是可选择的,但是还是建议每个entity都加上Serializable
在hibernate中使用过xml配置文件来控制entity类持久化.但是大量的entity类和xml文件,查找和修改的时候,还得一个的查找,费时费精力.碰到一个新手维护项目,一个entity包下面密密麻麻的全是.java文件和.xml配置文件,会把新手逼疯的.但是使用JPA的注解,就会好很多,只要找到相对应的entity类,然后进行扩展就可以了.JPA注解的出现,就是为了解决hibernate的xml文件配置问题.让程序员从复杂的xml配置文件中解脱出来.
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:341228次
积分:11149
积分:11149
排名:第1247名
原创:213篇
评论:2592条
阅读:13206
(3)(4)(4)(4)(4)(5)(4)(4)(4)(4)(4)(5)(4)(4)(4)(4)(5)(4)(4)(4)(4)(5)(4)(4)(5)(4)(4)(4)(6)(5)(3)(4)(4)(6)(4)(4)(6)(2)(8)(13)(6)(9)(12)(4)(2)(2)用原生sql查询返回实体对象的方法 - 推酷
用原生sql查询返回实体对象的方法
最近由于需求变更,客户需要在原来的查询基础上加上一个判断条件,但是这个判断条件所在的实体跟原来的查询实体没有直接关联。为了不影响原来的查询结果,改为用原生SQL,使用left join来关联查询。为了不改变对查询结果的处理逻辑,将查询结果封装成原来的对象进行操作。具体操作方法如下:
1.基于JPA规范的程序:
Query query = entityManager.createNativeQuery(&select id, name, age from t_user&);
query.unwrap(SQLQuery.class).setResultTransformer(Transformers.aliasToBean(clazz));
其中clazz为封装对象的class
List rows = query.getResultList();
2.基于Session的程序:
sess.createSQLQuery(&SELECT NAME, BIRTHDATE FROM CATS&).setResultTransformer(Transformers.aliasToBean(clazz));
这两种方法需要注意的是查询的字段的别名需要跟clazz的属性对应。
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致JPA换进上慎用entity_读书人
JPA换进上慎用entity
&来源:读书人网&【读书人网():综合教育门户网站】
JPA换进下慎用entity今天跟一个同事调试代码,突然发现,诸如findUserById(Integer uid)这样的方法,尽然产生
JPA换进下慎用entity &&& 今天跟一个同事调试代码,突然发现,诸如findUserById(Integer uid)这样的方法,尽然产生了一条update的sql语句,感觉很奇怪,并没有发现任何更新的地方,怎么会产生这条update语句呢???这个方法大致是这样的:public User findUserById(Integer uid) {
return entityManager.find(User.class, uid);}&& 仔细检查代码,却发现,在User类中,有这样的做法:public class User implements Serializable {
private Date lastLoginT
public void setLastLoginTime(Date date) {
this.lastLoginTime = new Date();
... ...}&&& 以往用惯Hibernate的朋友(像我就是这样),可能会觉得find出一个对象,然后你怎么区更改这个对象,不会同步到中去,而在JTA环境中,不是这样的,在JTA环境中,默认的,一个的操作方法,在方法开始前就会开启一个事务,而在方法结束后就会提交这个事务,这个过程对程序员来说是透明的,程序员自己感觉不到,不用编写任何代码就能完成的事情。&&& 不懂这个道理的朋友,可能很多人跟我一样,在学习的初期,大家都说EJB复杂,不好用,都被一本叫做XXX without EJB的书教唆至直接学习Spring +& Hibernate + Status去了,一提起Spring都会说有多么多么的好,其中就有一个叫做“声明式事务管理”的东东,当时我一直不知道到底为啥要叫做“声明式事务”,就简单的理解成,用那个事务拦截器配置 add*、save*、delete*啊,这样配置,然后写出诸如addUser、saveUser这样的方法,就可以了,直到我有一次直去写jdbc的时候,我才知道,不使spring事务管理去写那个编程式事务到底是怎么回事:tx.start();... ...tx.commit();&&& 于是了解了到底声明式事务是咋回事,这一扯就扯远了,不过也很无奈,谁叫我们大学里之交了java的语法,然后人家公司一招聘就要ssh之类的,逼的大家都ssh去了,一向自强的我又不愿意去培训那个什么“北大青鸟”、“新东方”当时我上大学的时,记得是这两个培训机构闹的最火,学费好贵,不是1W就是2W,我当时有两个选择,一个是买太超酷的电脑,一个就是去那里培训,几经思考海是抵挡不住“迪兰恒景”显卡的诱惑,最终搞了台1.2W 的电脑,于是开始了一边打“孤岛惊魂”,一边学java的日子....扯太远了,还是回归正体.&&& 在EJB环境下,有个叫做entityManager的东东,这个东西与hibernate的session不太一样,session里去出来的对象,你可以去任意的修改里边的属性,直到你自己调用update这样的方法,才会更新到数据库中,但是在EJB下,却不是那个样子。&&& EJB中的entityManager的持久华对象大致上有三种(还有多的,大家补充一下):&&& 1.调用entityManager.persist(Object o).&&& 2.调用entituManager.merge(Object o).&&& 3.调用entityManager.find(Class clazz,Object o)第一种:&&& 原来在数据库中没有这条记录,调用后会同步到数据库,前提条件是事务提交,那么默认的EJB环境下,是会自动提交这个事务,如果说,你在执行:user.setName("111111");entityManager.persist(user);user.setName("222222");这样最终,同步到数据库中的是user.name=22222.&&& 为什么会这样呢,这与我们原来用的hibernate有很大的不同, 虽然hibernate也有persist这样的方法,但是很少在ssh这样的环境下使用,一般都只是使用save方法,那么persist与save到底有什么不同呢,我怕自己描述不清除,从网上抄来了一段话:persist把一个瞬态的实例持久化,但是并"不保证"标识符被立刻填入到持久化实例中,标识符的填入可能被推迟到flush的时间&&& &&& 用我的话说就是把一个对象交给entityManager来管理,但entiyManager并不保证立刻写进数据库,直到调用flush方法的时候才会提交,那么默认的当一个事务结束的时候,是会自动调用flash方法,这样才算吧对象同步到数据库中了,所以上边那个程序最终写到数据库中的是22222.&&& 但是save方法会立即写入数据库.第二种:&&& 这个可以拿来与hibernate中的update方法来比较, 所谓要执行update,那表明了,数据库中已经有该对象所对应的记录,只是现在做一个更新操作,把对象中的属性值同步到数据库中去,当你执行update操作时,会立刻的打印出sql语句,而merge方法则不会,道理跟上边的save一样,只是把这个需要更新的对象交给entityManager管理,并不意味着立刻执行同步到数据库的操作,直到调用flush方法,entityManager才会去同步的数据库,同样的,事务结束的时候也会自动的调用flush方法.第三种:&&& 执行查找操作,如果数据库中有这条数据,则会返回一个引用给上层调用,那么这个过程经历了:数据库--&entityManager--&findUserById,三个过程,这里我们吧findUserById这个方法叫做上层,它可以由更上层的方法调用,在调用findUserById方法时,默认的EJB容器会开启事务(如果findUserById还有更上层的方法也会同样的加入到这个事务中来),拿我在最上边写的那个User类来说:1.首先entityManager会从数据库中查找到记录2.然后调用User的默认构造函数去生成一个对象3.接着把数据库中的记录的值赋给这个新生对象,调用了User类的setXXX方法来赋值4.把组装好的对象返回给上层调用&&& 但上边代码setLastLoginTime的做法,意图是直接在bean里产生一个最新的时间,那么,在底层调用的时候,刚好使用了最新的Date实例覆盖了原有的值,导致了返回给上层的User对象的属性值与数据库中的不一致,所以执行一次findUserById导致产生update的操作.&&& 不知不觉的开发过程貌似已经习惯了吧entity当作pojo来处理...&&& 一点经验,写下来希望可以帮助大家:)

我要回帖

更多关于 jpa sql 返回对象 的文章

 

随机推荐