当前位置: 首页 > 编程日记 > 正文

清瘦的记录者: 一个比dbutils更小巧、好用的的持久化工具

https://gitee.com/bitprince/memory

1. 概述

1.1 连接、语句和结果集

从JDBC的规范上看,其对数据访问层有相当简洁的抽象:1、连接(connection) 2、语句(statement)、3结果集(result set)。我们对数据库做的事情无非:连接数据库,执行语句,拿到结果

因此,持久化的工具的目的就不言自明了:进一步简化连接的管理、语句的执行、结果集提取等操作。下面从获取结果集、管理连接、语句预处理等3方面逐一阐述工具做了哪些事情。

这里提一句,Memory在设计与实现上,都借鉴了Dbutils,其相对于hibernate,mybatis这些庞然大物,已经是一个极其小巧的工具。 但是Memory的类和接口更少(不超过10个),体积更小(只有二十几K),数目和体积都约为dbutils的1/3,却添加了非常实用的功能:

  • 将简单的POJO对象直接持久化到数据库中;
  • 打印运行时出错的SQL语句,其可以直接拷贝到数据库客户端上进行调试;
  • 直截了当的分页查询。

1.2 获取结果集

获取结果集,就是把ResultSet转换为目标数据结构,这里使用T(泛型)泛指各种数据结构。我们定义一个接口类来表示这件事情:

public interface ResultSetHandler<T> { T handle(ResultSet rs) throws SQLException; } 

在实际应用中,结果集是某张表或视图的一行或多行数据时,常使用BeanHandler、BeanListHandler或JSONObjectHandler、JSONArrayHandler进行处理,结果集是某一列的一行或多行数据时,使用ColumnHandler、ColumnListHandler进行处理。

1.3 连接的管理

将连接的交给外部的数据源(DataSource)进行统一管理。比如使用Tomcat容器自带的数据源。   在Tomcat的context.xml文件配置数据源xxxxx:

<?xml version="1.0" encoding="UTF-8"?> 
<Context>
<Resource name="jdbc/test" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8" username="root" password="root" maxActive="300" maxIdle="30" maxWait="3000" validationQuery = "SELECT 1" testWhileIdle = "true" testOnBorrow = "true" timeBetweenEvictionRunsMillis = "3600000" minEvictableIdleTimeMillis = "18000000" /> </Context> 

在代码中,采用懒加载单例模式加载数据源并实例化:

public class MemoryFactory {private MemoryFactory() { } private static class SingletonHolder { public static final Memory MEMORY = new Memory(getDataSource()); //public static final Memory MEMORY = new Memory(new SimpleDataSource()); } public static Memory getInstance() { return SingletonHolder.MEMORY; } public static final DataSource getDataSource() { try { Context context = new InitialContext(); return (DataSource) context.lookup("java:comp/env/jdbc/test"); } catch (NamingException e) { throw new RuntimeException(e); } } } 

1.4 语句预处理

与ResultSetHanlder相互呼应,提供了PreparedStatementHanlder类,这个类提供语句(PreparedStatment)一些辅助性的方法,比如生成运行时的SQL语句、调整日期格式、简化分页语句写法等。这个类在应用中不会直接用到。其作用将隐藏在最重要的一个类Memory之中(与这个工具命名相同)。

2. 使用

上章从结果集提取、连接管理、语句处理等3个角度介绍了这个工具,本章介绍的Memory类就是对3者的集成,分3节描述Memory开放的API。

2.1 命令与查询

对数据库所有的操作,可分为两类:命令与查询。命令即更新数据,可进一步分为新增、删除与编辑。

2.1.1 查询(query)

public <T> T query(StringBuffer sql, ResultSetHandler<T> rsh, List<Object> params); public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params); public <T> T query(Connection conn, StringBuffer sql,ResultSetHandler<T> rsh, List<Object> params); public <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params); 

从接口定义可以看出,查询(query)方法,返回结果集,参数名也相似,只是数据结构不同而已:StringBuffer和List一组,String和Array(变长参数)一组,没有传递Connection参数,则表明连接在memory内部管理;有传递Connection参数,则表明连接交给外部程序管理。

在这个层面使用API,就是写SQL语句,几乎没有任何限制,唯一的限制就是在使用BeanHandler与BeanListHandler时,Bean的字段与Table的字段要存在相互匹配,Bean的字段命名风格是驼峰式,Table的字段命名是下划线连接。

2.1.2 命令(update)

