MyBatis与Spring的整合

1、整合环境搭建

1)、要实现MyBatis与Spring的整合,很明显需要这两个框架的JAR包,但是只使用这两个框架中所提供的JAR包是不够的,还需要其他的JAR包来配合使用,整合时所需准备的JAR包具体如下。Spring框架所需的JAR包

注意:核心容器依赖的commons-logging的JAR在MyBatis框架的lib包中已经包含

2)、MyBatis框架所需的JAR包:(共13个)

3)、MyBatis与Spring整合的中间JAR:mybatis-spring-1.3.1.jar

4)、数据库驱动JAR(MySQL):mysql-connector-java-5.1.40-bin.jar

5)、数据源所需JAR(DBCP数据库连接池):commons-dbcp2-2.1.1.jar、commons-pool2-2.4.2.jar

6)、编写配置文件:

①创建项目,引入JAR包;

②编写db.properties ;

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=******
jdbc.maxTotal=30
jdbc.maxIdle=10
jdbc.initialSize=5

#密码自己设置

编写Spring配置文件applicationContext.xml;

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> <!--1、读取db.properties文件的位置 -->
<context:property-placeholder location="classpath:db.properties"/> <!-- 2、配置数据源 -->
<bean id="dataSourceID" class="org.apache.commons.dbcp2.BasicDataSource"> <!--2.1、数据库驱动 -->
<property name="driverClassName" value="${jdbc.driver}" /> <!--2.2、连接数据库的url -->
<property name="url" value="${jdbc.url}" /> <!--2.3、连接数据库的用户名 -->
<property name="username" value="${jdbc.username}" /> <!--2.4、连接数据库的密码 -->
<property name="password" value="${jdbc.password}" /> <!--2.5、最大连接数 -->
<property name="maxTotal" value="${jdbc.maxTotal}" /> <!--2.6、最大空闲连接 -->
<property name="maxIdle" value="${jdbc.maxIdle}" /> <!--2.7、初始化连接数 -->
<property name="initialSize" value="${jdbc.initialSize}" /> </bean> <!-- 3、事务管理器,依赖于数据源 -->
<bean id="transactionManagerID" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSourceID" />
</bean> <!--4、开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManagerID"/> <!--5、配置MyBatis工厂来于Spring整合,
构建sqlSessionFactory是通过mybatis.spring包中提供的org.mybatis.spring.SqlSessionFactoryBean类配置的;
配置时通常需要2个参数:①数据源;②MyBatis的配置文件路径
-->
<bean id="sqlSessionFactoryID" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--5.1、注入数据源 -->
<property name="dataSource" ref="dataSourceID" /> <!--5.2、指定核心配置文件位置 :mybatis-config.xml-->
<property name="configLocation" value="classpath:mybatis-config.xml"/> </bean> <!--6、实例化Dao -->
<bean id="customerDaoID" class="com.itheima.dao.impl.CustomerDaoImpl">
<!-- 6.1、注入SqlSessionFactory对象实例-->
<property name="sqlSessionFactory" ref="sqlSessionFactoryID" />
</bean> <!-- 7、Mapper代理开发(基于MapperFactoryBean) -->
<!-- <bean id="customerMapperID" class="org.mybatis.spring.mapper.MapperFactoryBean"> 指定了接口mapperInterface和工厂sqlSessionFactory
<property name="mapperInterface" value="com.itheima.mapper.CustomerMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactoryID" /> </bean> --> <!-- 8、Mapper代理开发(基于MapperScannerConfigurer)
配置类路径:org.mybatis.spring.mapper.MapperScannerConfigurer
指定映射文件所在的包路径:com.itheima.mapper
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.itheima.mapper" />
</bean> <!-- 9、使用注解,开启扫描
Spring注解提供了另外一种高效的注解配置方式,(对包路径下的所有Bean文件进行扫描)
使用 context 命名空间 ,通知Spring扫描指定包下所有Bean类,进行注解解析
-->
<context:component-scan base-package="com.itheima.service" /> </beans>

编写MyBatis配置文件mybatis-config.xml;

 <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration> <!--1、配置别名:POJO类过多时,使用自动扫描包的形式定义别名
目的:在于减少全限定类名的冗余。
-->
<typeAliases>
<package name="com.itheima.po" />
</typeAliases> <!--2、配置Mapper的位置 -->
<mappers> <mapper resource="com/itheima/po/CustomerMapper.xml" /> <!-- Mapper接口开发方式 -->
<mapper resource="com/itheima/mapper/CustomerMapper.xml" /> </mappers>
</configuration>

