JDO对开发的帮助有哪些 - 实例解析

JDO是什么意思?JDO使用实例 为此,我们需要定义一个JDO持久化类来处理Employee对象的持久化。JDO(Java Data Objects)是一种Java持久化技术,它提供了一种独立于数据存储方式的对象持久化机制,允许Java开发人员将对象保存到关系数据库或其他持久化存储中。当然,JDO还有很多其他功能和配置选项,比如查询语言、级联操作、乐观锁等等,这些可以通过JDO文档进行学习和了解。上面的代码创建了一个持久化管理器,并通过pm.makePersistent(emp)方法将Employee对象保存到数据库中。 阅读详情
JDO对开发的帮助有哪些 - 实例解析

(本文的版权属作者本人,欢迎转载,但必须注明出处和原作者)

1 权责划分:业务开发组和数据库管理组


对一个项目来讲,开发团队在逻辑上划分为两块:业务开发组和数据库管理组。两者各有特点,各有责任,但相互之间界限很清晰,不会有什么纠缠。下面用表格说明一下二者的区别:

人员构成
业务开发组 系统分析员、程序员。
数据库管理组 DBA、运行维护人员。一般一到两个人就可以,并可横跨多个项目

工作内容
业务开发组 设计数据类图,设计业务逻辑接口并用代码实现(一般在类似sessionbean的类中)
数据库管理组 通过数据类图映射数据表,一般只需在JDO自动生成的表结构上作少许调整

所需知识和工具
业务开发组 UML、Java、JSP、Ant。工具可为任何IDE。
数据库管理组 JDO原理、UML中的类图、连接池配置。工具包括PowerDesigner、数据库访问工具、具体使用的JDO产品的一些细节

相互的责任范?lt;BR>业务开发组 向数据库管理组提交数据部分 的UML实体类图,及某些细节(如某属性是否很长的字符串)。在对方配置好PersistenceManagerFactory连接池后在代码中调用。
数据库管理组 根据UML类图及业务开发组对某些细节的建议建立相应的数据库(基本上自动完成),在服务器上配置相应的JDO PersistenceManagerFactory(一个J2EE Connector,就象配置数据库连接池一样)

工作量
业务开发组 与业务相关,因为主要代码量在业务逻辑上
数据库管理组 一般情况下不大,但在从旧数据库中导入数据时可能需要一些功夫,不过是一次性的工作

涉及数据结构变动的功能变更时所需工作
业务开发组 一方面调整UML实体类图,提交给数据库开发组;另一方面根据新功能需求改写业务逻辑代码
数据库管理组 根据新的UML实体类图调整数据库结构(有的JDO产品可自动完成)。服务器配置不变。


由于面向数据库管理组的工作内容比较简单,只是量的问题,下面的介绍就尽量不涉及数据库管理组的工作,而只面向业务开发组。

2 UML实体类图


UML实体类图是项目中涉及到数据的部分,这些数据不会随着程序中止而丢失,称作可持续的(Persistent),所有数据库中的数据都是可持续的。
而我们在设计的时候,最开始应该分析出系统有哪些实体类(即可持续的数据类),从而画出实体类图。在这个最初级的类图上面,可以不包含任何属性,但必须包含实体类之间的关系,这样才能一眼看出系统的大概轮廓。
下面就是一个简单的示范实体类图,是一个论坛中的主要实体的关系图。

简单地说,项目可以说是一些具有相互关系的实体类加上处理业务逻辑的控制类,以及输入/输出数据的边界类组成,另外可能附加一些接口或特殊服务,如短信/邮件发送或面向第三方的数据访问接口等等。
有了上面这个图,DBA就比较清楚数据库中会有什么样的数据表,表之间如何关联了。但数据库中的表与实体类并不是一一对应的。比如对实体类图中的某个多多对应关系,数据库中必须有一个额外的表来对应,有些实体的某部分属性可能会放在另一个额外表中以加强性能。
下一步就是在这个图的基础上为实体类添加属性,然后给每个属性加上访问器(accessors,即getXXX()/isXXX()和setXXX()等),以及一些必须的方法(比如getAge(),通过当前日期和生日得出年龄)。 这样,才成为一个完整的实体类图。下图就是一个增添了普通属性的实体类图。