public int update(StringBuffer sql, List<Object> params); public int update(String sql, Object... params); public int update(Connection conn, StringBuffer sql, List<Object> params); public int update(Connection conn, String sql, Object... params); public int[] batch(String sql, Object[][] params); public int[] batch(Connection conn, String sql, Object[][] params); 

相对于查询(query)方法,更新(update)方法,没有结果集处理器(ResultSetHandler)的参数以及结果集转化为的对象。但更新有批量更新(batch)的方法,提供批量执行sql语句的功能。

2.2 增删改查(CRUD)

增删改查,英文缩写为CRUD,这个大家都非常熟悉,使用Create, read, update, delete来做作为接口名称,这样记忆和理解成本最低。      Lifesinger在《jQuery 为什么优秀兼谈库与框架的设计》一文中,提到:在类库界,解决了What,解决了定位问题后,基本上已经决定了生死存亡。 至于 How,也重要但往往不是关键。        本人对此深以为然,所以Memory工具在接口方法名称、类名等的使用上相当节制(数量尽量少),这点也不同于别的持久化工具。

2.2.1 新增(create)

public <T> int create(Class<T> cls, T bean); public <T> int create(Class<T> cls, T bean, boolean customKey); public <T> int create(Connection conn, Class<T> cls, T bean); public <T> int create(Connection conn, Class<T> cls, T bean, boolean customKey); public <T> int[] create(Class<T> cls, List<T> beans); public <T> int[] create(Class<T> cls, List<T> beans, boolean customKey); public <T> int[] create(Connection conn, Class<T> cls, List<T> beans); public <T> int[] create(Connection conn, Class<T> cls, List<T> beans, boolean customKey); 

这些接口可持久化新增的一个对象或多个对象时。customkey这个参数表示主键的值是否使用自定的值。如果不是使用自定义的值,则采用序列(oracle)或自增主键(mysql),此时主键的名称必须是ID。

2.2.2 查询(read)

public <T> T read(Class<T> cls, long id); public <T> T read(Connection conn, Class<T> cls, long id); 

根据主键(主键名必须为ID)读取一条记录,并转化为对象。

2.2.3 更新(update)

public <T> int update(Class<T> cls, T bean); public <T> int update(Connection conn,Class<T> cls, T bean); public <T> int update(Class<T> cls, T bean, String primaryKey); public <T> int update(Connection conn, Class<T> cls, T bean, String primaryKey); public <T> int[] update(Class<T> cls, List<T> beans); public <T> int[] update(Connection conn, Class<T> cls, List<T> beans); public <T> int[] update(Class<T> cls, List<T> beans,String primaryKey); public <T> int[] update(Connection conn, Class<T> cls, List<T> beans,String primaryKey); 

这些接口可持久化更新的一个对象或多个对象时。primaryKey这个参数指定主键名称,默认是ID。

2.2.4 删除(delete)

public <T> int delete(Class<T> cls, long id); public <T> int delete(Connection conn, Class<T> cls, long id); 

根据主键(主键名必须为ID)删除一条记录。

2.3 其它

Memory的API在SQL语句操作层面分为:命令与查询(2.1节),在对象操作层面分为:增删改查(2.2节)。查询有一些常用的辅助性操作,比如分页和IN语句;在对事务有要求的场合,memory提供获取连接的接口,并将连接交给应用自行控制。

2.3.1 分页

public void pager(StringBuffer sql, List<Object> params, int pageSize, int pageNo); 

分页查询几乎是必不可少的,但是oracle的分页查询语句写起来相当复杂(3重嵌套),mysql分页查询虽然简单,但是其参数limit offset, n也不够直观。分页查询,即在问如果每页pageSize条记录,那么第pageNo页的记录是什么。分页查询接口(pager)封装了oracle和mysql的查询语句,并提供了pageSize和pageNo两个直观的参数。

2.3.2 IN语句

public <T> void in(StringBuffer sql, List<Object> params, String operator, String field, List<T> values) 

IN语句在查询时也比较常用,占位符?必须与参数的个数相匹配,手工拼接容易出错;当参数个数是动态变化时,占位符的拼写更是繁琐,因此对IN语句做了一个简单的封装,以保持代码的简洁。

2.3.3 事务

public Connection getConnection();

可以从memory取出一条连接,然后设置连接为非自动提交,进行事务操作与回滚。

3.多余的废话

3.1 为什么不用链式写法?

