Hibernate持久化类的编写规则

Hibernate是持久层的ORM映射框架,专注于数据的持久化工作。所谓持久化,就是将内存中的数据永久存储到关系型数据库中。

持久化类

一个java类与数据库表建立了映射关系,那么这个类称为持久化类。可以简单的理解为持久化类就是一个java类有一个映射文件与数据库的表建立了关系。

持久化类的编写规则:

1、持久化类需要提供无参数的构造方法。因为在Hibernate的底层需要使用反射生成类的实例。

2、持久化类的属性需要私有,对私有的属性提供共有的get和set方法。因为在Hibernate底层会将查询到的数据进行封装。

3、持久化类的属性要尽量使用包装类的类型。因为包装类和基本类型的默认值不同,包装类的类型语义描述更清晰,而基本数据类型不容易描述。比如:double默认为0,Double默认为null。

4、持久化类要有一个唯一标识OID与表的主键对应。因为Hibernate中需要通过这个唯一标识OID区分在内存中是否是同一个持久化类。Hibernate是不允许在内存中出现两个OID相同的持久化对象的。

5、持久化类要尽量不要使用final进行修饰。因为Hibernate中有延迟加载的机制,这个机制中会产生代理对象,Hibernate产生代理对象使用的是字节码的增强技术完成的,其实就是产生了当前类的一个子类对象实现的。如果使用了final修饰持久化类。那么就不能产生子类。那么Hibernate的延迟加载策略就会失效。

Hibernate主键生成策略

主键的类型分为自然主键和代理主键

自然主键:把具体业务含义的字段作为主键,称为自然主键。比如在customer表中,如果把name字段作为主键,其前提条件必须是:每一个客户的姓名不允许为null,不允许重名,并且不允许修改客户姓名。尽管这也是可行的,但是不能满足不断变化的业务需求,一旦出现了允许客户端重名的业务需求,就必须修改数据模型,重新定义表的主键,这给数据库的维护增加了难度。

代理主键:把不具备业务含义的字段作为主键,称之为代理主键。显然更合理的方式是使用代理主键。

Hibernate的主键生成策略

increment:主键自增.由hibernate来维护.每次插入前会先查询表中id最大值.+1作为新主键值。用于long、short、int类型,由Hibernate自动以递增的方式生成唯一标识符,每次增量为1.只有当没有其它进程向同一张表中插入数据时才可以使用,不能再集群环境下使用。适用于代理主键。

identity:主键自增.由数据库来维护主键值.录入时不需要指定主键。采用底层数据库本身提供的主键生成标识符,条件是数据库支持自动增长数据类型。适用于代理主键。

hilo:高低位算法.主键自增.由hibernate来维护.开发时不使用.

sequence:Oracle中的主键生成策略.Hibernate根据底层数据库序列生成标识符。条件是数据库支持序列。适用于代理主键。

native:hilo+sequence+identity 自动三选一策略。根据底层数据库对自动生成表示符的能力来选择identity、squence、hilo三种生成器中的一种,适合跨数据库平台开发。适用于代理主键。

uuid:产生随机字符串作为主键. 主键类型必须为string 类型。Hibernate采用128位的UUID算法来生成标识符。该算法能够在网络环境中生成唯一的字符串标识符,其UUID被编码为一个长度为32位的石榴进制字符串,这种策略并不流行,因为字符串类型的主键比整数类型的主键占用更多的数据库空间。适用于代理主键。

assigned:hibernate不会管理主键值.由开发人员自己录入。有java程序负责生成标识符,如果不指定id元素的generator属性,则默认使用该主键生成策略,适用于自然主键。

  <id name="cust_id"  >
<!-- generator:主键生成策略 -->
<generator class="native"></generator>
</id>

Hibernate的持久化对象的三种状态

Hibernate为了更好的来管理持久化类,特将持久化类分成了三种状态。分别是瞬时态、持久态、脱管态。

瞬时态

也称临时态或者自由态,瞬时态的实例是由new命令创建、开辟内存空间的对象,不存在持久化标识OID(相当于主键值),尚未与Hibernate Session关联,在数据库中也没有记录,仅是一个信息携带的载体。

持久态