引入log4j.properties。

# Global logging configuration
log4j.rootLogger=ERROR, stdout

# MyBatis logging configuration...
log4j.logger.com.itheima=DEBUG

# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

2、传统DAO方式的开发整合

1)、采用传统DAO开发方式进行MyBatis与Spring框架的整合时,可以使用mybatis-spring包中所提供的SqlSessionTemplate类SqlSessionDaoSupport类来实现。

2)、SqlSessionTemplate:是mybatis-spring的核心类,它负责管理MyBatis的SqlSession(会话对象)调用MyBatis的SQL方法。当调用SQL方法时,SqlSessionTemplate将会保证使用的SqlSession和当前Spring的事务是相关的。它还管理SqlSession的生命周期,包含必要的关闭、提交和回滚操作

3)、SqlSessionDaoSupport:是一个抽象支持类,它继承DaoSupport类,主要是作为DAO的基类来使用。可以通过SqlSessionDaoSupport类的getSqlSession()方法来获取所需的SqlSession
4)、实现持久层:

①客户持久化类:src/com/itheima/po/Customer.java

 package com.itheima.po;
/**
* 客户持久化类
*/
public class Customer {
private Integer id; // 主键id
private String username; // 客户名称
private String jobs; // 职业
private String phone; // 电话 public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getJobs() {
return jobs;
} public void setJobs(String jobs) {
this.jobs = jobs;
} public String getPhone() {
return phone;
} public void setPhone(String phone) {
this.phone = phone;
} @Override
public String toString() {
return "Customer [id=" + id + ", username=" + username + ", jobs=" + jobs + ", phone=" + phone + "]";
}
}

②创建客户映射(映射数据库表)文件:src/com/itheima/po/CustomerMapper.xml

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.itheima.po.CustomerMapper"> <!--根据id查询客户信息 -->
<select id="findCustomerById" parameterType="Integer"
resultType="customer">
<!-- 属性resultType:用于指定返回结果的类型,这里表示返回的数据是customer对象类型,
可见,其直接使用了别名,减少全限定名称的冗余。
相当于把 com.itheima.po.Customer 换成了customer
-->
select * from t_customer where id = #{id}
</select>
</mapper>

③在MyBatis的配置文件mybatis-config.xml中,配置映射文件src/com/itheima/po/CustomerMapper.xml

<mapper resource="com/itheima/po/CustomerMapper.xml" />

5)、实现DAO层

①创建Dao的接口:CustomerDao

package com.itheima.dao;
import com.itheima.po.Customer; public interface CustomerDao {
// 通过id查询客户
public Customer findCustomerById(Integer id);
}

②创建接口CustomerDao的实现类:src/com/itheima/dao/impl/CustomerDaoImpl.java

 package com.itheima.dao.impl;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import com.itheima.dao.CustomerDao;
import com.itheima.po.Customer; /* CustomerDaoImpl类继承了SqlSessionDaoSupport类,并实现了CustomerDao接口。
* 其中SqlSessionDaoSupport类在使用时需要一个SqlSessionFactory或一个SqlSessionTemplate对象
* 所以需要Spring给SqlSessionDaoSupport类的子类对象注入一个SqlSessionFactory或SqlSessionTemplate。
* 这样子类中就能通过调用SqlSessionDaoSupport类的getSqlSession()方法来获取SqlSession对象,并使用SqlSession对象中的方法。
*
*/ public class CustomerDaoImpl extends SqlSessionDaoSupport implements CustomerDao {
// 通过id查询客户
public Customer findCustomerById(Integer id) {
return this.getSqlSession().selectOne("com.itheima.po.CustomerMapper.findCustomerById", id);
}
}

③整合测试:src/com/itheima/test/DaoTest.java

 package com.itheima.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
import com.itheima.dao.CustomerDao;
import com.itheima.mapper.CustomerMapper;
import com.itheima.po.Customer;
/**
* DAO测试类
*/
public class DaoTest {
@Test
public void findCustomerByIdDaoTest(){
ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml");
// 根据容器中Bean的id来获取指定的Bean
// CustomerDao customerDao = (CustomerDao) act.getBean("customerDaoID"); //Spring获取Bean的另一种方式,这种方式不再需要进行强制类型转换了
CustomerDao customerDao = act.getBean(CustomerDao.class);
Customer customer = customerDao.findCustomerById(1);
System.out.println(customer);
}
}

④测试结果:

3、Mapper接口方式的开发整合