不少持久化的库或框架,喜欢使用链式写法来写SQL语句。但是殊不知链式的写法在Jquery很自然,在SQL中却是生搬硬套,不得其法。SQL是数据库领域的专用语言(DSL),用其本来的写法来表达是最自然的

试举一些持久化框架的做法,比如droidparts:

 // Select is used to provide data to EntityCursorAdapter
Select<EntityType> select = select().columns("_id", "name").where("external_id", Is.EQUAL, 10); // alternatively, call execute() to get the underlying Cursor Cursor cursor = select().where("name", Is.LIKE, "%%alex%%").execute(); // use Where object for complex queries Where haveCoordinaltes = new Where("latitude", Is.NOT_EQUAL, 0).or("longitude", Is.NOT_EQUAL, 0); select().where("country", Is.EQUAL, "us").where(haveCoordinates); 

又比如nutzam:

Condition c = Cnd.where("age",">",30).and("name", "LIKE", "%K%").asc("name").desc("id"); 

这些库的设计与Hibernate的Criterion多多少少有些相似,把SQL简单明了的写法改成所谓面向对象的链式写法。关系和对象变得扭曲(Object-Relational Impedance Mismatch),让人几乎看不到SQL本身的简洁和链式写法(builder pattern)的优雅,一举两“失”。

3.2 为什么不用XML或Annotation配置?

只要我们约定了表名与类名、列名与字段名的命名规则,并严格遵循,何须在再去了解XML和annotation配置的写法,再去写XML和Annotation维护映射关系呢?。少了这些额外的东西,代码的可维护性和可读性是不是也大大提高了呢。

试举一些持久化框架的做法,比如droidparts:

@Table(name="track_to_tag") public class TrackToTag extends Entity { @Column(nullable = false) public Track track; @Column(nullable = false) public Tag tag; } 

又比如nutzam:

@Table("t_company")
public class Company { @Id private int id; @Name private String name; @Column private int ceoId; @One(target = Employee.class, field = "ceoId") private Employee CEO; } 

XML繁琐冗长的配置,比如Ibatis或Hibernate,就不拷贝举例了

3.3 为什么只用PreparedStatement?

Statement和CallableStatement只在极少的场景,比如复杂的数据导入导出,可能用到。但在绝多大多数场景,PreparedStatment相对Statement更高效、更安全,代码的可读性更好;而CallableStatment,是把业务逻辑隐藏在SQL的存储过程,而不是显化在代码之中,理解代码将变得更困难,可读性也不如PreparedStatement。

3.4 能不能把运行时的SQL语句打印出来?

在开发过程,SQL语句有可能写错,如果能把运行时出错的SQL语句直接打印出来,那对排错非常方便,因为其可以直接拷贝到数据库客户端进行调试。在《JDBC 查询日志变得简单》这篇文章中,作者也希望有一种方法,它使我们能够获得查询字符串,并用实际的参数值替换参数占位符,最终他提出了一种解决方案,使用修饰器模式(decorator)扩展PreparedStatement,新增一个有日志功能的LoggableStatment的类。这当然是很不错的解决方案。      Memory工具,没有新增扩展类,只是在PreparedStatementHandler中,提供一个print方法,将SQL语句中的占位符替换为实际的参数,并在发生SQL Exception时,将其打印出来。

3.5 也说ORM

在开源中国可以搜到数百个ORM框架或类库。可见ORM曾经、也许现在还是,让不少攻城狮和程序猿,趋之若鹜。当然也有人对其反思,有一篇文章《为什么我说ORM是一种反模式》,中文版,英文版,就提出不同的看法。      ORM,通俗讲,就是把一种问题转化为另一种问题进行解决。但是数据库的问题,比如关联查询、分页、排序,能在OOP中得以完美的解决吗?OOP恐怕心有余而力不足。而这些问题却是关系数据库最擅长的问题域。把关系数据库擅长解决的问题转化给不擅长处理这类问题的OOP去解决,这不是很糊涂吗?OOP的方法论,应当控制一下自己的野心,专注于自己擅长的领域,比如代码的组织与管理、界面开发的应用等等。      当然ORM也不是一无是处,把一条数据(结果集)自动转化为一个对象,以便于业务代码的处理还是有益处的。但要把所有的关系操作映射为对象的操作(比如外键关系映射为继承),或者反之(比如将继承映射为外键关系),必定是事倍功半、得不偿失。

