http://blog.csdn.net/majian_1987/article/details/8725197
LZ在项目中需要处理这样一个业务,每天都有终端设备上传GPS位置信息到服务端,服务端要把GPS位置信息保存在本地,因为每天上传的GPS数据信息会有很多,
所以要把GPS数据按天分别存放在不同的表中,如2013年3月27日上传的GPS数据保存在Disa_GPS_20130327表中,而2013年3月28日上传的GPS数据保存在Disa_GPS_20130328表中,依次类推。这些表的数据结构完全一样,所以LZ想用一个实体去动态映射这些结构相同的表。在网上查了些资料,结果都是需要xml映射文件的,
而LZ用的是hibernate3.x的注解方式实现的映射,当时随便试了下,也没有调通(很惭愧,如果有研究注解方式可以实现的朋友,麻烦共享下,先在这里谢谢了)。所以,又另寻它法。后来在网上又找到了一个通过HQL的基础,SQLQuery实现的动态映射方法,经过LZ实验,终于调通。在此,与各位共享下。
【注】:DIsaGpsdata是实体类,里面要写注解或配置hbm.xml文件。
DisaGpsdata.java:
- package com.supermap.earth.server.hibernate.disaster;
- import java.math.BigDecimal;
- import java.util.Date;
- import javax.persistence.Column;
- import javax.persistence.Entity;
- import javax.persistence.Id;
- import javax.persistence.Table;
- import javax.persistence.Temporal;
- import javax.persistence.TemporalType;
- @Entity
- @Table(name = "DISA_GPSDATA", schema = "EARTH_DISASTER")
- public class DisaGpsdata implements java.io.Serializable {
- private String id;
- private String temId;
- private String earthId;
- private String userId;
- private Double lng;
- private Double lat;
- private Double secretLng;
- private Double secretLat;
- private Date gpsTime;
- private Double gpsDir;
- private Double gpsSpeed;
- public DisaGpsdata() {
- }
- public DisaGpsdata(String id, String temId, Double lng, Double lat,
- Double secretLng, Double secretLat, Date gpsTime, Double gpsDir,
- Double gpsSpeed) {
- super();
- this.id = id;
- this.temId = temId;
- this.lng = lng;
- this.lat = lat;
- secretLng = secretLng;
- secretLat = secretLat;
- this.gpsTime = gpsTime;
- this.gpsDir = gpsDir;
- this.gpsSpeed = gpsSpeed;
- }
- public DisaGpsdata(String id, String temId, String earthId, String userId,
- Double lng, Double lat, Double secretLng, Double secretLat,
- Date gpsTime, Double gpsDir, Double gpsSpeed) {
- super();
- this.id = id;
- this.temId = temId;
- this.earthId = earthId;
- this.userId = userId;
- this.lng = lng;
- this.lat = lat;
- secretLng = secretLng;
- secretLat = secretLat;
- this.gpsTime = gpsTime;
- this.gpsDir = gpsDir;
- this.gpsSpeed = gpsSpeed;
- }
- @Id
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- @Column(name="TEM_ID")
- public String getTemId() {
- return temId;
- }
- public void setTemId(String temId) {
- this.temId = temId;
- }
- public Double getLng() {
- return lng;
- }
- public void setLng(Double lng) {
- this.lng = lng;
- }
- public Double getLat() {
- return lat;
- }
- public void setLat(Double lat) {
- this.lat = lat;
- }
- @Column(name="SECRET_LNG")
- public Double getSecretLng() {
- return secretLng;
- }
- public void setSecretLng(Double secretLng) {
- secretLng = secretLng;
- }
- @Column(name="SECRET_LAT")
- public Double getSecretLat() {
- return secretLat;
- }
- public void setSecretLat(Double secretLat) {
- secretLat = secretLat;
- }
- @Temporal(TemporalType.TIMESTAMP)
- @Column(name = "GPS_TIME")
- public Date getGpsTime() {
- return gpsTime;
- }
- public void setGpsTime(Date gpsTime) {
- this.gpsTime = gpsTime;
- }
- @Column(name = "GPS_DIR")
- public Double getGpsDir() {
- return gpsDir;
- }
- public void setGpsDir(Double gpsDir) {
- this.gpsDir = gpsDir;
- }
- @Column(name = "GPS_SPEED")
- public Double getGpsSpeed() {
- return gpsSpeed;
- }
- public void setGpsSpeed(Double gpsSpeed) {
- this.gpsSpeed = gpsSpeed;
- }
- @Column(name = "EARTH_ID")
- public String getEarthId() {
- return earthId;
- }
- public void setEarthId(String earthId) {
- this.earthId = earthId;
- }
- @Column(name = "USER_ID")
- public String getUserId() {
- return userId;
- }
- public void setUserId(String userId) {
- this.userId = userId;
- }
- }
1.新增操作:
- public void addDisaGpsData(DisaGpsdata data, String tabName)
- throws Exception {
- Transaction tx = session.beginTransaction();
- SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
- Date date = new Date();
- String sql = "insert into disa_gpsdata_"
- + sdf.format(date)
- + " (id, tem_id, lng, lat, gps_time, gps_dir, gps_speed, earth_id, user_id, secret_lng, secret_lat)"
- + " values (?, ?, ?, ?, ?, ?, ?, ?, ?,?,?)";
- SQLQuery query = session.createSQLQuery(sql);
- query.setString(0,data.getId());
- query.setString(1,data.getTemId());
- query.setDouble(2,data.getLng());
- query.setDouble(3,data.getLat());
- query.setDate(4,data.getGpsTime());
- query.setDouble(5,data.getGpsDir());
- query.setDouble(6,data.getGpsSpeed());
- query.setString(7,data.getEarthId());
- query.setString(8,data.getUserId());
- query.setDouble(9,data.getLng());
- query.setDouble(10,data.getLat());
- try {
- query.executeUpdate();
- } catch (Exception e) {
- tx.rollback();
- e.printStackTrace();
- }
- tx.commit();
- }
2.删除操作:
- public void removeDisaGpsDataById(String id, String tabName)
- throws Exception {
- Transaction tx = session.beginTransaction();
- String sql = "delete " + tabName + " where id = ?";
- SQLQuery query = session.createSQLQuery(sql);
- query.setString(0,id);
- try {
- query.executeUpdate();
- tx.commit();
- } catch (Exception e) {
- tx.rollback();
- e.printStackTrace();
- }
- }
3.查询操作:
注:这里写的是一个DEMO,
- public List<DisaGpsdata> queryDisaGpsdatasByPara(Page page, Map map,
- String tabName) throws Exception {
- List<DisaGpsdata> datas = null;
- String sql = "select * from " + tabName
- + " where id = ?";
- SQLQuery query = session.createSQLQuery(sql);
- query.addEntity(DisaGpsdata.class);
- query.setString(0,(String)map.get("id"));
- try {
- datas = query.list();//返回多条记录的结果集,如果返回一条记录的调用query.uniqueResult();
- } catch (Exception e) {
- e.printStackTrace();
- }
- return datas;
- }
【总结】:执行查询操作时,需要把查询出来的结果集和实体之间建立映射关系:通过query.addEntity(DisaGpsdata.class);就可以建立表和DisaGpsdata之间的映射关系。
以上便可以实现一个实现DisaGpsdata和多张表之间的动态映射功能。资料参考了【有思想的代码:http://wujuxiang.blog.51cto.com/2250829/403693】,感谢有思想的代码。
另:HibernateSessionFactory类是通过hibernate.cfg.xml配置文件得到的Session工厂,所以要保证hibernate.cfg.xml中一定要含有DisaGpsdata类的映射信息,LZ项目中用的是注解方式,所以在hibernate.cfg.xml中配置的是:
<mapping class="com.supermap.earth.server.hibernate.disaster.DisaGpsdata"/>
如果项目中用的是hbm.xml来映射实体和表之间的关系,则用<mapping resource="*.hbm.xml"/>来引入DisaGpsdata类的映射配置文件,否则报错:org.hibernate.MappingException: Unknown entity:com.supermap.earth.server.hibernate.disaster.DisaGpsdata,这点挺重要,LZ就犯了这个错误,费了好久才找到原因!
------------------------------------
hibernate动态表名映射--只有想不到,没有做不到
http://www.2cto.com/kf/201409/339525.html
最近的一个项目有一个需求,有N个考核单位,要对每个考核单位生成一张考核情况表,这样做的目的是横切数据库,这这个需求的实现中,我的组员遇到了一个技术问题,我将我的解决办法和整个思考过程与大家分享,
思路:
用一个配置文件,一个类去映射多个表,(每个表的结构相同)。按照平时的做法,有多少个表就要 写多少个配置文件,岂不是很麻烦。怎样才能只写一个配置文件就能达到上述目的呢? 经过研究,发现Hibernate中的NamingStrategy可以达到这个目的。它是用来定义表名和列名映射规 则的一个接口。我们要通过实现这个接口来实现自己的命名策略。这个接口中包含的十个方法,其中的 public String classToTableName(String className)是通过类名来映射表名的。实现我们的想法就要用 到这个方法。好了,下面来看怎么做:
步骤:
1、自定义一个类MyNamingStrategy来实现NamingStrategy。(这样你要实现10个方法,如果其他方法 不需要,我们可以通过继承它的一个适配器类DefaultNamingStrategy来只实现我们需要的方法)好了,我 们就继承DefaultNamingStrategy 吧。2、实现public String classToTableName(String className)方法来实现自己命名策略。
我这的业务需要是每隔一个月就要换一个表。比如1月用biz_1,那么2月就用biz_2….但是这些表的结构是相同的。我们要做的就是通过获得月份来动态的选择表。我们从这个方法中这样写:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<span style=
"font-size:18px;"
>
/**
*这个类是重新定义一个hibernate的命名规范
**/
public
class
MyNamingStrategy
extends
DefaultNamingStrategy {
//这是为了实现单例
public
static
final
MyNamingStrategy INSTANCE =
new
MyNamingStrategy();
//重新定义名称映射关系
public
String classToTableName(String className) {
//自己的名称定义规则
return
“biz_” + Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
}
} </span>
|
3、使用命名策略。
要使用这个命名策略可以这样:
1
2
3
4
|
<span style=
"font-size:18px;"
>Configuration cfg =
new
Configuration()
.setNamingStrategy(MyNamingStrategy.INSTANCE)
.configure(“hibernate.cfg.xml”)
.addFile(“biz.hbm.xml”); </span>
|
ok,这样就可以实现我们的动态表名映射啦!
总结:
很多时候,我是经常被自己的思维所束缚,这是我的一种思维惯性,而且我只要找到一种解决问题的方法,就会当作宝典收藏,别人有比你好的,也会有种排斥的信息,二者恰恰是阻碍我们进步的牢笼,我们应该冲破这曾牢笼,我们应该更大胆些,想到且看到我们和以前截然不同的一面!