1)、在MyBatis+Spring的项目中,虽然使用传统的DAO开发方式可以实现所需功能,但是采用这种方式在实现类中会出现大量的重复代码在方法中也需要指定映射文件中执行语句的id,并且不能保证编写时id的正确性(运行时才能知道)。为此,我们可以使用MyBatis提供的另外一种编程方式,即使用Mapper接口编程

2)、基于MapperFactoryBean的整合

a)、MapperFactoryBean是MyBatis-Spring团队提供的一个用于根据Mapper接口生成Mapper对象的类,该类在Spring配置文件中使用时可以配置以下参数:

mapperInterface:用于指定接口
SqlSessionFactory:用于指定SqlSessionFactory
SqlSessionTemplate:用于指定SqlSessionTemplate。如果与SqlSessionFactory同时设定,则只会启用SqlSessionTemplate

b)、实操MapperFactoryBean是如何来实现MyBatis与Spring的整合:

创建CustomerMapper接口即对应的映射文件:(注意此处就与上面的操作不同了)src/com/itheima/mapper--->CustomerMapper.java

 package com.itheima.mapper;

 import java.lang.Integer;
import com.itheima.po.Customer;
public interface CustomerMapper { // 创建CustomerMapper接口 // 通过id查询客户
public Customer findCustomerById(Integer id); // 添加客户
public void addCustomer(Customer customer); }

②src/com/itheima/mapper--->CustomerMapper.xml

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.itheima.mapper.CustomerMapper"> <!--1、根据id查询客户信息,返回类型是customer类型
Mapper接口中的方法名和Mapper.xml中定义的每个执行语句的id相同!!!
-->
<select id="findCustomerById" parameterType="Integer"
resultType="customer">
select * from t_customer where id = #{id}
</select> <!--2、添加客户信息,参数类型是 customer类型-->
<insert id="addCustomer" parameterType="customer">
insert into t_customer(username,jobs,phone)
values(#{username},#{jobs},#{phone})
</insert> </mapper>

③在MyBatis的配置文件mybatis-config.xml中,配置新的映射文件src/com/itheima/mapper/CustomerMapper.xml

<mapper resource="com/itheima/mapper/CustomerMapper.xml" />

④在Spring的配置文件中,创建CustomerMapper的Bean实例id

   <!-- 7、Mapper代理开发(基于MapperFactoryBean) -->
<bean id="customerMapperID" class="org.mybatis.spring.mapper.MapperFactoryBean"> <!-- 指定了接口mapperInterface和工厂sqlSessionFactory -->
<property name="mapperInterface" value="com.itheima.mapper.CustomerMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactoryID" /> </bean>

⑤单元测试:

    @Test
public void findCustomerByIdMapperTest(){
ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml");
CustomerMapper customerMapper = act.getBean(CustomerMapper.class);
Customer customer = customerMapper.findCustomerById(1);
System.out.println(customer);
}

⑥测试结果:

c)、Mapper接口编程方式只需要编写Mapper接口相当于DAO接口),然后由MyBatis框架根据接口的定义创建接口的动态代理对象,等同于DAO接口的实现类

3)、虽然使用Mapper接口编程的方式很简单,但是在具体使用时还是需要遵循一些规范。

a)、Mapper接口的名称对应的Mapper.xml映射文件的名称必须一致

b)、Mapper.xml文件中的namespaceMapper接口类路径相同。(即接口文件和映射文件需要放在同一个包中

c)、注意:Mapper接口中的方法名和Mapper.xml中定义的每个执行语句的id相同

d)、Mapper接口中方法的输入参数类型要和Mapper.xml中定义的每个sql的parameterType的类型相同。

e)、Mapper接口方法的输出参数类型要和Mapper.xml中定义的每个sql的resultType的类型相同。

4)、基于MapperScannerConfigurer的整合

a)、在实际的项目中,DAO层会包含很多接口,如果每一个接口都在Spring配置文件中配置,不但会增加工作量,还会使得Spring配置文件非常臃肿。为此,可以采用自动扫描的形式来配置MyBatis中的映射器——采用MapperScannerConfigurer类

b)、MapperScannerConfigurer类在Spring配置文件中可以配置以下属性:

basePackage:指定映射接口文件所在的包路径,当需要扫描多个包时可以使用分号或逗号作为分隔符。指定包路径后,会扫描该包及其子包中的所有文件
annotationClass:指定了要扫描的注解名称,只有被注解标识的类才会被配置为映射器
sqlSessionFactoryBeanName:指定在Spring中定义的SqlSessionFactory的Bean名称。
sqlSessionTemplateBeanName:指定在Spring中定义的SqlSessionTemplate的Bean名称。如果定义此属性,则sqlSessionFactoryBeanName将不起作用。
markerInterface:指定创建映射器的接口

c)、MapperScannerConfigurer的使用非常简单,只需要在Spring的配置文件中编写如下代码:

<!-- Mapper代理开发(基于MapperScannerConfigurer) -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.itheima.mapper" />
</bean>

d)、通常情况下,MapperScannerConfigurer在使用时只需通过basePackage属性指定需要扫描的包即可,Spring会自动的通过包中的接口来生成映射器。这使得开发人员可以在编写很少代码的情况下,完成对映射器的配置,从而提高开发效率。对MapperScannerConfigurer进行测试可得与上面相同的结果。

4、 测试事务

1)、在项目中,Service层既是处理业务的地方,又是管理数据库事务的地方。对事务进行测试:

a)、创建Service层

b)、在Service层编写添加客户操作的代码

c)、有意地添加一段异常代码(如int i = 1/0;)来模拟现实中的意外情况

d)、编写测试方法,调用业务层的添加方法。这样,程序在执行到错误代码时就会出现异常

2)、在没有事务管理的情况下,即使出现了异常,数据也会被存储到数据表中;如果添加了事务管理,并且事务管理的配置正确,那么在执行上述操作时,所添加的数据将不能够插入到数据表中

3)在CustomerMapper接口中,添加addCustomer()方法,然后在CustomerMapper映射文件中编写执行插入操作的SQL配置,具体看上面的代码。

①创建业务接口:src/com/itheima/service/CustomerService.java

package com.itheima.service;
import com.itheima.po.Customer;
public interface CustomerService { // 业务层:创建CustomerService接口
public void addCustomer(Customer customer);
}

②创建业务接口的实现类:com/itheima/service/impl/CustomerServiceImpl.java

 package com.itheima.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.itheima.mapper.CustomerMapper;
import com.itheima.po.Customer;
import com.itheima.service.CustomerService; // 使用Spring的注解@Service来标识业务层的类
@Service // 使用@Transactional注解来标识事务处理的类
@Transactional
public class CustomerServiceImpl implements CustomerService { //通过@Autowired注解注入CustomerMapper
@Autowired
private CustomerMapper customerMapper; //添加客户
public void addCustomer(Customer customer) {
// 调用接口中的addCustomer()方法
this.customerMapper.addCustomer(customer); //模拟添加操作后系统突然出现的异常问题
int i = 1 / 0;
}
}

③在Spring的配置文件中,编写开启注解扫描的配置代码:

   <!-- 9、使用注解,开启扫描
Spring注解提供了另外一种高效的注解配置方式,(对包路径下的所有Bean文件进行扫描)
使用 context 命名空间 ,通知Spring扫描指定包下所有Bean类,进行注解解析
-->
<context:component-scan base-package="com.itheima.service" />

④测试类:com/itheima/test/TransactionTest.java

 package com.itheima.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.itheima.po.Customer;
import com.itheima.service.CustomerService;
/**
* 测试事务
*/
public class TransactionTest {
public static void main(String[] args) {
ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml");
CustomerService customerService = act.getBean(CustomerService.class); Customer customer = new Customer();
customer.setUsername("zhangsan");
customer.setJobs("manager");
customer.setPhone("13233334444");
customerService.addCustomer(customer);
}
}

⑤先将@Transactional注释掉后运行测试类的结果如下:

4)、虽抛出异常,但查询数据库mybatis中的t_customer表可知,新添加的数据已经存储在该表中,这就验证了在没有事务管理的情况下,即使出现了异常,数据也会被存储到数据表中

5)、将注释去掉,再次执行并查询表如图所示:

这就说明项目中配置的事务是正确的。

个人总结:

本章详细介绍了如何实现SM的整合步骤。个人认为基于Mapper的接口方式实现MyBatis与Spring的整合是相对比较方便和简单的,至少在编码方面能提高开发者的工作效率,但实现DAO层的整合也需充分理解,总之,实践是检验真知的标准!