接下来,加入对普通属性的访问器方法,可能再给加一个Member.getAge()方法,这个实体类图就算是完成了。这些过程都比较简单,并且有很多工具可以自动完成,这里不再多说。
有一点要着重说明的是,对实体类,只要给出这个图,然后用工具生成对应的Java类代码,这些类的代码就算是完成了,以后不用再在其中写代码了。

3 透明的存储


对开发人员来说,主要工作集中在业务逻辑的实现上,这就需要写一些控制类,来实现这些逻辑。这些控制类一般可以XxxSession的方式来命名,表示面向某一类使用者的控制类,比如MemberSession,完成会员登录后的一些功能;AdminSession用于完成管理员登录后的一些功能。
在这些控制类中的一个方法中,只需要通过JDO规范的接口类(javax.jdo.*)来获取对前面的实体的访问,从而完成业务功能。一个典型的方法如下:

MemberSession的发表主题贴的方法:

public Topic postTopic(String title,String content, String forumId) {
//业务逻辑过程开始
javax.jdo.PersistenceManager pm = getPersistenceManagerFactory().getPersistenceManager();
pm.currentTransaction().begin();

//先生成一个主题,设置基本属性
Topic topic = new Topic();
topic.setTitle(title);
topic.setContent(content);
topic.setPostTime(new Date());

//获取相关的论坛和当前登录的会员
//下面用到的this.logonMemberId是本MemberSession对象生成时必须提供的会员标识。
//本MemberSession对象一般是在登录的时候生成的。
Forum forum = (Forum)pm.getObjectById(pm.newObjectIdInstance(Forum.class,forumId));
Member author = (Member)pm.getObjectById(pm.newObjectIdInstance(Member.class, this.logonMemberId));

//设置该主题的论坛和作者
topic.setForum(forum);
topic.setAuthor(author);

//标记为需要存储
pm.makePersistent(topic);

//顺便更改论坛和作者的一些相关属性
forum.setTopicCount(forum.getTopicCount()+1);
author.setPostCount(author.getPostCount()+1);

//业务逻辑过程完成
pm.currentTransaction().commit();
pm.close();
}

这样,这个方法就算写完了。我们可以看到,只要将与实体类相关的代码放在pm.currentTransaction()的开始和提交之间就可以了。
唯一中间需要与JDO打交道的就是对新生成的对象(topic)需要调用一下pm.makePersistent(),但实际上在很多情况下,只要从pm中取出的对象指向这个对象(比如:author.getPostTopics().add(topic)),就根本不需要这条语句(当然写上也没错),因为pm会根据可达性(Reachability)的原则将当前已经在数据库中的对象能直接或间接指到的新生成的那些对象都存储起来。
以上的代码说明了我们不必对每个发生变化的对象调用更新函数,因为JDO的pm会自动跟踪这些变化,并将确实发生改变的对象同步到数据库。这就是“透明的存储”。

4 灵活的查询:JDOQL vs SQL


JDOQL是JDO中使用的查询语言,是对象式的查询语言,很象OQL,也很象EJBQL,但没有EJBQL那种只能静态存在的缺点。
对象式查询语言的优点有很多文章都有介绍,这里不再说明。只说明一点:JDOQL完全基于UML实体类图,不必理会具体数据库中的任何内容。
下面举一些例子,说明这种灵活性。

4.1 例:查找某作者发表过贴子的所有论坛

我们给出的参数只有作者的姓名,希望得到的是所有的他发表过主题或回复过主题的论坛。我们需要这样的JDOQL条件:首先查询的目标是Forum类,然后是JDOQL的过滤串
this == _topic.forum && (_topic.author.name == “<作者姓名>” || _topic.contains(_reply) && _reply.author.name == “<作者姓名>”)
然后,声明用到的变量:Topic _topic; Reply _reply;
再执行SQL即可。一般的JDO产品会将这个查询尽可能优化地翻译为:

select a.<可预定义的最常用字段组> from FORUM a, TOPIC b, REPLY c, MEMBER d

where a.FORUM_ID = b. FORUM_ID and (b.MEMBER_ID = d. MEMBER_ID and d.NAME=’<作者姓名>’ or b.TOPIC_ID = c. TOPIC_ID and c.MEMBER_ID = d.MEMBER_ID and d.NAME = ‘<作者姓名>’)

