在使用原始SQL语句的情况下,将查询出来的结果映射到对象中:
本文假设hibernate环境已经配置在项目中(包括数据源:dataSource以及sessionFactory)
不使用hql语句,而是使用原生SQL语句或者hibernate封装好的工具类
在数据库中新建一张文章表:
DROP TABLE IF EXISTS `group_content_article`;
CREATE TABLE `group_content_article` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`title` varchar(255) DEFAULT NULL COMMENT '文章标题',
`img_url` varchar(2048) DEFAULT NULL COMMENT '配图url',
`content_id` bigint(11) DEFAULT NULL COMMENT '文章ID',
`article_url` varchar(2048) DEFAULT NULL COMMENT '文章url',
`time_limit_flag` bit(1) DEFAULT b'0' COMMENT '是否时间限制',
`valid_start_time` datetime DEFAULT NULL COMMENT '生效开始时间',
`valid_end_time` datetime DEFAULT NULL COMMENT '生效结束时间',
`data_source` int(5) DEFAULT '1' COMMENT '数据来源 1:自动获取 2:人工录入',
`visible_flag` bit(1) DEFAULT b'1' COMMENT '是否显示',
`publish_time` datetime DEFAULT NULL COMMENT '发布时间',
`last_sync_time` datetime DEFAULT NULL COMMENT '最后同步时间',
`read_count` bigint(11) DEFAULT '0' COMMENT '阅读次数',
`support_count` bigint(11) DEFAULT '0' COMMENT '点赞数',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_content_id` (`content_id`),
KEY `idx_last_sync_time` (`last_sync_time`),
KEY `idx_publish_time` (`publish_time`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4;
创建成功之后,在model中创建对应的Entity:
@Entity
@DynamicInsert(true)
@DynamicUpdate(true)
@Table(name = "GROUP_CONTENT_ARTICLE")//这是数据库对应的表名
public class GroupContentArticleEntity implements Serializable {
/**
* 版本号
*/
private static final long serialVersionUID = -1767884109348072235L;
/** */
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
/** */
@Column(name = "CREATE_TIME")
private Date createTime;
/** */
@Column(name = "UPDATE_TIME")
private Date updateTime;
/**
* 文章标题
*/
@Column(name = "TITLE")
private String title;
/**
* 配图url
*/
@Column(name = "IMG_URL")
private String imgUrl;
/**
* 文章ID
*/
@Column(name = "CONTENT_ID")
private Long contentId;
/**
* 文章url,目前人工录入才有
*/
@Column(name = "ARTICLE_URL")
private String articleUrl;
/**
* 是否时间限制
*/
@Column(name = "TIME_LIMIT_FLAG")
private Boolean timeLimitFlag;
/**
* 生效开始时间
*/
@Column(name = "VALID_START_TIME")
private Date validStartTime;
/**
* 生效结束时间
*/
@Column(name = "VALID_END_TIME")
private Date validEndTime;
/**
* 数据来源 1:自动获取 2:人工录入
*/
@Column(name = "DATA_SOURCE")
private Integer dataSource;
/**
* 是否显示
*/
@Column(name = "VISIBLE_FLAG")
private Boolean visibleFlag;
/**
* 发布时间
*/
@Column(name = "PUBLISH_TIME")
private Date publishTime;
/**
* 最后同步时间
*/
@Column(name = "LAST_SYNC_TIME")
private Date lastSyncTime;
/**
* 阅读次数
*/
@Column(name = "READ_COUNT")
private Integer readCount;
/**
* 点赞数
*/
@Column(name = "SUPPORT_COUNT")
private Integer supportCount;
创建对应的Dao方法,需要配置SessionFactory在hibernate.xml文件中,然后进行调用,在GenericDaoHibernate中加入下面代码以获取当前session和数据库连接:
@Resource
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return this.sessionFactory;
}
public Session getSession() throws HibernateException {
Session session = getSessionFactory().getCurrentSession();
if (session == null) {
session = getSessionFactory().openSession();
}
return session;
}
对应的sessionFactory以及DataSource配置此处不给出,需要自行配置!
创建对应的Dao接口:
public interface GroupContentArticleDao extends GenericDao<GroupContentArticleEntity, Long>
实现类:
@Repository("groupContentArticleDao")
public class GroupContentArticleDaoHibernate extends GenericDaoHibernate<GroupContentArticleEntity, Long> implements GroupContentArticleDao
类中的方法,按各自业务进行定义。
在查询article表时,可以写成:
//使用Query.addScalar方法进行列名与属性名对应
String sql = "select a.id id, a.create_time createTime, a.update_time updateTime, a.title title, " +
"a.img_url imgUrl, a.content_id contentId, a.article_url articleUrl, a.data_source dataSource, " +
"a.publish_time publishTime, a.read_count readCount, a.support_count supportCount " +
"from group_content_article a"
Query q = getSession().createSQLQuery(sql)
.addScalar("id", LongType.INSTANCE)
.addScalar("createTime", TimestampType.INSTANCE)
.addScalar("updateTime", TimestampType.INSTANCE)
.addScalar("title", StringType.INSTANCE)
.addScalar("imgUrl", StringType.INSTANCE)
.addScalar("contentId", LongType.INSTANCE)
.addScalar("articleUrl", StringType.INSTANCE)
.addScalar("dataSource", IntegerType.INSTANCE)
.addScalar("readCount", IntegerType.INSTANCE)
.addScalar("supportCount", IntegerType.INSTANCE)
.addScalar("publishTime", TimestampType.INSTANCE);
q.setResultTransformer(Transformers.aliasToBean(GroupContentArticleEntity.class));
q.list();
或者:
//使用SQLQuery.addEntity方法进行对应
//要求Entity.class要有对应的注解,Query类型要使用getSession().createSQLQuery(sql)创建。
String sql = "SELECT a.* FROM group_content_article a ";
Query query = getSession().createSQLQuery(sql)
.addEntity(GroupContentArticleEntity.class);
query.list();
两种方法各有益处,但是主要是要在Entity中写好对应的列名与对象属性名的对应。
有人说使用:
//使用Criteria 进行操作,插入条件时要使用Java对象的属性名,Entity.class中要有对应列名和属性名的注解
Criteria criteria = getSession().createCriteria(GroupContentArticleEntity.class);
//此方法加入条件时可以使用下面方法:Restrictions后有对应的条件约束,参数值 1 :属性名(不是数据库中的列名,而是对应的类属性名)、参数 2 :传入的条件值,需要外部传参,切类型对应
criteria.add(Restrictions.eq("contentId", contentId));
criteria.list()
然后在下方加入条件也可以。
但是hibernate最大的难处就是多表关联条件的使用,如果使用原始SQL语句,就可以很好解决这个问题,上面三种方法,将hibernate查询的结果对应到JavaBean中,可以按照不同的使用情景进行调整,也可以同时出现。