4. 参考文献

  • http://commons.apache.org/proper/commons-dbutils/
  • http://www.nowamagic.net/librarys/veda/detail/2217
  • https://github.com/brettwooldridge/SansOrm/wiki/ORM-is-an-anti-pattern
  • http://segmentfault.com/a/1190000000378827
  • http://www.oschina.net/project/tag/126/orm
  • http://www.nutzam.com/core/dao/annotations.html
  • https://github.com/lifesinger/lifesinger.github.com/issues/114
  • https://github.com/brettwooldridge/SansOrm/wiki/ORM-is-an-anti-pattern
  • http://www.oschina.net/translate/secrets-of-awesome-javascript-api-design
  • https://github.com/lifesinger/lifesinger.github.com/issues/114
  • http://download.oracle.com/otndocs/jcp/jdbc-4_1-mrel-spec/index.html
  • http://en.wikipedia.org/wiki/Singleton_pattern#Lazy_initialization

相关文章:

html 显示消息数量,html实现消息按钮上的数量角标的实例详解

这篇文章主要介绍了html在消息按钮上增加数量角标的实现代码,需要的朋友可以参考下html代码&#xff1a;消息4css代码&#xff1a;/*角标 */.ii{display: none;background: #f00;border-radius: 50%;width: 20px;height: 20px;top: 5px;right: 0px;position: absolute;text-ali…

为什么让A.I.“顶天立地”需要6个多月?

在A.I.的发展中&#xff0c;专注技术or专注应用&#xff1f;这从来不是一道选择题。“技术顶天&#xff0c;应用落地&#xff0c;希望全社会的开发者可以和我们一起开放创新、共建A.I.生态。”2018年3月22日&#xff0c;在科大讯飞主办的「AI大学未来课栈上海栈」&#xff0c;科…