从上面,我们可以看到,JDOQL无论在可读性还是可维护性上都远远好于SQL。我们还可以将作者姓名作为一个绑定参数,这样会更简单。
如果直接操作SQL的话会变得很麻烦,一方面要注意实体类中的属性名,一方面又要注意在数据库中的对应字段,因为多数情况下,两者的拼写由于各种因素(如数据库关键字冲突等)会是不一样的。
从这个例子扩展开去,我们可以进一步:

4.2 例:查找某作者发表过贴子的所有论坛中,总贴数大于100并且被作者收入自己的收藏夹的那些论坛

很简单,将过滤串这样写:
this == _topic.forum && (_topic.author == _author || _topic.contains(_reply) && _reply.author == _author) && _author.name == ‘<作者姓名>’ && postCount > 100 && _author.favoriteForums.contains(this)
这一次多了一个用到的变量:Member _author。其底层的SQL大家可以自己去模拟。

5 长字符串


我们经常会遇到用户输入的某个信息文字串超出了规定的数据字段的大小,导致很麻烦的处理,尤其是一些没有必要限制长度的字符串,比如一篇主题文章的内容,有可能几万字,这迫使我们将其分作很多子记录,每条子记录中放一部分。所有这些,都使我们的代码量加大,维护量加大。
现在有了JDO,我们的代码就简单多了,我们可能尽量利用JDO提供的透明存储功能,通过一些简单的工具类实现:原理是将其分割为字符串子串。

package jdo_util;
import java.util.*;

public class StringHelper {
public static List setLongString(String value) {
if(value == null) return null;
int len = value.length();
int count = (len+partSize-1)/partSize;
List list = new ArrayList(count);
for(int i = 0; i < count; i++) {
int from = i*partSize;
list.add(value.substring(from,Math.min(from+partSize,len)));
}
return list;
}

public static String getLongString(List list) {
if(list == null) return null;
StringBuffer sb = new StringBuffer();
for(Iterator itr = list.iterator(); itr.hasNext(); ) sb.append(itr.next());
s = sb.toString();
return s;
}

private static int partSize = 127; //字符串片断的大小。针对不同的数据库可以不同,如Oracle用2000
}

有了这个类以后,我们只需要将Topic.content的类型换成List,而其访问器的接口不变,仍是String,只是内容变一下:(并在JDO描述符中指明该List的元素类型是String)

public class Topic {
…
List content; //原先是String类型
…
public String getContent() {
return StringHelper.getLongString(content);
}

public void setContent(String value) {
content = StringHelper.setLongString(value);
}
}

这样,就解决了长字符串的问题,而其它相关的代码完全不需要改,这就支持了无限长的主题内容。
最后,唯一的缺陷是对内容进行关键字查询的时候需要将
content.startsWith(‘%<关键字>’)
变为
content.contains(s) && s.startsWith(‘%<关键字>’)
并且,可能查询结果不太准(比如正好跨越两个子串部分)。庆幸的是,一般这种对很长的字符串字段的查询需求不是太多。
需要说明的是,采用传统的SQL同样也会需要对拆分的字符串进行额外的查询,并具有同样的缺点。
另外,这个功能需要JDO产品支持规范中的一个可选选项:javax.jdo.option.List,主要的几个JDO产品都支持。比如KodoJDO和JDOGenie。

6 资源回收:pm.close()


我们采用传统SQL写代码时,最危险的就是资源释放问题,这在基于WEB的应用中尤其重要。因为与JDBC相关的资源不是在Java虚拟机中分配的,而是在系统底层分配的,Java的垃圾回收机制鞭长莫及,导致系统内存慢慢耗光而死机。
在JDBC中需要主动释放的资源有:Connection、Statement、PreparedStatement、ResultSet,在每个对这些类型的变量赋值的时候,都必须将先前的资源释放掉。无疑是一件繁琐而又容易被忽略的事情。
在JDO中,事情变得简单多了,所有的资源在pm.close()的时候会自动释放(除非JDO产品增加了一些对PreparedStatement和ResultSet的Cache),这是JDO规范的要求。因此,只要我们记住在对实体类处理完毕时调用pm.close()就行了。比如下面的代码:

PersistenceManager pm = null
try {
pm = getPersistenceManagerFactory().getPersistenceManager();
//做一些数据类的处理工作

} finally{
pm.close();
}