Java EE学习笔记(十)的更多相关文章

  1. java jvm学习笔记十(策略和保护域)

    欢迎转载请说明出处:http://blog.csdn.net/yfqnihao/article/details/8271415 前面一节,我们做了一个简单的实验,来说明什么是策略文件,在文章的最后,也 ...

  2. java jvm学习笔记十二(访问控制器的栈校验机制)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 本节源码:http://download.csdn.net/detail/yfqnihao/4863854 这一节,我们 ...

  3. Java基础学习笔记十二 类、抽象类、接口作为方法参数和返回值以及常用API

    不同修饰符使用细节 常用来修饰类.方法.变量的修饰符 public 权限修饰符,公共访问, 类,方法,成员变量 protected 权限修饰符,受保护访问, 方法,成员变量 默认什么也不写 也是一种权 ...

  4. Java基础学习笔记十五 集合、迭代器、泛型

    Collection 集合,集合是java中提供的一种容器,可以用来存储多个数据. 在前面的学习中,我们知道数据多了,可以使用数组存放或者使用ArrayList集合进行存放数据.那么,集合和数组既然都 ...

  5. Java基础学习笔记十八 异常处理

    什么是异常?Java代码在运行时期发生的问题就是异常. 在Java中,把异常信息封装成了一个类.当出现了问题时,就会创建异常类对象并抛出异常相关的信息(如异常出现的位置.原因等). 异常的继承体系 在 ...

  6. Java基础学习笔记十九 IO

    File IO概述 回想之前写过的程序,数据都是在内存中,一旦程序运行结束,这些数据都没有了,等下次再想使用这些数据,可是已经没有了.那怎么办呢?能不能把运算完的数据都保存下来,下次程序启动的时候,再 ...

  7. Java基础学习笔记十九 File

    IO概述 回想之前写过的程序,数据都是在内存中,一旦程序运行结束,这些数据都没有了,等下次再想使用这些数据,可是已经没有了.那怎么办呢?能不能把运算完的数据都保存下来,下次程序启动的时候,再把这些数据 ...

  8. Java EE学习笔记(七)

    MyBatis的核心配置 1.MyBatis的核心对象 1).SqlSessionFactory是MyBatis框架中十分重要的对象,它是单个数据库映射关系经过编译后的内存镜像,其主要作用是创建Sql ...

  9. Java基础学习笔记十 Java基础语法之final、static、匿名对象、内部类

    final关键字 继承的出现提高了代码的复用性,并方便开发.但随之也有问题,有些类在描述完之后,不想被继承,或者有些类中的部分方法功能是固定的,不想让子类重写.可是当子类继承了这些特殊类之后,就可以对 ...

随机推荐

  1. boobmarklet

    bookmarklet ,一般都称呼为小书签.它是一段 JavaScript 脚本,一般网络上的小书签都是一个链接,它的安装非常简单,只需要把链接拖到你的收藏夹里. 利用它,可以实现一些页面优化.性能 ...

  2. Windows下Anaconda安装 python + tensorflow

    下载安装Anaconda 首先下载Anaconda,可以从清华大学的镜像网站进行下载. 安装Anaconda,注意安装时不要将添加环境变量的选项取消掉. 安装完成之后,在安装目录下cmd,输入 con ...

  3. ScrollView cannot scroll in Slidinguppanellayout 解决办法

    xml源码如下 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:an ...

  4. python2 + selenium + eclipse 中,配置好runserver 127.0.0.1:9000,运行的时候,报错

    python2 + selenium + eclipse 中,配置好runserver 127.0.0.1:9000,运行的时候,报错,如图: 原因:       google发现是WSGI appl ...

  5. [nyoj737]石子归并(区间dp入门题)

    题意:有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆.求出总的代价最小值 ...

  6. There&nbsp;is&nbsp;no&nbsp;resul…

    There is no result type defined for type 'json' mapped with name 'success'. 这个错误是json初学者很容易遇到的错误:现在把 ...

  7. 条款32:确定你的public继承塑模出is-a的关系

    Make sure public inheritance models "is –a " 如果令clsss D 以public的形式继承class B,你便是告诉编译器说,每一个类 ...

  8. 《精通Spring4.X企业应用开发实战》读后感第三章

  9. 《Java多线程编程核心技术》读后感(十五)

    线程的状态 线程对象在不同的运行时期有不同的状态,状态信息就存在与State枚举类中. 验证New,Runnable,Terminated new:线程实例化后还从未执行start()方法时的状态 r ...

  10. UVaLive 4256 Salesmen (简单DP)

    题意:给一个无向连通图,和一个序列,修改尽量少的数,使得相邻两个数要么相等,要么相邻. 析:dp[i][j] 表示第 i 个数改成 j 时满足条件.然后就很容易了. 代码如下: #pragma com ...