[ASP.NET]状态管理[摘自C#入门经典]

[出处]&#xff1a;来自《C#入门经典》第三版中文版&#xff0c;P505-P506[涉及]&#xff1a;1、状态管理[附注]:看到这个表格总结得还是相当不错的&#xff0c;就摘抄下来了,兴许你看过&#xff0c;但没太在意,那就再看看吧.[正文]:HTTP协议是无状态的。从客户端到服务器的连接…

html表单颜色选择器,如何在Django管理中使用HTML5颜色选择器

我试图在Django的管理页面中实现HTML5 colorpicker。这是我的模型&#xff1a;#model.py...class Category(models.Model):...color models.CharField(max_length7)这是表格&#xff1a;#form.pyfrom django.forms import ModelFormfrom django.forms.widgets import TextInpu…

微软曾经的二号人物永远地离开了

参加 2018 AI开发者大会&#xff0c;请点击 大会官网 他是一位发明家、投资者、考古学家和慈善家&#xff0c;“他对微软做出的不可或缺的贡献”会让人们永远铭记。 据外媒 CNBC 今日早间报道&#xff0c;微软联合创始人之一保罗艾伦&#xff08;Paul Allen&#xff09;于当地时…

经理人必须抛弃的十个习惯思维

1、过分的完美主义可能很多经理人总希望自己可以做到完美&#xff0c;于是拟订了诸多工作计划&#xff0c;但往往到最后&#xff0c;连自己也不知道应该如何选择。一名信奉完美主义的美术设计师总是很晚才交上作品&#xff0c;但他没有意识到&#xff0c;准时与作品质量具有同等…

菜鸟学习之linux用户行为日志审计方案

今天学习了了sudo日志审计&#xff0c;专门对使用sudo命令系统的用户记录其执行的相关命令信息说明&#xff1a;所谓sudo命令日志审计,不记录普通用户操作,而是记录执行sudo命令的用户操作1、安装sudo命令,syslog服务[rootqzj ~]# rpm -qa |egrep "sudo|syslog" rsys…

html+服务器控件语法,HtmlForm 服务器控件声明性语法

HtmlForm 服务器控件声明性语法08/20/2007本文内容创建一个服务器端控件&#xff0c;该控件映射到 HTML 元素并允许您为网页中的元素创建一个容器。DefaultButton"string"DefaultFocus"string"EnableViewState"False|True"Id"string"…

Javascript内置对象新增接口列表

网上很少有提供不同版本接口对比的文章&#xff0c;所以自己总结一下。 Array MethodDescriptionModifyVersionconcat连接多个数组&#xff0c;返回数组副本&#xff0c;参数可以为值或数组否ES3join把数组元素组合为字符串否ES3pop删除并返回最后一个元素是ES3push向数组末尾添…

程序员四大焦虑瞬间:拿什么拯救你,我日益后退的发际线?

参加 2018 AI开发者大会&#xff0c;请点击 大会官网 一场突如其来的降温&#xff0c;再度把程序员的格子衬衫送上热搜&#xff0c;和“发际线 专业水平”等常见标签一样&#xff0c;这往往被视作一种“程序员式的幽默”&#xff0c;但自我调侃之余也不乏令人头秃的真实焦虑。…

mono和monodevelop源码编译安装

之所以用源码编译的方式安装mono和monodevelop&#xff0c;是因为通过yum安装的mono不是最新版本&#xff0c;而且monodevelop不能建 asp.net MVC3的工程。 而且通过源码安装&#xff0c;可以进一步了解mono的各个项目之间的关系。 我用的Fedora16系统 1. mono的源码编译安装 …

sql数据库打包部署安装

目的&#xff1a;在客户端服务器上”附加数据库文件”。一).创建部署项目1. 打开VS.NET2005。2&#xff0e;在“文件”菜单上指向“新建项目”。3. 在“新建项目”对话框中&#xff0c;选择“项目类型”窗格中的”其他项目类型”中的“安装和部署”&#xff0c;然后选择“模板”…

2021潍坊市高考成绩查询,潍坊2021高考成绩排名榜单,潍坊各高中高考成绩喜报

2018高考成绩排名榜单,各高中高考成绩喜报尚未公布&#xff0c;请广大考生和家长参考往年公布情况&#xff01;潍坊四中潍坊四中今年高考再次实现新的历史突破&#xff1a;本科过线1429人&#xff0c;自招(重本)上线379人。高分段情况&#xff1a;理660分以上3人&#xff0c;65…

掌握哪些机器学习工具更受企业青睐?

参加 2018 AI开发者大会&#xff0c;请点击 大会官网 想成为一名优秀的开发工程师不是一件简单的事情&#xff0c;除了掌握工程师的通用技能以外&#xff0c;还需要掌握机器学习的各种算法&#xff0c;更需要掌握从开发到调试到优化等一系列能力&#xff0c;这些能力中的每一项…

从头编写 asp.net core 2.0 web api 基础框架 (5) EF CRUD

第1部分&#xff1a;http://www.cnblogs.com/cgzl/p/7637250.html 第2部分&#xff1a;http://www.cnblogs.com/cgzl/p/7640077.html 第3部分&#xff1a;http://www.cnblogs.com/cgzl/p/7652413.html 第4部分&#xff1a;http://www.cnblogs.com/cgzl/p/7661805.html Github源…

可以打游戏的计算机,还在用笔记本玩游戏?台式机才能给你极致享受

【PConline 游戏爆测】随着笔记本的性能越来越好&#xff0c;玩家对于游戏本的需求也越来越高了&#xff0c;再加上购买游戏笔记本并不需要额外购买显示器&#xff0c;就能享受到高刷新率高色域的屏幕&#xff0c;让玩家对于游戏台式机就更加不感兴趣了。但我想说的是&#xff…

如何把Windows安装的所有打印机列出来

[转]最近在论坛中不少网友问"如何把Windows安装的所有打印机列出来"&#xff0c;在下面的程序中我们将把系统中所安装的打印机用列表框列出来&#xff0c;同时为默认打印机设置缺省值。  在下面的程序中我们用到了两个主要的类&#xff0c;把所有的打印机列表出来用…

今晚直播 | 谷歌资深工程师手把手教你使用TensorFlow最新API构建学习模型

目前&#xff0c;深度学习的研究和应用大受追捧&#xff0c;各种开源的深度学习框架层出不穷。TensorFlow 作为目前最受欢迎的深度学习框架&#xff0c;已经在 GitHub 上获得了 112194 个 star&#xff0c;受欢迎程序可见一斑。但如何学习 TensorFlow&#xff0c;以及如何通过 …

澳洲计算机学,2020年澳洲计算机科学专业工作好找吗

就业前景&#xff1a;本专业毕业生就业前景十分良好。在完成学业后可以凭借其良好扎实的专业技能自主创业&#xff0c;或者进一步学习获得硕士或博士学位&#xff0c;也可进入计算机科学领域求职&#xff0c;如对先进计算机进行研发、编程、游戏设计、多媒体设计、网页设计、信…

AngularJS如何在filter中相互调用filter

调用方式如下&#xff1a; app.filter(filter2, function( $filter ) {return function( input) {return $filter(filter1)( input );}});本文转自黄聪博客园博客&#xff0c;原文链接&#xff1a;http://www.cnblogs.com/huangcong/p/6800107.html&#xff0c;如需转载请自行联…

腾讯AI Lab开源业内最大规模多标签图像数据集(附下载地址)

今日&#xff08;10 月 18 日&#xff09;&#xff0c;腾讯AI Lab宣布正式开源“Tencent ML-Images”项目。该项目由多标签图像数据集 ML-Images&#xff0c;以及业内目前同类深度学习模型中精度最高的深度残差网络 ResNet-101 构成。 该开源项目的主要内容包括&#xff1a; 1、…

two years in cnblogs.com

时间过得太快了&#xff0c;几乎还没什么感觉就在博客园扎寨两年了。回头瞄瞄这两年来的随笔觉得自己留下的都是毛皮&#xff0c;自己一直在调船头&#xff0c;几乎没有在哪一个专业中找到精髓&#xff0c;有点遗憾&#xff01;在博客园这两年最要感谢的人是dudu&#xff0c;他…

自动驾驶公司Momenta完成超2亿美元融资,估值超10亿美元

参加 2018 AI开发者大会&#xff0c;请点击 ↑↑↑10 月 17 日&#xff0c;自动驾驶公司 Momenta 对外公布完成新一轮融资&#xff0c;本轮融资主要来自行业领先的战略投资者和国资背景的投资者。本轮战略投资者包括腾讯等多家机构&#xff0c;国资背景投资者则包括招商局创投…

shell版俄罗斯方块

#!/bin/bash # Tetris Game # 10.21.2003 xhchen #颜色定义 cRed1 cGreen2 cYellow3 cBlue4 cFuchsia5 cCyan6 cWhite7 colorTable($cRed $cGreen $cYellow $cBlue $cFuchsia $cCyan $cWhite) #位置和大小 iLeft3 iTop2 ((iTrayLeft iLeft 2)) ((iTrayTop iTop 1)) ((iTray…

利用计算机进行机械设计属于什么,计算机技术机械设计应用

【摘要】近几年计算机技术的飞速发展使得它在各个领域中的地位越来越显著&#xff0c;应用越来越广泛&#xff0c;在机械设计过程中也逐渐地引入了计算机技术。在计算机技术中有一种单独的辅助设计技术用来辅助各种设计工作&#xff0c;计算机辅助设计技术使得机械设计更加简单…

linux carry php Soap 扩展

前言今天又出现下问题了需要解决如下&#xff1a;报错信息是没有soap这个扩展&#xff01;解决问题如图所示&#xff1a;cd php-5.6.2/ext/soap//usr/local/php5/bin/phpize # 进入phpize开始编译安装 ./configure -with-php-config/usr/local/php5/bin/php-config -enable-so…

html使用highcharts绘制饼图,html js highcharts绘制圆饼图表

jquery实现饼状图效果 - 站长素材var chart;$(function () {var totalMoney999var zccw178var sycw821$(document).ready(function() {chart new Highcharts.Chart({chart: {renderTo: pie_chart,plotBackgroundColor: white,//背景颜色plotBorderWidth: 0,plotShadow: false}…

pycharm的安装配置和简单使用

1.pycharm的安装和配置1&#xff09;下载地址https://www.jetbrains.com/pycharm/download/#sectionwindows各位可以选择Community版本进行安装学习&#xff0c;土豪可以选择Professional版本下载安装包后默认安装2&#xff09;基本设置file-setting-project-project interpret…

港中大、商汤开源目标检测工具包mmdetection,对比Detectron如何?

近日&#xff0c;香港中文大学-商汤联合实验室开源了基于 PyTorch 的检测库——mmdetection。上个月&#xff0c;商汤和港中大组成的团队在 COCO 比赛的物体检测&#xff08;Detection&#xff09;项目中夺得冠军&#xff0c;而 mmdetection 正是基于 COCO 比赛时的 codebase 重…

关注中国的房地产市场

美国房贷呆账持续恶化引发道指大跌 亚洲股市应声猛泻中国的房地产&#xff0c;现在热得不得了&#xff0c;很多人贷款买房&#xff0c;买房子的人多了&#xff0c;房价也就上涨很多&#xff0c;投机商也囤积居奇。更促使房价迅猛上升。当中国房价不断上涨的势头减缓的时候&…