有些人可能就是不喜欢调用它,觉得烦,因为每次要用时都要打开一个PM,而用完时都要关闭,如果JDO产品没有PM连接池的话,性能可能受到影响。这样,我们可以利用下面的继承java.lang.ThreadLocal的工具类完成这一点:

public class PersistenceManagerRetriever extends ThreadLocal {
/**
* 根据配置信息初始化一个PersistenceManager获取器
* @param p
*/

public PersistenceManagerRetriever(java.util.Properties p) {
pmf = JDOHelper.getPersistenceManagerFactory(p);
}

/**
* 获取相关的PersistenceManagerFactory
* @return 一个PersistenceManagerFactory对象
*/

public PersistenceManagerFactory pmf() {
return pmf;
}

/**
* 获取一个与当前线程相关的PersistenceManager
* @return 一个PersistenceManager对象
*/

public PersistenceManager pm() {
return (PersistenceManager)get();
}

/**
* 释放所有与本线程相关的JDO资源
*/

public void cleanup() {
PersistenceManager pm = pm();
if(pm == null) return;

try {
if(!pm.isClosed()) {
Transaction ts = pm.currentTransaction();
if(ts.isActive()) {
log.warn("发现一个未完成的Transaction ["+pmf.getConnectionURL()+"]!"+ts);
ts.rollback();
}
pm.close();
}

} catch(Exception ex) {
log.error("释放JDO资源时出错:"+ex,ex);

} finally {
set(null);
}
}

public Object get() {
PersistenceManager pm = (PersistenceManager)super.get();
if(pm == null || pm.isClosed()) {
pm = pmf.getPersistenceManager();
set(pm);
if(log.isDebugEnabled()) log.debug("retrieved new PM: "+pm);
}
return pm;
}

public static final Logger log = Logger.getLogger(PersistenceManagerRetriever.class);
private PersistenceManagerFactory pmf;
}

这样,只要在一个线程中(比如一次页面请求),在所有的需要PM的地方,都只需直接调用

persistenceManagerRetriever.pm();

即可,并且,只在最后用完后才调用一次persistenceManagerRetriever.cleanup()以关闭它。

这个persistenceManagerRetriever可以在某个系统类的初始化代码中加入:

PersistenceManagerRetriever persistenceManagerRetriever = new PersistenceManagerRetriever(properties);


而关闭当前线程相关的PM的语句(persistenceManagerRetriever.cleanup())可以配置一个JspFilter来完成它,比如:

public static class JspFilter implements javax.servlet.Filter {
public void doFilter(
javax.servlet.ServletRequest request,
javax.servlet.ServletResponse response,
javax.servlet.FilterChain chain)
throws javax.servlet.ServletException,java.io.IOException {
try {
chain.doFilter(request,response);
} finally {
if(pmRetriever != null) pmRetriever.cleanup();
}
}
public void init(javax.servlet.FilterConfig filterConfig) throws javax.servlet.ServletException {}
public javax.servlet.FilterConfig getFilterConfig() { return null; }
public void setFilterConfig(javax.servlet.FilterConfig fc) {}
public void destroy() {}
}

然后我们将其配置在WebApp的描述符中:

<filter>
<filter-name>jdo_JspFilter</filter-name>
<filter-class>…xxx.jdo_util.JspFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>jdo_JspFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>

这样,我们在JSP中的代码更简单:


…

persistenceManagerRetriever.pm().currentTransaction().begin();


//调用一些处理业务逻辑的XxxSession.someMethodThatUsesPM()方法,这些方法中直接用persistenceManagerRetriever.pm()来取得PM。

persistenceManagerRetriever.pm().currentTransaction().commit();

不用处理异常,JspFilter自会处理。

7 ID与对象模型



对象标识字段,实际上只是一个数据库范畴的字段,在对象模型中实际上是不需要这些属性的。也就是说,在Java应用中,一个对象的标识就是在内存中的地址,不并是这个对象本身的属性,因为根据这个内存地址就可以唯一地确定这个对象。比如一个编辑矢量地图的Java程序,从文件中读入各个地图元素(对象)后,这些对象就有了一个唯一的内存地址,所以不需要给每个对象加一个类似“ID”之类的属性并写入文件。
JDO也采用了这样的概念,ID独立于对象之外,并不属于对象的一部分。前面的论坛实体类图中我们可以看到,每个类中都没有类似“id”之类的属性。那么,JDO怎样控制与数据库中的主键的对应呢?这就是两个常用的工具类方法:
Object PersistenceManager.getObjectId(Object obj)
Object PersistenceManager.getObjectById(Object obj, boolean validate)

