Ok,今天比较详细的学习一下hibernate的C(create)、R(read)、U(update)、D(delete) 相关api...

前言

  Session: 是Hibernate持久化操作的基础,提供了众多的数据库操作方法,如save(),update(),delete()。。。etc,用于完成对象的增加,修改,删除等方法.

  后面代码中使用到的HinernateUtil类:是用于构建SessionFactory(Hibernate提供的获取session的工厂类)的一个封装类,在前面的文章SSH初体验系列--Hibernate--1--环境配置及demo中有详细代码,可自行查看.

一) 增(C)

  1.添加单条个数据;

    @org.junit.Test
public void save(){
//创建对象
Feedback newItem=new Feedback();
newItem.setUsername("andew17");
newItem.setContent("测试单条插入");
newItem.setSendTime(new Timestamp(System.currentTimeMillis())); Session session=null;
Transaction tx=null;
try{
//获取session对象
session= HibernateUtil.openSession();
//开启事务
tx=session.beginTransaction();
//执行保存
session.save(newItem);
//提交事务
tx.commit();
}catch(Exception e){
//异常时,事务回滚
tx.rollback();
e.printStackTrace();
throw new RuntimeException(e);
}finally {
//释放session
session.close();
}
}

添加单条数据

  2.批量添加数据;

    可以通过for循环,将数据统一添加到一级缓存session中,再commit到数据库;

@org.junit.Test
public void saveMany(){
//创建对象
List<Feedback> feedbackList=new ArrayList<>();
for(int i=0;i<10;i++){
Feedback newItem=new Feedback();
newItem.setUsername("andew"+i);
newItem.setContent("测试单条插入"+i);
newItem.setSendTime(new Timestamp(System.currentTimeMillis()));
feedbackList.add(newItem);
}
Session session=null;
Transaction tx=null;
try{
//获取session对象
session= HibernateUtil.openSession();
//开启事务
tx=session.beginTransaction();
//执行保存,此时只是保存到Session缓存中,并没有同步到数据库
Feedback feedback=null;
for(int i=0;i<feedbackList.size();i++){
feedback=feedbackList.get(i);
session.save(feedback);
}
//提交事务,就缓存同步到数据库
tx.commit();
}catch(Exception e){
//异常时,事务回滚
tx.rollback();
e.printStackTrace();
throw new RuntimeException(e);
}finally {
//释放session
session.close();
}
}

for循环执行session的save方法

    如果数据量不大时,或者对性能没有极致的追求时,这种方法还ok;但是当批量插入数据量较大时,这个方式的弊端就体现出来了.

    弊端主要有两点:a,循环向Session添加,修改数据时,Session对象自身开辟的一级缓存会不断被消耗,直到耗尽(outOfMemoryError);

             b,通过在hibernate.cfg.xml文件配置"显示sql语句"

        <!--显示SQL语句-->
<property name="show_sql">true</property>

              再跟踪打印的SQl语句,很容易就发现,内部其实还是执行了n(n=数据量)次的插入操作,而不是一次语句执行,在性能上,可想并不是很好. 对于喜欢追求代码性能的小伙伴,这是让人难以忍受的,如鲠在喉...

Hibernate: select max(id) from feedback
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Hibernate: insert into feedback (username, content, sendTime, id) values (?, ?, ?, ?)
Disconnected from the target VM, address: '127.0.0.1:59399', transport: 'socket' Process finished with exit code 0

    解决方案:a,对于内存溢出,可以在代码中进行判断,每隔n条,释放一次缓存;并且在hibernate.xfg.xml中配置每次提交sql的数量

<property name="hibernate.jdbc.batch_size">10</property>
// 每处理20条清空缓存
session.save(newItem);
if (i%20 == 0) {
session.flush();
session.clear();
}

        b.若想在性能上有所提升,可以绕过Hibernate Api,直接使用jdbc api来做批量插入;