持久态的对象存在持久化标识(OID),加入到了Session缓存中,并且相关联的session没有关闭,在数据库中有对应的记录,每条记录只对应唯一的持久化对象,需要注意的是,持久对象是在事务还未提交前变成持久态的。

脱管态

脱管态也称离线态或者游离态,当某个持久化状态的实例与Session的关联被关闭时就变成了托管态。脱管态对象存在持久化标识OID,并且仍然与数据库中的数据存在关联,只是失去了与当前Session的关联,脱管状态对象发生改变时Hibernate不能检测到。

区分对象的三种状态

    //三种状态特点
//save方法: 其实不能理解成保存.理解成将瞬时状态转换成持久状态的方法
//主键自增 : 执行save方法时,为了将对象转换为持久化状态.必须生成id值.所以需要执行insert语句生成.
//increment: 执行save方法,为了生成id.会执行查询id最大值的sql语句.
public void fun2(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
Customer c = new Customer(); // 没有id, 没有与session关联 => 瞬时状态
c.setCust_name("联想"); // 瞬时状态
session.save(c); // 持久化状态, 有id,有关联
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}

以上代码中,Customer对象由new关键字创建,此时还未与Session进行关联,它的状态称为瞬时态;

在执行了session.save(c)之后,Customer对象纳入了Session的管理范围,这时的Customer对象变成了持久态对象,此时的Session的事务还未提交;此时仅仅生成ID,比如:如果主键策略为identity,执行插入操作才会生成ID,所以会生成insert语句,而如果主键策略为increment,则会生成select max(cust_id)  from cst_customer语句,当提交事务的时候,才会生成insert语句。

//三种状态特点
// 持久化状态特点: 持久化状态对象的任何变化都会自动同步到数据库中.
public void fun3(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
Customer c = session.get(Customer.class, 1l);//持久化状态对象
c.setCust_name("微软公司");
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}

以上代码即时没调用update方法,也会生成update语句。

状态转换

更多请参考这里

Hibernate的一级缓存

缓存的作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能。缓存的数据时数据存储源中数据的拷贝。缓存的物理介质通常是内存。

Hibernate的缓存分为一级缓存和二级缓存,Hibernate的这两级缓存都位于持久化层,存储的都是数据库数据的备份。其中第一级缓存为Hibernate的内置缓存,不能被卸载。

Hibernate的一级缓存就是指Session缓存,Session缓存是一块内存空间,用来存放管理的java对象,在使用Hibernate查询对象的时候,首先会使用对象属性的OID值在Hibernate的一级缓存中进行查找,如果找到,直接取出,不会查询数据库。Hibernate的一级缓存的作用就是减少对数据库的访问次数。

Hibernate的一级缓存特点:

1、当应用程序调用Session接口的save、update、saveOrUpdate时,如果Session缓存中没有相应的对象,Hibernate就会自动地把从数据库中查询到的相应对象信息加入到一级缓存中去。

2、当调用Session接口的load、get方法,一级Query接口的list、iterator方法时,会判断缓存中是否存在该对象,有则返回,不会查询数据库,如果缓存中没有要查询对象,再去数据库中查询对应对象,并添加到一级缓存中。

3、当调用Session的close方法时,Session缓存会被清空。

证明一级缓存存在

//证明一级缓存存在
public void fun1(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作 Customer c1 = session.get(Customer.class, 1l);
Customer c2 = session.get(Customer.class, 1l);
Customer c3 = session.get(Customer.class, 1l);
Customer c4 = session.get(Customer.class, 1l);
Customer c5 = session.get(Customer.class, 1l); System.out.println(c3==c5);//true
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}

以上代码只生成1次sql语句。

提高效率手段1:提高查询效率

提高效率手段2:减少不必要的修改语句发送

public void fun2(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作 Customer c1 = session.get(Customer.class, 1l);
c1.setCust_name("哈哈");
c1.setCust_name("谷歌公司");
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}

以上代码当查询出来的cust_name为“谷歌公司”时,不会再生成update语句。

  Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
Customer c1=new Customer();
c1.setCust_id(1l);
session.update(c1);
Customer c2=session.get(Customer.class,1l);
//session.save(customer);
transaction.commit();
session.close();

以上代码调用update方法,c1变成持久态,加入到缓存中,当执行get方法时,由于缓存中已存在id为1的实体,所以不会查询数据库,当事务提交时,快照中没有数据,所以比对不相同,会生成update语句。