这样,可以随时获得某个实体对象的ID,也可以在任何时候通过一个ID找出该对象。第一个方法还可以用javax.jdo.JDOHelper.getObjectId()代替。
JDO规范建议的模式中,这些ID都是由JDO产品自动生成的,项目应用中只在需要传递对象的引用的时候才使用,比如在两个页面间传送。并且,这些ID类都是可以与String互转的,这就方便了JSP间的传递。这种由JDO产品来控制的ID叫做datastore identity,在数据表中的字段名一般是“JDO_ID”。
如果实在是想自己控制对象在数据库中的ID,JDO也提供用户自定义的ID,这时,该ID作为对象的一个属性存在,可以是任何类型,int, Date, String, 或其它自定义的复合类型(如两个属性合起来作ID)。这种类型的ID叫做application identity。
就个人而言,我建议在新的项目中采用datastore identity,这样可省下很多时间。而在实体类中,也可以写一些替代的方法来保持与application identity保持兼容,如:

public class SomePersistentClass {
…
public String getId() {
return JDOHelper.getObjectById(this).toString();
}

public static SomePersistentClass getById(String id) {
PersistenceManager pm = persistenceManagerRetriever.pm();
return pm.getObjectById(pm.newObjectIdInstance(SomePersistentClass.class, id));
}
}

这种方式对两种类型的ID都有效。注意,这个类本身有这两个方法,但并没有一个ID属性。

8 缓冲与Optimistic Transaction



缓冲是JDO中的一个亮点。虽然JDO规范并没有严格要求一个JDO产品必须实现什么样的缓冲,但几乎每一个JDO产品,尤其是商业化产品,都有比较完善的缓冲体系,这个体系是不同的JDO产品相互竞争的重点之一。
主要的JDO产品包含下列缓冲:
1. PM连接池。对PersistenceManager进行缓冲,类似JDBC连接池,在调用pm.close()的时候并不关闭它,而是等待下一次调用或超时。
2. PreparedStatement缓冲。如果JDO底层发现一个JDOQL语句与前面用过的某句相同,则不会重新分析并生成一个新的PreparedStatement,而是采用缓冲池中的已有的语句。对PreparedStatement的缓冲也是JDBC3.0规范中的一项功能。而JDO底层发现如果配置的是符合JDBC3.0规范的驱动时,会采用驱动的缓冲,否则采用自己的缓冲。
3. ResultSet缓冲。这种缓冲的实现的JDO产品不多,目前好象只有KodoJDO 2.5.0 beta实现了。其机制是如果第二次请求执行同样JDOQL语句、同样参数的查询时,JDO底层从上一次执行结果中取出该集合,直接返回,大大增强性能。不过比较耗资源,因为是采用JDBC2.0中的ScrollableResultSet实现。

一般我们在对数据库进行更新操作时,都会对数据库进行锁定操作,设定不同的隔离级别,可以完成不同程度的锁定,比如锁记录、锁字段、锁表、锁库等等。而JDO中可以在具体JDO产品的厂商扩展(Vendor Extension)标记中设定。另外,JDO规范还提供了一种对数据库完全没有锁定的方式:javax.jdo.option.OptimisticTransaction,它是一项可选选项,也就是说,并不强制JDO厂商实现它,不过主要的几个厂商的JDO产品都实现了这个功能。
OptimisticTransaction的机制原理是:在每个对象的数据库记录中增加一个交易控制字段,然后所有的对象更改在Java虚拟机的内存中完成,当提交的时候,会检查每个被改过的对象的在从数据库中取出后是否被其它外部程序改过,这就是通过这个控制字段完成的。一般这个字段的实现方式有以下几种:
1. 存放最近一次更改的时间,字段名多取作“JDO_LAST_UPDATE_TIME”
2. 存放历史上被更改过的次数,字段名多取作“JDO_VERSION”

在OptimisticTransaction的一次Transaction中,JDO底层不会对数据库进行锁定,这就保证了时间跨度较长的transaction不会影响其它线程(请求)的执行,只是如果更新操作比较多,访问量又比较大的话,Transaction提交失败的的几率也会相应变大。

