关于Session.getIdentifier(Object entity)的讨论

本文探讨了Hibernate提供的两种获取数据库ID的方法:通过持久化实例的标识符属性与使用Session.getIdentifier方法。文中对这两种方法的实际应用场景及意义进行了讨论。
在重读Hibernate时,在4.2.2一节发现这么一段话:
Hibernate exposes database identity to the application in two ways(Hibernate的API提供了两种方法来获得数据库ID):
■ The value of the identifier property of a persistent instance (通过处于持久太对象的getId方法)
■ The value returned by Session.getIdentifier(Object entity) (调用Session.getIdentifier(Object entity)方法)

前面两句话理解上没有任何问题, 最后一句有些疑问:这个方法有什么实际意义?当得到一个Model类后不也就自然而然地以getId方式获得它的ID,为什么还要绕一下呢?这里面有什么玄机?

看Session实现类SessionImpl对getIdentifier方法实现的源码,也没发现什么特殊之处。

大家说说看这个方法ession.getIdentifier(Object entity)有什么特殊意义?Hibernate为什么加这么个方法呢?实际中怎么用?
package com.kucun.data.entity; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; /** 产品组件关联类 @author Administrator */ @Entity @Table(name=“chanpin_zujian”) public class Chanpin_zujian { @Id private Integer id; // 关联到产品 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = “chanpin_id”) private Chanpin chanpin; // 关联到组件 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "zujian_id") private Zujian zujian; // 关联到板材 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "bancai_id") private Bancai bancai; private Double one_howmany; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Chanpin getChanpin() { return chanpin; } public void setChanpin(Chanpin chanpin) { this.chanpin = chanpin; } public Zujian getZujian() { return zujian; } public void setZujian(Zujian zujian) { this.zujian = zujian; } public Bancai getBancai() { return bancai; } public void setBancai(Bancai bancai) { this.bancai = bancai; } public Double getOne_howmany() { return one_howmany; } public void setOne_howmany(Double one_howmany) { this.one_howmany = one_howmany; } public Chanpin_zujian() { super(); // TODO Auto-generated constructor stub } } package com.kucun.data.entity; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.UniqueConstraint; /** 订单 @author Administrator */ @Entity @Table(name=“dingdan”, uniqueConstraints = { @UniqueConstraint(columnNames = “number”) }) public class Dingdan { @Id private Integer id; //订单号 private String number; @OneToMany( mappedBy = “dingdan”, cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true ) private List<Dingdan_chanpin> dingdan_chanpins; // 优化订单与订单组件关联 @OneToMany( mappedBy = “dingdan”, cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true ) private List<Dingdan_chanpin_zujian> dingdan_chanpins_zujians; public List<Dingdan_chanpin_zujian> getDingdan_chanpins_zujians() { return dingdan_chanpins_zujians; } public void setDingdan_chanpins_zujians(List<Dingdan_chanpin_zujian> dingdan_chanpins_zujians) { this.dingdan_chanpins_zujians = dingdan_chanpins_zujians; } public List<Dingdan_chanpin> getDingdan_chanpins() { return dingdan_chanpins; } public void setDingdan_chanpins(List<Dingdan_chanpin> dingdan_chanpins) { this.dingdan_chanpins = dingdan_chanpins; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public Dingdan(Integer id, String number) { super(); this.id = id; this.number = number; } public Dingdan() { super(); // TODO Auto-generated constructor stub } } package com.kucun.data.entity; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; /** 订单和产品关联 @author Administrator */ @Entity @Table(name=“dingdan_chanpin”) public class Dingdan_chanpin { @Id private Integer id; //产品信息 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = “dingdan_id”) // 指 private Dingdan dingdan; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "chanpin_id") // 指 private Chanpin chanpin; private Integer shuliang;//产品数量; public Chanpin getChanpin() { return chanpin; } public void setChanpin(Chanpin chanpin) { this.chanpin = chanpin; } public Integer getShuliang() { return shuliang; } public void setShuliang(Integer shuliang) { this.shuliang = shuliang; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Dingdan getDingdan() { return dingdan; } public void setDingdan(Dingdan dingdan) { this.dingdan = dingdan; } public Chanpin getChanping() { return chanpin; } public void setChanping(Chanpin chanping) { this.chanpin = chanping; } } package com.kucun.data.entity; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; /** 一个订单中的产品组件订购板材数量 @author Administrator */ @Entity public class Dingdan_chanpin_zujian { @Id private Integer id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "dingdan_id") // 指定外键列 private Dingdan dingdan; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "chanpin_zujian_id") // 指定外键列 private Chanpin_zujian zujian; // 修改为单数形式 //板材 @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "bancai_id") private Bancai bancai; //订购数 private Integer shuliang ; public Dingdan_chanpin_zujian() { super(); // TODO Auto-generated constructor stub } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Dingdan getDingdan() { return dingdan; } public void setDingdan(Dingdan dingdan) { this.dingdan = dingdan; } public Bancai getBancai() { return bancai; } public void setBancai(Bancai bancai) { this.bancai = bancai; } public Chanpin_zujian getZujian() { return zujian; } public void setZujian(Chanpin_zujian zujian) { this.zujian = zujian; } public Integer getShuliang() { return shuliang; } public void setShuliang(Integer shuliang) { this.shuliang = shuliang; } } package com.kucun.data.entity; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; /** 通信类 @author Administrator */ public class Information { private static final ObjectMapper mapper = new ObjectMapper(); private Integer Status ; private String text; private Object data; public Integer getStatus() { return Status; } public void setStatus(Integer status) { Status = status; } public String getText() { return text; } public void setText(String text) { this.text = text; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } public Information(Integer status, String text, Object data) { super(); Status = status; this.text = text; this.data = data; } @SuppressWarnings({“unchecked”,“rawtypes”}) public Information(Integer status, String text, String data, Class T) throws Exception { super(); Status = status; this.text = text; this.data = fromJson(data,T); } public Information() { super(); // TODO Auto-generated constructor stub } public String DataJson() throws JsonProcessingException { // Java对象转JSON return mapper.writeValueAsString(this); } @SuppressWarnings(“unchecked”) public <T> T fromJson(String json, Class<T> clazz) throws Exception { data= mapper.readValue(json, clazz); return (T) data; } public static Information NewSuccess(Object data) { return new Information(200, "success", data); } public static Information NewSuccess(String data) { return new Information(200, "success", data); } public static Information Newfail(Integer status,String text,Object data) { return new Information(status, "success", data); } } package com.kucun.data.entity; import java.util.Date; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.ManyToOne; @Entity public class Jinhuo { @Id private Integer id; @ManyToOne private Dingdan dingdan; @ManyToOne private Chanpin chanpin; @ManyToOne private Zujian zujian; @ManyToOne private Bancai bancai; private Integer shuliang; private Date date; @ManyToOne private User user; public Jinhuo(Integer id, Dingdan dingdan, Chanpin chanpin, Zujian zujian, Bancai bancai, Integer shuliang, Date date, User user) { super(); this.id = id; this.dingdan = dingdan; this.chanpin = chanpin; this.zujian = zujian; this.bancai = bancai; this.shuliang = shuliang; this.date = date; this.user = user; } public Jinhuo() { super(); // TODO Auto-generated constructor stub } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Dingdan getDingdan() { return dingdan; } public void setDingdan(Dingdan dingdan) { this.dingdan = dingdan; } public Chanpin getChanpin() { return chanpin; } public void setChanpin(Chanpin chanpin) { this.chanpin = chanpin; } public Zujian getZujian() { return zujian; } public void setZujian(Zujian zujian) { this.zujian = zujian; } public Bancai getBancai() { return bancai; } public void setBancai(Bancai bancai) { this.bancai = bancai; } public Integer getShuliang() { return shuliang; } public void setShuliang(Integer shuliang) { this.shuliang = shuliang; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } } package com.kucun.data.entity; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToOne; /** 库存 @author Administrator */ @Entity public class Kucun { @Id private Integer id; private Long shuliang; @OneToOne(fetch = FetchType.LAZY) // 正确映射 Bancai 实体 @JoinColumn(name = "bancai_id", referencedColumnName = "id") private Bancai bancai; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Bancai getBancai() { return bancai; } public void setBancai(Bancai bancai) { this.bancai = bancai; } public Long getShuliang() { return shuliang; } public void setShuliang(Long shuliang) { this.shuliang = shuliang; } public Kucun(Integer id, Bancai bancai, Long shuliang) { super(); this.id = id; this.bancai = bancai; this.shuliang = shuliang; } public Kucun() { super(); // TODO Auto-generated constructor stub } } package com.kucun.data.entity; import java.util.List; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.UniqueConstraint; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; /** 木皮 @author Administrator */ @Entity @Table(name=“caizhi”, uniqueConstraints = { @UniqueConstraint(columnNames = “name”) }) @JsonIgnoreProperties({“hibernateLazyInitializer”, “handler”}) public class Mupi extends SimpleEntity { /** * 是否有油漆 */ private Boolean you; // 添加 OneToMany 映射 @OneToMany(mappedBy = "mupi1") // 指向 Bancai 中的 mupi1 字段 @JsonIgnore private List<Bancai> bancaisForMupi1; @OneToMany(mappedBy = "mupi2") // 指向 Bancai 中的 mupi2 字段 @JsonIgnore private List<Bancai> bancaisForMupi2; public List<Bancai> getBancaisForMupi1() { return bancaisForMupi1; } public void setBancaisForMupi1(List<Bancai> bancaisForMupi1) { this.bancaisForMupi1 = bancaisForMupi1; } public List<Bancai> getBancaisForMupi2() { return bancaisForMupi2; } public void setBancaisForMupi2(List<Bancai> bancaisForMupi2) { this.bancaisForMupi2 = bancaisForMupi2; } public Mupi() { super(); } public Boolean getYou() { return you; } public void setYou(Boolean you) { this.you = you; } } package com.kucun.data.entity; import java.util.Objects; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import com.fasterxml.jackson.databind.ObjectMapper; /** 用户 @author Administrator / @Entity @Table(name=“user”) public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; /* * 名字 / @Column(nullable=false) private String name; /* * 账号 / @Column(nullable=false) private String andy; /* * 密码 / @Column(nullable=false) private String pass; /* * 权限 */ @Column(nullable=false) private int role; public User() { super(); } public User(int id, String name, String andy, String pass) { super(); this.id = id; this.name = name; this.andy = andy; this.pass = pass; } public Integer getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAndy() { return andy; } public void setAndy(String andy) { this.andy = andy; } public String getPass() { return pass; } public void setPass(String pass) { this.pass = pass; } public int getRole() { System.out.println(role); return role; } public void setRole(int role) { this.role = role; } @Override public String toString() { return "{id:" + id + ", name:" + name + ", andy:" + andy + ", pass:" + pass + ", role:" + role + "}"; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; return Objects.equals(id, user.id) && Objects.equals(name, user.name) && Objects.equals(andy, user.andy)&& Objects.equals(role, user.role); //添加所有属性比较 } @Override public int hashCode() { return Objects.hash(id, name, andy,pass,role); } } package com.kucun.data.entity; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.OneToMany; @Entity public class Zujian extends SimpleEntity{ // 反向关联到产品组件 @OneToMany( mappedBy = "zujian", cascade = CascadeType.ALL, fetch = FetchType.LAZY ) private List<Chanpin_zujian> chanpins; public List<Chanpin_zujian> getChanpins() { return chanpins; } public void setChanpins(List<Chanpin_zujian> chanpins) { this.chanpins = chanpins; } } package com.kucun.data.entity; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToOne; import javax.persistence.Table; import com.fasterxml.jackson.annotation.JsonBackReference; import com.fasterxml.jackson.annotation.JsonManagedReference; /** 板材 @author Administrator */ @Entity @Table(name=“bancai”) public class Bancai { @Id private int id; @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = “caizhi_id”) // @JsonManagedReference // 标记为“主”关联方 private Caizhi caizhi; @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = “mupi1_id”) private Mupi mupi1; @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = “mupi2_id”) private Mupi mupi2; private Double houdu; @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = “kucun_id”, referencedColumnName = “id”) private Kucun kucun; public Kucun getKucun() { return kucun; } public void setKucun(Kucun kucun) { this.kucun = kucun; } public int getId() { return id; } public void setId(int id) { this.id = id; } public Caizhi getCaizhi() { return caizhi; } public void setCaizhi(Caizhi caizhi) { this.caizhi = caizhi; } public Mupi getMupi1() { return mupi1; } public void setMupi1(Mupi mupi1) { this.mupi1 = mupi1; } public Mupi getMupi2() { return mupi2; } public void setMupi2(Mupi mupi2) { this.mupi2 = mupi2; } public Double getHoudu() { return houdu; } public void setHoudu(Double houdu) { this.houdu = houdu; } public Bancai(int id, Caizhi caizhi, Mupi mupi1, Mupi mupi2, Double houdu) { super(); this.id = id; this.caizhi = caizhi; this.mupi1 = mupi1; this.mupi2 = mupi2; this.houdu = houdu; } public Bancai() { super(); } } package com.kucun.data.entity; import java.util.List; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.UniqueConstraint; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; /** 板材材质 @author Administrator */ @Entity @Table(name=“caizhi”, uniqueConstraints = { @UniqueConstraint(columnNames = “name”) }) @JsonIgnoreProperties({“hibernateLazyInitializer”, “handler”}) public class Caizhi extends SimpleEntity{ @OneToMany(mappedBy=“caizhi”) @JsonIgnore private List<Bancai> bancais; public Caizhi() { super(); } // 添加反向关联维护方法 public void addBancai(Bancai bancai) { bancais.add(bancai); bancai.setCaizhi(this); } // 添加移除方法 public void removeBancai(Bancai bancai) { bancais.remove(bancai); bancai.setCaizhi(null); } public List<Bancai> getBancais() { return bancais; } public void setBancais(List<Bancai> bancais) { this.bancais = bancais; } } package com.kucun.data.entity; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.UniqueConstraint; /** 产品类 @author Administrator */ @Entity @Table(name=“chanpin”, uniqueConstraints = { @UniqueConstraint(columnNames = “bianhao”) }) public class Chanpin { @Id private Integer id; // 关联订单产品 @OneToMany( mappedBy = “chanpin”, cascade = CascadeType.ALL, fetch = FetchType.LAZY ) private List<Dingdan_chanpin> dingdans; private String bianhao; @OneToMany( mappedBy = "chanpin", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true ) private List<Chanpin_zujian> zujians; // 添加/移除组件的辅助方法 public void addZujian(Chanpin_zujian zujian) { zujians.add(zujian); zujian.setChanpin(this); } public void removeZujian(Chanpin_zujian zujian) { zujians.remove(zujian); zujian.setChanpin(null); } // 添加/移除组件的辅助方法 public void addDingdan(Dingdan_chanpin dingdan) { dingdans.add(dingdan); dingdan.setChanpin(this); } public void removeDingdan(Dingdan_chanpin dingdian) { dingdans.remove(dingdian); dingdian.setChanpin(null); } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public List<Dingdan_chanpin> getDingdans() { return dingdans; } public void setDingdans(List<Dingdan_chanpin> dingdans) { this.dingdans = dingdans; } public String getBianhao() { return bianhao; } public void setBianhao(String bianhao) { this.bianhao = bianhao; } public List<Chanpin_zujian> getZujians() { return zujians; } public void setZujians(List<Chanpin_zujian> zujians) { this.zujians = zujians; } public Chanpin(Integer id, List<Dingdan_chanpin> dingdians, String bianhao, List<Chanpin_zujian> zujians) { super(); this.id = id; this.dingdans = dingdians; this.bianhao = bianhao; this.zujians = zujians; } public Chanpin() { super(); // TODO Auto-generated constructor stub } } 创建api 分别输出全部数据,下级实体类还是一个对象 对象中只有id属性
06-09
package com.example.kucun2.dataProcessing; import android.content.Context; import android.os.Handler; import android.os.Looper; import android.util.Log; import com.example.kucun2.entity.data.GsonFactory; import com.example.kucun2.entity.data.SynchronizableEntity; import com.example.kucun2.entity.data.SynchronizedList; import com.example.kucun2.function.MyAppFnction; import com.google.gson.Gson; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; /** * 数据加载处理器 * 职责: * - 从服务器加载全量/增量数据 * - 处理JSON解析和数据转换 * - 更新数据存储并建立关联 * - 提供加载状态回调 */ public class DataLoader { private static final String TAG = "DataLoader"; private final DataCore dataCore; private final DataAssociator associator; private final Gson gson = GsonFactory.createGson(); // 加载状态跟踪 private boolean isLoading = false; public DataLoader(DataCore dataCore, DataAssociator associator) { this.dataCore = dataCore; this.associator = associator; } /** * 从服务器加载全量数据 * @param context Android上下文 * @param callback 加载结果回调 */ public void loadAllData(Context context, Data.LoadDataCallback callback) { // 主线程检查 if (Looper.myLooper() != Looper.getMainLooper()) { throw new IllegalStateException("必须在主线程调用Data.loadAllData"); } // 防止重复加载 if (isLoading) { callback.onFailure(); return; } isLoading = true; dataCore.ensurePreservedObjects(); // 获取OkHttp客户端 OkHttpClient client = MyAppFnction.getClient(); // 构建请求 Request request = new Request.Builder() .url(MyAppFnction.getApiUrl("api/data/all")) .addHeader("Authorization", "Bearer " + Data.getUser().getToken()) .build(); // 异步执行请求 client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { isLoading = false; safeCallback(callback, false); Log.e(TAG, "数据加载失败", e); } @Override public void onResponse(Call call, Response response) { try { if (!response.isSuccessful()) { throw new IOException("Unexpected code: " + response); } String jsonData = response.body().string(); parseAndAssignData(jsonData, context, callback); } catch (Exception e) { isLoading = false; safeCallback(callback, false); Log.e(TAG, "数据处理失败", e); } } }); } /** * 加载增量更新数据 * @param lastSyncTimestamp 上次同步时间戳 * @param callback 加载结果回调 */ public void loadDeltaData(long lastSyncTimestamp, Data.LoadDataCallback callback) { // 构建增量请求 Request request = new Request.Builder() .url(MyAppFnction.getApiUrl("api/data/delta?since=" + lastSyncTimestamp)) .addHeader("Authorization", "Bearer " + Data.getUser().getToken()) .build(); // 执行请求(类似loadAllData) } /** * 解析JSON数据并更新到实体列表 */ private void parseAndAssignData( String jsonData, Context context, Data.LoadDataCallback callback ) { try { // 解析JSON数据 Data.AllDataResponse allData = gson.fromJson( jsonData, Data.AllDataResponse.class ); // 更新所有列表 updateAllLists(allData); // 建立实体关联 associator.automaticAssociation(); // 标记所有实体为已修改 Data.setAllEntitiesState(SynchronizableEntity.SyncState.MODIFIED); // 保存到本地存储 DataPersistence.saveToPreferences(context); // 回调成功 isLoading = false; safeCallback(callback, true); } catch (Exception e) { isLoading = false; safeCallback(callback, false); Log.e(TAG, "数据解析失败", e); } } /** * 更新所有实体列表 */ private void updateAllLists(Data.AllDataResponse allData) { updateList(dataCore.bancais, allData.bancais); updateList(dataCore.caizhis, allData.caizhis); updateList(dataCore.mupis, allData.mupis); updateList(dataCore.chanpins, allData.chanpins); updateList(dataCore.chanpin_zujians, allData.chanpin_zujians); updateList(dataCore.dingdans, allData.dingdans); updateList(dataCore.dingdan_chanpins, allData.dingdan_chanpins); updateList(dataCore.Dingdan_chanpin_zujians, allData.Dingdan_chanpin_zujians); updateList(dataCore.kucuns, allData.kucuns); updateList(dataCore.zujians, allData.zujians); updateList(dataCore.users, allData.users); updateList(dataCore.jinhuos, allData.jinhuos); } /** * 更新单个实体列表(合并策略) */ private <T extends SynchronizableEntity> void updateList( SynchronizedList<T> existingList, List<T> newList ) { if (newList == null) return; // 创建ID映射表用于快速查找 Map<Long, T> existingMap = new HashMap<>(); for (T entity : existingList) { existingMap.put(entity.getId(), entity); } // 处理新数据:更新或添加 for (T newEntity : newList) { T existing = existingMap.get(newEntity.getId()); if (existing != null) { // 合并更新 existing.mergeFrom(newEntity); } else { // 添加新实体 existingList.add(newEntity); } } // 处理删除:标记不在新数据中的实体为删除 Set<Long> newIds = newList.stream() .map(SynchronizableEntity::getId) .collect(Collectors.toSet()); Iterator<T> iterator = existingList.iterator(); while (iterator.hasNext()) { T entity = iterator.next(); if (!newIds.contains(entity.getId())) { entity.setState(SynchronizableEntity.SyncState.DELETED); } } } /** * 安全回调到主线程 */ private void safeCallback(Data.LoadDataCallback callback, boolean success) { new Handler(Looper.getMainLooper()).post(() -> { if (callback == null) return; if (success) callback.onSuccess(); else callback.onFailure(); }); } }package com.example.kucun2.function; import android.app.Application; import android.content.Context; import androidx.annotation.StringRes; import java.lang.reflect.Field; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.X509TrustManager; import okhttp3.OkHttpClient; public class MyAppFnction extends Application { private static MyAppFnction instance; public static OkHttpClient getClient() { return client; } private static OkHttpClient client; @Override public void onCreate() { super.onCreate(); instance = this; createSecureClient(this.getApplicationContext()); } public static String getStringResource(@StringRes int resId) { return instance.getString(resId); } public static String getStringResource(@StringRes int resId, Object... args) { return instance.getString(resId, args); } public static String getStringResource(String resourceType, String resourceName) { try { // 1. 构造完整的资源路径 String className = instance.getPackageName() + ".R$" + resourceType; // 2. 反射获取资源ID Class<?> resClass = Class.forName(className); Field field = resClass.getField(resourceName); int resId = field.getInt(null); // 静态字段获取资源ID // 3. 获取实际字符串资源 return instance.getResources().getString(resId); } catch (Exception e) { handleError(e); return null; // 或返回默认值 } } private static void handleError(Exception e) { // 异常处理逻辑 if (e instanceof ClassNotFoundException) { System.err.println("R类未找到: " + e.getMessage()); } else if (e instanceof NoSuchFieldException) { System.err.println("资源字段不存在: " + e.getMessage()); } else { e.printStackTrace(); } } public static void createSecureClient(Context context) { // 创建安全的SSL上下文 SSLContext sslContext = TLSUtils.createSSLContext(context, "selfsigned.crt"); SSLSocketFactory socketFactory = sslContext.getSocketFactory(); X509TrustManager trustManager = TLSUtils.createTrustManager(context, "selfsigned.crt"); client = new OkHttpClient.Builder() .sslSocketFactory(socketFactory, trustManager) .hostnameVerifier((hostname, session) -> { // 开发环境直接返回true,生产环境应验证域名 return true; }) .build(); } }
06-17
package com.example.kucun2.dataProcessing; import android.content.Context; import android.os.Handler; import android.os.Looper; import android.util.Log; import com.example.kucun2.entity.data.GsonFactory; import com.example.kucun2.entity.data.SynchronizableEntity; import com.example.kucun2.entity.data.SynchronizedList; import com.example.kucun2.function.MyAppFnction; import com.google.gson.Gson; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; /** 数据加载处理器 职责: 从服务器加载全量/增量数据 处理JSON解析和数据转换 更新数据存储并建立关联 提供加载状态回调 */ public class DataLoader { private static final String TAG = “DataLoader”; private final DataCore dataCore; private final DataAssociator associator; private final Gson gson = GsonFactory.createGson(); // 加载状态跟踪 private boolean isLoading = false; public DataLoader(DataCore dataCore, DataAssociator associator) { this.dataCore = dataCore; this.associator = associator; } /** 从服务器加载全量数据 @param context Android上下文 @param callback 加载结果回调 */ public void loadAllData(Context context, Data.LoadDataCallback callback) { // 主线程检查 if (Looper.myLooper() != Looper.getMainLooper()) { throw new IllegalStateException(“必须在主线程调用Data.loadAllData”); } // 防止重复加载 if (isLoading) { callback.onFailure(); return; } isLoading = true; dataCore.ensurePreservedObjects(); // 获取OkHttp客户端 OkHttpClient client = MyAppFnction.getClient(); // 构建请求 Request request = new Request.Builder() .url(MyAppFnction.getApiUrl(“api/data/all”)) .addHeader(“Authorization”, "Bearer " + Data.getUser().getToken()) .build(); // 异步执行请求 client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { isLoading = false; safeCallback(callback, false); Log.e(TAG, “数据加载失败”, e); } @Override public void onResponse(Call call, Response response) { try { if (!response.isSuccessful()) { throw new IOException("Unexpected code: " + response); } String jsonData = response.body().string(); parseAndAssignData(jsonData, context, callback); } catch (Exception e) { isLoading = false; safeCallback(callback, false); Log.e(TAG, "数据处理失败", e); } } }); } /** 加载增量更新数据 @param lastSyncTimestamp 上次同步时间戳 @param callback 加载结果回调 */ public void loadDeltaData(long lastSyncTimestamp, Data.LoadDataCallback callback) { // 构建增量请求 Request request = new Request.Builder() .url(MyAppFnction.getApiUrl(“api/data/delta?since=” + lastSyncTimestamp)) .addHeader(“Authorization”, "Bearer " + Data.getUser().getToken()) .build(); // 执行请求(类似loadAllData) } /** 解析JSON数据并更新到实体列表 */ private void parseAndAssignData( String jsonData, Context context, Data.LoadDataCallback callback ) { try { // 解析JSON数据 Data.AllDataResponse allData = gson.fromJson( jsonData, Data.AllDataResponse.class ); // 更新所有列表 updateAllLists(allData); // 建立实体关联 associator.automaticAssociation(); // 标记所有实体为已修改 Data.setAllEntitiesState(SynchronizableEntity.SyncState.MODIFIED); // 保存到本地存储 DataPersistence.saveToPreferences(context); // 回调成功 isLoading = false; safeCallback(callback, true); } catch (Exception e) { isLoading = false; safeCallback(callback, false); Log.e(TAG, “数据解析失败”, e); } } /** 更新所有实体列表 */ private void updateAllLists(Data.AllDataResponse allData) { updateList(dataCore.bancais, allData.bancais); updateList(dataCore.caizhis, allData.caizhis); updateList(dataCore.mupis, allData.mupis); updateList(dataCore.chanpins, allData.chanpins); updateList(dataCore.chanpin_zujians, allData.chanpin_zujians); updateList(dataCore.dingdans, allData.dingdans); updateList(dataCore.dingdan_chanpins, allData.dingdan_chanpins); updateList(dataCore.Dingdan_chanpin_zujians, allData.Dingdan_chanpin_zujians); updateList(dataCore.kucuns, allData.kucuns); updateList(dataCore.zujians, allData.zujians); updateList(dataCore.users, allData.users); updateList(dataCore.jinhuos, allData.jinhuos); } /** 更新单个实体列表(合并策略) */ private <T extends SynchronizableEntity> void updateList( SynchronizedList<T> existingList, List<T> newList ) { if (newList == null) return; // 创建ID映射表用于快速查找 Map<Long, T> existingMap = new HashMap<>(); for (T entity : existingList) { existingMap.put(entity.getId(), entity); } // 处理新数据:更新或添加 for (T newEntity : newList) { T existing = existingMap.get(newEntity.getId()); if (existing != null) { // 合并更新 existing.mergeFrom(newEntity); } else { // 添加新实体 existingList.add(newEntity); } } // 处理删除:标记不在新数据中的实体为删除 Set<Long> newIds = newList.stream() .map(SynchronizableEntity::getId) .collect(Collectors.toSet()); Iterator<T> iterator = existingList.iterator(); while (iterator.hasNext()) { T entity = iterator.next(); if (!newIds.contains(entity.getId())) { entity.setState(SynchronizableEntity.SyncState.DELETED); } } } /** 安全回调到主线程 */ private void safeCallback(Data.LoadDataCallback callback, boolean success) { new Handler(Looper.getMainLooper()).post(() -> { if (callback == null) return; if (success) callback.onSuccess(); else callback.onFailure(); }); } }package com.example.kucun2.function; import android.app.Application; import android.content.Context; import androidx.annotation.StringRes; import java.lang.reflect.Field; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.X509TrustManager; import okhttp3.OkHttpClient; public class MyAppFnction extends Application { private static MyAppFnction instance; public static OkHttpClient getClient() { return client; } private static OkHttpClient client; @Override public void onCreate() { super.onCreate(); instance = this; createSecureClient(this.getApplicationContext()); } public static String getStringResource(@StringRes int resId) { return instance.getString(resId); } public static String getStringResource(@StringRes int resId, Object... args) { return instance.getString(resId, args); } public static String getStringResource(String resourceType, String resourceName) { try { // 1. 构造完整的资源路径 String className = instance.getPackageName() + ".R$" + resourceType; // 2. 反射获取资源ID Class<?> resClass = Class.forName(className); Field field = resClass.getField(resourceName); int resId = field.getInt(null); // 静态字段获取资源ID // 3. 获取实际字符串资源 return instance.getResources().getString(resId); } catch (Exception e) { handleError(e); return null; // 或返回默认值 } } private static void handleError(Exception e) { // 异常处理逻辑 if (e instanceof ClassNotFoundException) { System.err.println("R类未找到: " + e.getMessage()); } else if (e instanceof NoSuchFieldException) { System.err.println("资源字段不存在: " + e.getMessage()); } else { e.printStackTrace(); } } public static void createSecureClient(Context context) { // 创建安全的SSL上下文 SSLContext sslContext = TLSUtils.createSSLContext(context, "selfsigned.crt"); SSLSocketFactory socketFactory = sslContext.getSocketFactory(); X509TrustManager trustManager = TLSUtils.createTrustManager(context, "selfsigned.crt"); client = new OkHttpClient.Builder() .sslSocketFactory(socketFactory, trustManager) .hostnameVerifier((hostname, session) -> { // 开发环境直接返回true,生产环境应验证域名 return true; }) .build(); } } <string name=“url”>https://192.168.31.177:3000</string> <string name=“url_all”>/app/all</string> <string name=“url_bancis”>/app/bancai/all</string> <string name=“url_caizhis”>/app/caizhi/all</string> <string name=“url_mupis”>/app/mupi/all</string> <string name=“url_dingdans”>/app/dingdan/all</string> <string name=“url_chanpins”>/app/chanpin/all</string> <string name=“url_zujians”>/app/zujian/all</string> <string name="url_chanpin_zujians">/app/chanpin_zujian/all</string> <string name="url_dingdan_zujians">/app/dingdan_zujian/all</string> <string name="url_dingdan_chanpins">/app/dingdan_chanpin/all</string> <string name="url_jinhuos">/app/jinhuo/all</string> <string name="url_add_bancai">/app/bancai/add</string> <string name="url_add_dingdan">/app/dingdan/add</string> <string name="url_add_chanpin">/app/chanpin/add</string> <string name="url_add_zujian">/app/zujian/add</string> <string name="url_add_caizhi">/app/caizhi/add</string> <string name="url_add_mupi">/app/mupi/add</string> <string name="url_add_dingdan_chanpin">/app/dingdan_chanpi/add</string> <string name="url_add_dingdan_zujian">/app/dingdan_zujian/add</string> <string name="url_add_chanpin_zujian">/app/chanpin_zujian/add</string> <string name="url_add_jinhuo">/app/jinhuo/add</string> <string name="url_login">/user/login</string>api url标准化,url规则url_{增删改查}_实体类名小写,获取全部url_实体类名小写+s
06-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值