Hibernate的事务控制

在Hibernate中,可以通过代码来操作管理事务,除了在代码中对事务开启,提交和回滚之外,还可以在Hibernate的配置文件中对事务进行配置。配置文件中,可以设置事务的隔离级别。

         <!-- 指定hibernate操作数据库时的隔离级别
#hibernate.connection.isolation 1|2|4|8
0001 1 读未提交
0010 2 读已提交
0100 4 可重复读
1000 8 串行化
-->
<property name="hibernate.connection.isolation">4</property>

在项目中如何管理事务

业务开始之前打开事务,业务执行之后提交事务. 执行过程中出现异常.回滚事务.

在dao层操作数据库需要用到session对象.在service控制事务也是使用session对象完成. 我们要确保dao层和service层使用的使用同一个session对象。

在hibernate中,确保使用同一个session的问题,hibernate已经帮我们解决了. 我们开发人员只需要调用getCurrentSession()方法即可获得与当前线程绑定的session对象。

注意:

1、调用getCurrentSession方法必须配合主配置中的一段配置

<!-- 指定session与当前线程绑定 -->
<property name="hibernate.current_session_context_class">thread</property>

2、通过getCurrentSession方法获得的session对象.当事务提交时,session会自动关闭.不要手动调用close关闭.

比如:

Service对象

    public void save(Customer c) {
Session session = HibernateUtils.getCurrentSession();
//打开事务
Transaction tx = session.beginTransaction();
//调用Dao保存客户
try {
customerDao .save(c);
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
}
//关闭事务
tx.commit();
}

Dao层

    public void save(Customer c) {
//1 获得session
Session session = HibernateUtils.getCurrentSession();
//3 执行保存
session.save(c);
}

hibernate中的批量查询

HQL查询-hibernate Query Language(多表查询,但不复杂时使用)

Hibernate独家查询语言,属于面向对象的查询语言。

1、基本查询:

    //基本查询