9 JDBC2.0和JDBC3.0


JDO只是一种对象级的包装,是建立在JDBC的基础上的,两者不能相互替代。实际上,JDBC的规范从1.0到2.0,再到3.0,一直在做功能和性能方面的改进。
JDO产品当然不会放过这些,一般的JDO产品,会检测底层配置的JDBC驱动是符合哪个规范,并会尽量采用驱动本身的功能来实现具体的操作。对代码开发人员来说,我们大多数情况下只能掌握JDBC1.0的操作,和少量的2.0的操作,只有一些很精通JDBC的高手才会用到JDBC3.0中的高级功能。因此,采用JDO也可以帮助我们在不了解JDBC3.0规范的情况下提高性能和效率。
换句话说,JDBC技术本身就是一件很复杂的东西,要想优化性能的话,很多JDBC技术和数据库技术是需要使用的,比如inner join, left/right outer join, Batch update,等等。这些对开发人员的技术要求很高,一方面要精确理解每种技术的应用范围和实际使用的注意事项,另一方面代码也会比较复杂。因此,既然有众多的有经验的JDO厂商在做这些事情,我们又何必再花功夫呢?

以上我介绍了JDO对我们的数据库项目开发的比较明显的几个好处,以后的文章中,我会继续写关于JDO使用中的概念性的问题和具体JDO产品的配置与使用,以及一些技巧。
本文的版权属于笔者本人,但欢迎转载,前提是注明出处和原作者。另外,欢迎在我的专栏中查看我的另几篇文章,并提出宝贵意见!
全面了解JDO数据库编程 全面了解JDO数据库编程,包括官方文档,API等详细说明 立即下载

相关推荐

nnDetection实战:手把手教你用Python在自家电脑上跑通第一个肺结节检测模型

本文详细介绍了如何使用nnDetection框架在普通电脑上实现肺结节检测模型的搭建与运行。从环境配置、数据预处理到模型训练与推理,手把手教你完成医学图像检测的全流程,特别适合初学者入门医学AI领域。

weixin_32377497的博客 330

JDO快速入门

<br />JDO快速入门Java数据对象(Java Data Objects,JDO)是一个应用程序接口(API),它是Java程序员能够间接地访问数据库,也就是说,不需使用直接的结构化查询语言(SQL)语句。JDO是作为Java数据库连接(JDBC)的一个补充来介绍的,而JDBC是一个支持使用SOL语句对流行的数据库程序进行访问的接口。有了 JDO,程序员就可以使用类来定义数据对象,然后支撑程序就会根据类的定义来管理对给定数据库的实际的数据访问了。  <br /><br />      JDO是以Sun

liuzhigang1237的专栏 1万+

数字IC设计之时序分析基础概念汇总

时序分析主要有两种办法:静态时序分析: (static timing analysis,STA),是遍历电路存在的所有时序路径,根据给定工作条件(PVT)下的时序库.lib文件计算信号在这些路径上的传播延时,检查信号的建立和保持时间是否满足约束要求,根据最大路径延时和最小路径延时找出违背时序约束的错误。

weixin_45230720的博客 5607

kodojdo指南第七章

第七章 PersistenceManagerFactoryPersistenceManagerFactory 创建PersistenceManager实例以供应用程序使用.它允许你配置数据连接方式和指定所创建的PersistenceManager的默认设置.你也可以通过它在编程中获知你当前厂商支持的JDO选项.使你能使用产品的全部特性来最优化你的程序.7.1. 获得Persiste

WalkingWithJava 1382

UE4游戏开发:GameInstance与GameMode的实战应用与避坑指南

本文深入解析了UE4中GameInstance与GameMode的核心差异与实战应用。GameInstance作为贯穿游戏进程的全局单例,负责跨关卡数据持久化与系统管理;而GameMode则定义特定关卡内的游戏规则与逻辑,随关卡加载销毁。文章通过数据存储、动态模式切换及网络游戏等场景,提供了清晰的应用指南与常见避坑方案,帮助开发者构建更健壮的UE4游戏架构。

kubernetes8ctl的博客 230

别再为电路自激发愁了:手把手教你用吸波材料搞定微波腔体谐振(附HFSS仿真设置)