@org.junit.Test
public void saveJdbc(){
//创建对象
List<Feedback> feedbackList=new ArrayList<>();
for(int i=0;i<;i++){
Feedback newItem=new Feedback();
newItem.setUsername("andew"+i);
newItem.setContent("测试单条插入"+i);
newItem.setSendTime(new Timestamp(System.currentTimeMillis()));
feedbackList.add(newItem);
}
String insertSql="insert into feedback (username, content, sendTime) values (?, ?, ?)"; Session session=null;
// Transaction tx=null;
try{
session= HibernateUtil.openSession();
//tx=session.beginTransaction();
session.doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
//这里面就得到connection了
PreparedStatement stmt=connection.prepareStatement(insertSql);
//方式1:自动提交
/*connection.setAutoCommit(true);
for(int i=0;i<feedbackList.size();i++){
stmt.setString(1,"andrew"+1);
stmt.setString(2,"test content "+i);
stmt.setTimestamp(3,new Timestamp(System.currentTimeMillis()));
stmt.execute();//此语句,每次执行,都会将一条数据插入到db
}*/ //方式2:批量提交
connection.setAutoCommit(false);
for(int i = 0; i<feedbackList.size();i++) {
stmt.setString(1,"andrew"+1);
stmt.setString(2,"test content "+i);
stmt.setTimestamp(3,new Timestamp(System.currentTimeMillis()));
stmt.addBatch();
if (i % 10 == 0) {
stmt.executeBatch();
connection.commit();//此处执行一次db插入操作
}
}
stmt.executeBatch();
connection.commit();
}
});
////注意:此时不能再用事务,会报错:org.hibernate.TransactionException: Unable to commit against JDBC Connection
// tx.commit();
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException(e);
}finally {
//释放session
session.close();
}
}

jdbc批量插入数据

    其中有几个地方需要注意:

      a,connection对象的获取:

a)过时方式:session.connection();
但是这个方法Hibernate不推荐使用,The method connection() from the type Session is deprecated
在3.3以后的版本中已经被废除了。 b)Session.doWork;
3.3官方的替代方法是用Session.doWork(Work work);
传入的参数work是一个接口,可以:
HibernateFactory.getSession().doWork(
new Work() {
public void execute(Connection connection) {
// 这里面就得到connection了,
}
}
);

      b.代码中的"方式2,批量提交",就是我们最终想要的高性能的答案;

  3.使用一对一关联添加数据

    在实际开发中,我们经常会遇到表关联的情况,比如一张数据表的记录与另一张数据表记录一一对应,即:一一对应关系,此时我们对表数据的添加最好也应该是一次性关联添加的.Hibernate就提供了相关的方法,供开发人员处理这种关系的映射,下面就来学习一下.

    此处,我们使用两张新表来进行学习,UserInfo和UserExtend,其中UserInfo记录用户的姓名,性别,出生日期等基础信息,UserExtend记录扩充信息,如职业,公司,地址等。UserInfo中通过一个UserExtend属性与UserExtend表相关联。具体如下:

/**
* Created by c-yangx on 11/18/2016.
*/
public class UserInfo {
private int id;
private String name;
private Timestamp birthday;
private String sex;
private UserExtend userExtend; public int 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 Timestamp getBirthday() {return birthday;} public void setBirthday(Timestamp birthday) {this.birthday = birthday;} public String getSex() {return sex;} public void setSex(String sex) {this.sex = sex;} public UserExtend getUserExtend() {return userExtend;} public void setUserExtend(UserExtend userExtend) {this.userExtend = userExtend;}
}

UserInfo.java

/**
* Created by c-yangx on 11/18/2016.
*/
public class UserExtend {
private int id;
private String position;
private String company;
private String address;
private UserInfo userInfo; public int getId() {return id;}
public void setId(int id) {this.id = id;} public String getPosition() {return position;} public void setPosition(String position) {this.position = position;} public String getCompany() {return company;} public void setCompany(String company) {this.company = company;} public String getAddress() {return address;} public void setAddress(String address) {this.address = address;} public UserInfo getUserInfo() {return userInfo;} public void setUserInfo(UserInfo userInfo) {this.userInfo = userInfo;}
}

UserExtend.java