public void fun1(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1> 书写HQL语句
     //String hql = " from cn.itheima.domain.Customer ";
String hql = " from Customer "; // 查询所有Customer对象
//2> 根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//3> 根据查询对象获得查询结果
List<Customer> list = query.list(); // 返回list结果
//query.uniqueResult();//接收唯一的查询结果 System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联 }

2、条件查询

?号占位符

    //条件查询
//问号占位符
public void fun3(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1> 书写HQL语句
String hql = " from Customer where cust_id = ? "; // 查询所有Customer对象
//2> 根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//设置参数
//query.setLong(0, 1l);
query.setParameter(0, 1l);
//3> 根据查询对象获得查询结果
Customer c = (Customer) query.uniqueResult(); System.out.println(c);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联 }

命名占位符

    //条件查询
//命名占位符
public void fun4(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1> 书写HQL语句
String hql = " from Customer where cust_id = :cust_id "; // 查询所有Customer对象
//2> 根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//设置参数
query.setParameter("cust_id", 1l);
//3> 根据查询对象获得查询结果
Customer c = (Customer) query.uniqueResult(); System.out.println(c);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联 }

3、分页查询

    //分页查询
public void fun5(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1> 书写HQL语句
String hql = " from Customer "; // 查询所有Customer对象
//2> 根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//设置分页信息 limit ?,?
query.setFirstResult(1);
query.setMaxResults(1);
//3> 根据查询对象获得查询结果
List<Customer> list = query.list(); System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联 }

Criteria查询(单表条件查询)

Hibernate自创的无语句面向对象查询

1、基本查询

    //基本查询
public void fun1(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//------------------------------------------- //查询所有的Customer对象
Criteria criteria = session.createCriteria(Customer.class); List<Customer> list = criteria.list(); System.out.println(list);      //Customer c = (Customer) criteria.uniqueResult(); //-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联 }

2、条件查询

    //条件查询
//HQL语句中,不可能出现任何数据库相关的信息的
// > gt
// >= ge
// < lt
// <= le
// == eq
// != ne
// in in
// between and between
// like like
// is not null isNotNull
// is null isNull
// or or
// and and
public void fun2(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//创建criteria查询对象
Criteria criteria = session.createCriteria(Customer.class);
//添加查询参数 => 查询cust_id为1的Customer对象
criteria.add(Restrictions.eq("cust_id", 1l));
//执行查询获得结果
Customer c = (Customer) criteria.uniqueResult();
System.out.println(c);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联 }

3、分页查询

    //分页查询
public void fun3(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//创建criteria查询对象
Criteria criteria = session.createCriteria(Customer.class);
//设置分页信息 limit ?,?
criteria.setFirstResult(1);
criteria.setMaxResults(2);
//执行查询
List<Customer> list = criteria.list(); System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联 }

4、设置查询总记录数

    //查询总记录数
public void fun4(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//创建criteria查询对象
Criteria criteria = session.createCriteria(Customer.class);
//设置查询的聚合函数 => 总行数
criteria.setProjection(Projections.rowCount());
//执行查询
Long count = (Long) criteria.uniqueResult(); System.out.println(count);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联 }

原生SQL查询(复杂的业务查询)

1、基本查询

返回数组List

    //基本查询
public void fun1(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1 书写sql语句
String sql = "select * from cst_customer"; //2 创建sql查询对象
SQLQuery query = session.createSQLQuery(sql); //3 调用方法查询结果
List<Object[]> list = query.list();
//query.uniqueResult(); for(Object[] objs : list){
System.out.println(Arrays.toString(objs));
} //-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联 }

返回对象List

    //基本查询
public void fun2(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1 书写sql语句
String sql = "select * from cst_customer"; //2 创建sql查询对象
SQLQuery query = session.createSQLQuery(sql);
//指定将结果集封装到哪个对象中
query.addEntity(Customer.class); //3 调用方法查询结果
List<Customer> list = query.list(); System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联 }

2、条件查询

    //条件查询
public void fun3(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1 书写sql语句
String sql = "select * from cst_customer where cust_id = ? "; //2 创建sql查询对象
SQLQuery query = session.createSQLQuery(sql); query.setParameter(0, 1l);
//指定将结果集封装到哪个对象中
query.addEntity(Customer.class); //3 调用方法查询结果
List<Customer> list = query.list(); System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}

3、分页查询

    //分页查询
public void fun4(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1 书写sql语句
String sql = "select * from cst_customer limit ?,? "; //2 创建sql查询对象
SQLQuery query = session.createSQLQuery(sql); query.setParameter(0, 0);
query.setParameter(1, 1);
//指定将结果集封装到哪个对象中
query.addEntity(Customer.class); //3 调用方法查询结果
List<Customer> list = query.list(); System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}

总结

一.hibernate中的实体创建规则

  1. 对象必须有oid.
  2. 对象中的属性,尽量使用包装类型
  3. 不使用final修饰类
  4. 提供get/set方法....

二.hibernate主键生成策略(7种)

  1. increment: 查询最大值.再加1
  2. identity: 主键自增.
  3. sequence:Oracle使用的
  4. hilo: hibernate自己实现自增算法
  5. native: 根据所选数据库三选一
  6. uuid: 随机字符串
  7. assigned: 自然主键.

三.对象的三种状态

  1. 瞬时状态:没有id,没有在session缓存中.
  2. 持久化状态:有id,再session缓存中。
  3. 托管|游离状态:有id,不在session缓存中.

持久化: 持久化状态的对象,会在事务提交时,自动同步到数据库中.我们使用hibernate的原则.就是将对象转换为持久化状态.
四.一级缓存
缓存: 为了提高效率.

一级缓存:为了提高效率.session对象中有一个可以存放对象的集合.

  • 查询时: 第一次查询时.会将对象放入缓存.再次查询时,会返回缓存中的.不再查询数据库.
  • 修改时: 会使用快照对比修改前和后对象的属性区别.只执行一次修改.

五.事务管理
1、如何配置数据库隔离级别

  • 1 读未提交
  • 2 读已提交
  • 4 可重复读
  • 8 串行化

2、指定session与当前线程绑定 hibernate.current_session_context_class thread
六.批量查询

  • HQL 面向对象的语句查询
  • Criteria 面向对象的无语句查询
  • SQL 原生SQL

Hibernate学习笔记二的更多相关文章

  1. Hibernate学习笔记二:Hibernate缓存策略详解

    一:为什么使用Hibernate缓存: Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序访问物理数据库的频次,从而提高应用程序的性能. 缓存内的数据是对物理数据源的复制,应用 ...

  2. Hibernate学习笔记二:常用映射配置

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6760895.html 一:单向一对一 常用唯一外键的方法来配置单向一对一关系. 1:实体关系 类A中有类B对象 ...

  3. Hibernate学习笔记(二)

    2016/4/22 23:19:44 Hibernate学习笔记(二) 1.1 Hibernate的持久化类状态 1.1.1 Hibernate的持久化类状态 持久化:就是一个实体类与数据库表建立了映 ...

  4. JDBC学习笔记二

    JDBC学习笔记二 4.execute()方法执行SQL语句 execute几乎可以执行任何SQL语句,当execute执行过SQL语句之后会返回一个布尔类型的值,代表是否返回了ResultSet对象 ...

  5. Hibernate学习笔记(一)

    2016/4/18 19:58:58 Hibernate学习笔记(一) 1.Hibernate框架的概述: 就是一个持久层的ORM框架. ORM:对象关系映射.将Java中实体对象与关系型数据库中表建 ...

  6. Hibernate 学习笔记一

    Hibernate 学习笔记一 今天学习了hibernate的一点入门知识,主要是配置domain对象和表的关系映射,hibernate的一些常用的配置,以及对应的一个向数据库插入数据的小例子.期间碰 ...

  7. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  8. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  9. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

随机推荐

  1. ORA-00904:标识符无效

    1.错误描述 ORA-00904:"TTT"."RN":标识符无效 00904 . 00000 - "%s:invalid identifier&qu ...

  2. python实现简单排序算法

    算法 递归两个特点: 调用自身 有穷调用 计算规模越来越小,直至最后结束 用装饰器修饰一个递归函数时会出现问题,这个问题产生的原因是递归的函数也不停的使用装饰器.解决方法是,只让装饰器调用一次即可,那 ...

  3. C#图解教程 第二十二章 异常

    异常 什么是异常try语句 处理异常 异常类catch 子句使用特定catch子句的示例catch子句段finally块为异常寻找处理程序更进一步搜索 一般法则搜索调用栈的示例 抛出异常不带异常对象的 ...

  4. C#隐式转换和显示转换举例--C#基础

    高精度的数据类型转换为低精度的数据类型是显示转换,低精度的转换为高精度的是隐式转换. 温馨提示:不能说强制类型转换是从低精度到高精度. int a=666;float b=(float)a: 由a到b ...

  5. [APIO2009]会议中心

    [APIO2009]会议中心 题目大意: 原网址与样例戳我! 给定n个区间,询问以下问题: 1.最多能够选择多少个不相交的区间? 2.在第一问的基础上,输出字典序最小的方案. 数据范围:\(n \le ...

  6. 【BZOJ1717】产奶的模式(后缀数组)

    [BZOJ1717]产奶的模式(后缀数组) 题面 权限题 hihocoder 洛谷 题解 \(hihocoder\)里面讲的非常好了 这题要求的就是最长可重叠重复K次子串 所谓相同的子串 我们可以理解 ...

  7. 笔记-JS高级程序设计-基本概念篇

    1:JS中的一切(变量,函数名和操作符)都是区分大小写的 2:标识符(变量,函数,属性的名字,以及函数的参数),第一个字符必须是字母,下划线,或者美元$,书写方式采用驼峰式,不能将关键字作为标识符. ...

  8. Postman使用小技巧

    Postman使用小技巧 2017-09-13 目录: 1 自动生成流水号2 保存响应结果 1 自动生成流水号 返回 为了让接口具有幂等性,在设计时,往往有一个字段是唯一的(比如流水号,交易编号等), ...

  9. IIS支持PHP文件解析

    打开IIS程序映射 添加模块映射 请求路径为:*.php 模块为:FastCgiModule 可执行路径选择 php-cgi.exe 名称随意写

  10. NOIP2015 D2T3 洛谷2680 BZOJ4326 运输计划 解题报告

    前言:个人认为这是历年NOIP中比较简单的最后一题了,因此将自己的思路与大家分享. 题目大意: 给一棵无根树,给出m条路径.允许将树上的一条边的权值改为0.求m条路径长度最大值的最小值.n,m< ...