本文详细解析了微波腔体谐振问题的工程解决方案,重点介绍了吸波材料的选型、安装工艺及HFSS仿真设置。通过实际案例和计算工具,帮助射频工程师有效抑制腔体自激,提升系统稳定性。特别适用于35GHz毫米波雷达等高频电路设计场景。

weixin_42662293的博客 383

JDO示例 - JPOX

JDO示例- JPOX(ALin 2006-12-27 00:28) 第一部分:相关概念[JDO的实现版本之一:JPOX]JPOX是JDO的一个具体实现版本。其官方主页为:http://www.jpox.org/index.jspJDO现在是2.0版,以前的1.0版的Sun官方有具体的实现,不过后来移交给Apache了,所以Apache网站上也有JDO的实现。这种标准的AP

e_ville的专栏 8789

tun虚拟网卡没有安装解决之道

目录 描述 过程 一、sstap 会提示你虚拟网卡没有安装; 二、还有会是这样的:病毒和威胁防护中无法启动;引擎不可以用等等,以及会显示需要IT管理员去处理;等等报错的信息; 系统升级地方会显示:Windows Defender Antivirus 的安全智能更新 - KB2267602 (版本 1.305.2147.0) - 错误 0xc8000442 Windows Defender报错; 三、还有就是会出现你搜自己家的WIFI搜不到,电脑端都不会显示WIFI名字; 解决方...

战神/calmness的博客 1万+

Java数据对象(JDO)快速入门

  JDO有一个充满活力的社区。所以如果你正在为你的POJO寻找持久化解决方案,JDO是一个通过JCP项目开发的标准。JDO为POJO持久化提供了一个丰富和具有全部特征的JSR规范,并且很多开发商正在提供竞争性的JDO实现。EJB3.0,正由Sun微系统和来自于不同的持久化开发商的专家创建,将是未来持久化模型的选择。  持久化Java技术对象到任何关系型数据库都是一项富有挑战性的任务,因为它必须潜

银狐的专栏 3625

【YOLO系列】YOLOv4详解:模型结构、损失函数、训练方法及代码实现

摘要:YOLOv4在目标检测领域实现了精度与速度的平衡,通过CSPDarknet53骨干网络、SPP+PANet特征融合及CIoU损失函数等创新,在MS COCO数据集达到65.7% AP50,V100显卡实现62FPS实时检测。核心优化包括Mosaic数据增强、自对抗训练和解耦头结构,显著提升小目标检测和遮挡场景鲁棒性。代码实现采用CSP模块和SPP多尺度池化,兼顾计算效率与检测性能,为工业落地提供高效解决方案。(149字)

一碗白开水一 1358

如何通过单步调试的方法,找到 SAP Gateway 到底把 Fiori 应用发送的 OData 请求,投递到哪一台 ABAP 后台服务器了?

这是一个 Count 请求,得到服务器响应的数据是 204,这个 204 会以数字的形式,显示在 Fiori Launchpad tile 上。那如果当前 Gateway 系统可以连接到多台 ABAP 后台服务器,比如下图所示,可以连接 SAP S/4HANA,ERP 或者 SAP CRM,我怎么知道 SAP UI5 应用上显示的数据,到底来自哪一台 ABAP 后台服务器呢?,就是上图 ABAP 调试器里断点停留的位置,即 SAP Frontend 服务器,通过 RFC 将 OData 请求投递给。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 642

JDO对开发的帮助有哪些-实例解析

<!--google_ad_client = "pub-2947489232296736";/* 728x15, 创建于 08-4-23MSDN */google_ad_slot = "3624277373";google_ad_width = 728;google_ad_height = 15;//--><script type="text/javascript"

zgqtxwd的专栏 440

实战:利用 Agent Harness 自动化 PPT 制作

本文将带你从零开始,用轻量级Agent编排框架,结合主流大模型(GPT-4o、通义千问、文心一言等),搭建一套全自动化的PPT生成工作流:从用户输入自然语言需求,到需求解析、大纲生成、内容填充、数据匹配、排版美化、导出成品,全程不需要手动操作,最快10分钟就能产出符合要求的PPT。我们不会讲晦涩的Agent理论,所有步骤都有可直接运行的代码示例,哪怕你只有基础的Python语法基础,也能跟着一步步做出能用的自动PPT工具。

AI Agent Harness Engineering 569

jdo是什么