<?xml version="1.0"  encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="models">
<class name="models.UserInfo" table="userinfo" catalog="public">
<id name="id" column="id" type="java.lang.Integer">
<generator class="native"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="name" length="45" not-null="true">
<comment>姓名</comment>
</column>
</property>
<property name="birthday" type="java.sql.Timestamp">
<column name="birthday" length="20" not-null="true">
<comment>出生日期</comment>
</column>
</property>
<property name="sex" type="java.lang.String">
<column name="sex" length="5" not-null="true">
<comment>性别:w=女;m=男;</comment>
</column>
</property>
<many-to-one name="userExtend" column="userExtend" unique="true" not-null="true" cascade="all"></many-to-one>
</class>
</hibernate-mapping>

UserInfo.hbm.xml

<?xml version="1.0"  encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="models">
<class name="models.UserExtend" table="userextend" catalog="public">
<id name="id" column="id" type="java.lang.Integer">
<generator class="native"></generator>
</id>
<property name="position" type="java.lang.String">
<column name="position" length="50" not-null="false">
<comment>职位</comment>
</column>
</property>
<property name="company" type="java.lang.String">
<column name="company" length="200" not-null="false">
<comment>公司名</comment>
</column>
</property>
<property name="address" type="java.lang.String">
<column name="address" length="50" not-null="false">
<comment>住址</comment>
</column>
</property>
<one-to-one name="userInfo" property-ref="userExtend"></one-to-one>
</class>
</hibernate-mapping>

UserExtend.hbm.xml

    测试代码为:

@org.junit.Test
public void save_one2one() throws ParseException {
//创建对象
UserInfo userInfo=new UserInfo();
UserExtend userExtend=new UserExtend();
userExtend.setPosition("IT");
userExtend.setCompany("guess");
userExtend.setAddress("BeiJing CangPing");
userInfo.setName("andrew"); SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
userInfo.setBirthday(new Timestamp(simpleDateFormat.parse("1992-01-10").getTime())); userInfo.setSex("m");
userInfo.setUserExtend(userExtend); Session session=null;
Transaction tx=null;
try{
session= HibernateUtil.openSession();
tx=session.beginTransaction(); session.save(userInfo); tx.commit();
}catch(Exception e){
tx.rollback();
e.printStackTrace();
throw new RuntimeException(e);
}finally {
session.close();
}
}

    从细分类上,此种属于"唯一外键双向关联",其他的还有"多对一单向关联"、"多对多单向关联"等,这个话题内容较多,就不在此处展开,后面也许会单开一篇文章研究一下.

    对了,最后一定别忘了在主配置文件hibernate.cfg.xml中添加mapping配置。

    放一张数据库截图,生成表结构如图所示:

  4.一对多关联添加数据.

    还有一种开发中常见的需求是,表的一对多关心,举个生活中的例子:一个支付宝账号绑定多张银行卡,每张卡都会显示他自己是哪个银行的,卡号是多少...等信息;

    那么我们这里就用两张新表来演示,一张账户表(Account),类比于支付宝账户;一张绑定银行卡表(BindCard),记录例子中的绑定银行卡信息;一个账户会对应有多条绑定银行卡记录.

    a> 两个model类的代码如下:

/**
* Created by c-yangx on 11/18/2016.
*/
public class Account { private int id;
private String name;
private Set<BindCard> bindCards; public int 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 Set<BindCard> getBindCards() {return bindCards;} public void setBindCards(Set<BindCard> bindCards) {this.bindCards = bindCards;}
}

Account.java

/**
* Created by c-yangx on 11/18/2016.
*/
public class BindCard {
private int id;
private String cardNum;
private int cardType; private Account account; public int getId() {return id;} public void setId(int id) {this.id = id;} public String getCardNum() {return cardNum;} public void setCardNum(String cardNum) {this.cardNum = cardNum;} public int getCardType() {return cardType;} public void setCardType(int cardType) {this.cardType = cardType;} public Account getAccount() {return account;} public void setAccount(Account account) {this.account = account;}
}