翻译:2002/09/18原文:http://www.libelis.com/inner-index.jsp?next=jdo.htmlJDO是Java对象持久化的新的规范。JDO经SunJava Community Process认定。一、历史JDO是对象持久化工作的综合成果,试图提供一个对象持久化的完全版本。JDO同时继承于ODMG(对象数据管理小组,标准化对象数据库的一个独立委员会)和对

Eric.Jonah! 3450

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

JDO

  如何用JDO开发数据库应用 (本文的版权属作者本人,欢迎转载,但必须注明出处和原作者) 本文将介绍如何使用Sun公司的最新《Java Data Objects 》规范来进行基于数据库的简单应用程序的开发,从而使读者对JDO有一个直接的感性的认识,为更深入的开发作铺垫,同时也希望抛砖引玉,让更多的富有经验的高手也参与到推广JDO的进程中来,为读者提供更多更精彩的文章! 1. JDO是何方神圣,

§为艺术而技术§ 1702

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

JDO持久框架——DataNucles

1. JDO框架简介 Java数据对象(Java Data Objects,JDO)是一个应用程序接口(API),它是Java程序员能够间接地访问数据库,也就是说,不需使用直接的结构化查询语言(SQL)语句。JDO是作为Java数据库连接(JDBC)的一个补充来介绍的,而JDBC是一个支持使用SOL语句对流行的数据库程序进行访问的接口。有了 JDO,程序员就可以使用类来定义数据对象,然后支撑程序就...

旗鼓相当的对手的博客 3588

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

JDO 是什么?

原文:http://www.libelis.com/inner-index.jsp?next=jdo.html转载网址:http://ijsp.net/2/2003-3/28/0000359.shtmlJDO是Java对象持久化的新的规范。JDO经SunJava Community Process认定。 历史JDO是对象持久化工作的综合成果,试图提供一个对象持久化的完全版本。JDO同

暮色飞扬 1757

JDO+JSP2.0开发Web应用向导 - 开发篇

JDO+JSP2.0开发Web应用向导 – 开发篇  在前面读者看到的本文的《配置篇》中,我们介绍了用于本文中的基于JDO的WebApp开发的各种环境配置,尤其是本文选用的JDO产品:JDOGenie。JDOGenie的特点就是图形配置工具功能强大,方便使用,学习JDO非常容易。  我们前面已经完成了一个基本的数据对象模型,并且,每个数据类的属性都用getter/setter进行了封装

sun2bin的专栏 4493

如何用JDO开发数据库应用

本文将介绍如何使用Sun公司的最新《Java Data Objects 》规范来进行基于数据库的简单应用程序的开发,从而使读者对JDO有一个直接的感性的认识,为更深入的开发作铺垫,同时也希望抛砖引玉,让更多的富有经验的高手也参与到推广JDO的进程中来,为读者提供更多更精彩的文章! 1. JDO是何方神圣,难道是ADO的翻版? 本节对稍熟悉JDO一点的读者来说,可能算是老生常谈,一堆垃圾,不

seinbar的专栏 1584

JDO学习笔记之Sun JDO参考实现篇

  这一段时间在学习JDO,使用的学习资料是孙宾翻译的《Java Data Objects 第一章 初步概览》,以及清华大学出版社出版的《JDO核心技术》。说实话,这两份学习资料的确很好,但在学习过程中还是遇到了问题,经历了不少痛苦,这里写出来供大家一笑。  首先,我想对类库进行一下说明。孙宾翻译的《Java Data Objects 第一章 初步概览》(以下简称《JDO》)中所涉及的jdo.ja

我是Didizyp 2923

JDO之前世今生

JDO之前世今生1 Java与数据库应用,JDBCJava发明以来,在短短的几年之间,迅速占领了从桌面应用(J2SE)到服务器(J2EE),再到小型设备嵌入式系统(J2ME)的应用开发市场,其语言吸取了SmallTalk的一切皆对象的理念,摆脱了C++的历史累赘,简洁、自由的风格赢得了很多开发者的喜爱。从JDK1.1开始,Java成为实用的语言,而不是被人观望的新品秀;再经过JDK1.2的

sun2bin的专栏 2583
上一篇: 一名纽约女技术员的JDO经验
下一篇: 一个JDO的成功案例分析
sun2bin
博客等级 码龄25年 1粉丝 15原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值