BindCard.java

    b>Account.hbm.xml;

      其中有几点需要特别说明一下:

        1.在映射文件里,通过<set>标签配置一对多的关系映射;

        2.cascade属性设置的是级联操作类型,设置为all时,是所以操作都能执行;  如果只进行"创建"和"修改",也可设置成save-update;

        3.<set>标签的name属性值=持久化类对应的属性名;   <key>的column属性值=与其关联的表的外键;                    

<?xml version="1.0"  encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="models">
<class name="models.Account" table="account" catalog="public">
<id name="id" column="id" type="java.lang.Integer">
<generator class="native"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="name" length="45" not-null="true">
<comment>账户名</comment>
</column>
</property>
<set name="bindCards" cascade="all" lazy="false">
<key column="cardId"/>
<one-to-many class="models.BindCard"/>
</set>
</class>
</hibernate-mapping>

    c>最后是测试代码,这就没啥好多说的了

@org.junit.Test
public void save_one2many(){
BindCard bindCard1=new BindCard();
bindCard1.setCardNum("1234343242");
bindCard1.setCardType(0); BindCard bindCard2=new BindCard();
bindCard2.setCardNum("3421213131");
bindCard2.setCardType(1); Set<BindCard> set=new HashSet<>();
set.add(bindCard1);
set.add(bindCard2); Account account=new Account();
account.setName("andrew's account");
account.setBindCards(set); Session session=null;
Transaction tx=null;
try{
session= HibernateUtil.openSession();
tx=session.beginTransaction(); session.save(account); tx.commit();
}catch(Exception e){
tx.rollback();
e.printStackTrace();
throw new RuntimeException(e);
}finally {
session.close();
}
}

      生成的数据表结构:

二) 查(R)

  方式一:根据主键id,查询单条记录,这也是最简单的方式;

        Session session=HibernateUtil.openSession();
Feedback feedback= session.get(Feedback.class,60);

  方式二:HQL(hibernate query language)查询;

     1.HQL查询语言是什么? HQL查询语言是面向对象查询语言,支持多态查询;  当我们想在查询时,做一些复杂的逻辑,比如where 筛选,order by 排序等,HQL就顶上用了;

        Session session= HibernateUtil.openSession();
String sqlStr="from Feedback";
Query q=session.createQuery(sqlStr);
List<Feedback> feedbacks=q.list();

      做条件筛选时,修改下sqlStr就行:

public List<Feedback> getAll(String userName) {
Session session = null;
try {
session = HibernateUtils.getSession();
Query q =session.createQuery("from Feedback where userName=?");
// 注意:参数索引从0开始
q.setParameter(0, userName);
// 执行查询
return q.list();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
session.close();
}
}

   方式三:QBC(Query By Criteria)查询;

      1)Hibernate 5.2版本之前(暂时还没有核实是5.2之前的哪一个版本开始),

        使用QBC查询,通常有3个步骤:

          1.用Session实例的createCriterria()方法创建Criteria对象c;

          2.使用Restrictions工具类的相关方法为创建的对象c设置查询条件。

            常见的方法有: a) Restrictions.eq = 等于;

                    b) Restrictions.allEq = 使用Map、key/value进行多个等于的对比;

                    c) Restrictions.gt = 大于;

                    d) Restrictions.ge = 大于等于;

                    e) Restrictions.ct = 小于;

                    f)  Restrictions.le = 小于等于;

                    g)  Restrictions.between = 对应SQL的between子句;

                    h) Restrictions.like = 对应SQL的like 子句;

                    i) Restrictions.in = 对应SQL 的in子句;

          3.使用对象c的list()方法执行查询,获取结果;

       2) Hibernate 5.2版本时,createCriteria()方法已经过时了,新版中使用的是链式的查询语句(类似C#中的linq to sql,还有现在android中的rxjava,看来,链式编程以其优美的代码风格,便于维护的特性,越来越成为潮流)

        下面放一段核心代码 (可能因为h5.2版本较新,关于createCriteria()替代方法的查询结果,在百度上暂时很难找到,这个地方也是费了老大劲了. ):

@org.junit.Test
public void get_qbc(){
Session session= HibernateUtil.openSession();
//在Hibernate 5.2中,此方法过时了
//Criteria criteria=session.createCriteria(Feedback.class); //用新的替代方法
CriteriaBuilder cBuilder=session.getCriteriaBuilder();
CriteriaQuery<Feedback> cQuery= cBuilder.createQuery(Feedback.class);
Root<Feedback> feedbackRoot=cQuery.from(Feedback.class); //1.select all records
CriteriaQuery<Feedback> select = cQuery.select(feedbackRoot);
TypedQuery<Feedback> typedQuery = session.createQuery(select);
List<Feedback> resultlist = typedQuery.getResultList();
/*
最终打印的sql语句:
Hibernate: select feedback0_.id as id1_2_, feedback0_.username as username2_2_, feedback0_.content as content3_2_, feedback0_.sendTime as sendTime4_2_
from feedback feedback0_
**/ //2.Ordering the records
CriteriaQuery<Feedback> select1 = cQuery.select(feedbackRoot);
select1.orderBy(cBuilder.asc(feedbackRoot.get("id")));
TypedQuery<Feedback> typedQuery1 = session.createQuery(select1);
List<Feedback> resultlist1 = typedQuery1.getResultList();
/*
最终打印的sql语句:
Hibernate: select feedback0_.id as id1_2_, feedback0_.username as username2_2_, feedback0_.content as content3_2_, feedback0_.sendTime as sendTime4_2_
from feedback feedback0_ order by feedback0_.id asc
* */ //3.where select条件筛选查询
CriteriaQuery<Feedback> select2 = cQuery.select(feedbackRoot);
select2.orderBy(cBuilder.asc(feedbackRoot.get("id")));
select2.where(cBuilder.ge(feedbackRoot.get("id"),60));
TypedQuery<Feedback> typedQuery2 = session.createQuery(select2);
List<Feedback> resultlist2 = typedQuery2.getResultList();
/*
最终打印的sql语句:
Hibernate: select feedback0_.id as id1_2_, feedback0_.username as username2_2_, feedback0_.content as content3_2_, feedback0_.sendTime as sendTime4_2_
from feedback feedback0_ where feedback0_.id>=60 order by feedback0_.id asc
* */ System.out.println("result ok");
}

三) 改(U)、删(D)

  相较于"CR",修改和删除的需求相对就比较简单了,没有那么多的复杂需求,这个地方就简单带过了;

        //修改(updateInstance=要修改的实例)
session.update(updateInstance);
//删除(deleteInstance=要删除的实例)
session.delete(deleteInstance);

后言

  呼~~总算能松口气了。。。

  真正写的时候,才发现, "crud",叫起来多么简单的一个单词,中间的文章何其多,深挖起来,几天几夜也说不完; hibernate一个流行的框架,里面的内容又是何其多,博主实在是不敢继续继续深入下去了,否则这篇文章发表不知要到何年何月去了(哈哈~~开个玩笑)...

  文章内容虽然不深,不过博主是在用心写,里面的每一段代码,都是测试运行,确认无误的...(自己受够了网上前言不搭后语的demo代码,骂过... 同样原因,可不想自己也被参考了文内代码的人在背后骂^_^)如果大家发现什么问题,也欢迎评论,有问题的地方,我会及时修正;

  文章写着挺耗时的,不过楼主会坚持下去。理由只有两个:1.如果你也刚开始学Hibernate,本文能让你觉得多少有些收获,我就会觉得自己的没有做无用功;  2.博主自己忘了的时候,业可以回头来翻看;

  也欢迎大家关注,共同学习,共同进步.

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利;

本文出自:博客园--别问是谁

SSH初体验系列--Hibernate--2--crud操作的更多相关文章

  1. SSH初体验系列--Hibernate--1--环境配置及demo

    最近在学hibernate,常见的教程都是搭配mysql,因为公司本地电脑用的是pg,所以就尝试着做个pg的小demo. 自己也是边学边写,只当是加深印象.话不多说,直接开始; 一) 准备工作; 1) ...

  2. SSH初体验系列--Hibernate--3--单值与分页查询

    前言 查询可以按结果集分2类:单个结果 和 数组 ; 其中,返回数组,在这个 数据库数据量随随便便就能上几十万的互联网时代大背景下,常常需要做分页处理, 所以这里就说一下单值和分页, 算是对上一篇&q ...

  3. hibernate的CRUD操作

    一对多关系映射的crud操作: 1.单项的保存操作 /** * 保存操作 * 正常的保存:创建一个联系人,需要关联客户 */ @Test public void test1(){ Session s= ...

  4. hibernate之CRUD操作

    CRUD是指在做计算处理时的增加(Create).读取(Retrieve)(重新得到数据).更新(Update)和删除(Delete)几个单词的首字母简写. 下面列举实例来讲解这几个操作: 实体类: ...

  5. java框架篇---hibernate之CRUD操作

    CRUD是指在做计算处理时的增加(Create).读取(Retrieve)(重新得到数据).更新(Update)和删除(Delete)几个单词的首字母简写. 下面列举实例来讲解这几个操作: 实体类: ...

  6. 初窥MyBatis-普通的CRUD操作

    编写接口 编写对应的Mapper.xml中的sql语句 测试(增删改需要提交事务) <mapper namespace="com.perwrj.dao.UserMapper" ...

  7. hibernate--CRUD初体验

    hibernate的crud操作初体验. 看具体实例 package com.fuwh.model; import javax.persistence.Column; import javax.per ...

  8. ipython及Python初体验

    阅读目录: Python环境体验 Python编辑器 ipython安装 Python提示符 Python初体验 print和变量 变量操作 内建函数:方法 数学运算:简单算术.随机数 关于模块 一. ...

  9. 【SSH三大框架】Hibernate基础第五篇:利用Hibernate完毕简单的CRUD操作

    这里利用Hibernate操作数据库完毕简单的CRUD操作. 首先,我们须要先写一个javabean: package cn.itcast.domain; import java.util.Date; ...

随机推荐

  1. Android媒体扫描详细解析之一(MediaScanner & MediaProvider)

    用过Android手机的同学都知道,每次开机的时候系统会先扫描sdcard,sdcard重新插拔(挂载)也会扫描一次sdcard. 为什么要扫描sdcard,其实是为了给系统的其他应用提供便利,比如, ...

  2. promise对象解决回调地狱

    先放一张图片感受一下回调地狱 看起来是真的很让人头痛的东西 而现在我这里使用promise对象来解决回调地狱 采用链式的 then,可以指定一组按照次序调用的回调函数. 这时,前一个 then 里的一 ...

  3. 转: Android中的签名机制

    转载请注明出处:http://www.blogjava.net/zh-weir/archive/2011/07/19/354663.html Android APK 签名比对 发布过Android应用 ...

  4. OpenCV 之 霍夫变换

    Hough 变换,对图像中直线的残缺部分.噪声.以及其它的共存结构不敏感,因此,具有很强的鲁棒性. 它常用来检测 直线和曲线 (圆形),识别图像中的几何形状,甚至可用来分割重叠或有部分遮挡的物体. 1 ...

  5. 算法笔记_074:子集和问题(Java)

    目录 1 问题描述 2 解决方案 2.1 全排列思想求解 2.2 状态空间树思想求解   1 问题描述 求n个正整数构成的一个给定集合A = {a1,a2,a3,...,an}的子集,子集的和要等于一 ...

  6. 获取ping的最短、最长、平均时间

    # -*- coding: utf-8 -*- import osimport rep = os.popen('ping 120.26.77.101') out = p.read()regex = r ...

  7. js中求水仙花数

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. Public Private Protect Inheritance and access specifiers

    In the previous lessons on inheritance, we've been making all of our data members public in order to ...

  9. Docker Container同时启动多服务 supervisor

    Docker Container同时启动多服务 转载请注明来自:http://blog.csdn.net/wsscy2004 昨天踩了个天坑,我有一个基本的镜像centos6.5+ssh,是通过Doc ...

  10. hybird和js交互退出