Spring、SpringMVC、SpringData + JPA 整合详解
原创播客,如需转载请注明出处。原文地址:http://www.cnblogs.com/crawl/p/7759874.html
----------------------------------------------------------------------------------------------------------------------------------------------------------
笔记中提供了大量的代码示例,需要说明的是,大部分代码示例都是本人所敲代码并进行测试,不足之处,请大家指正~
本博客中所有言论仅代表博主本人观点,若有疑惑或者需要本系列分享中的资料工具,敬请联系 qingqing_crawl@163.com
-----------------------------------------------------------------------------------------------------------------------------------------------------------
前言:之前详细讲解过了 JPA 和 SpringData,包括 Spring 和 SpringMVC 也进行了详细的讲述。很早就想来一个整合了,因为事情比较多,所以就一直拖着。
那么现在就来说说 Spring + SpringMVC + SpringData + JPA(下文中简写为 SSSP) 的整合,SSSP 的整合之后再来写一个 CRUD 的小案例,楼主不打算把增删改查都来一遍了,只介绍一个查询所有员工信息,然后分页显示即可。大家可以对比在 JavaWeb 的过程中写的分页查询,看一看是否简单的许多。下面进行详细的介绍~
一、加入 Spring
1. 首先当然要新建一个动态的 WEB 的工程了,取名 sssp
2. 加入 Spring 的 jar 包,观察这些 jar 包,大家可以发现其中既包含了 Spring 的 jar 包,也包含了 SpringMVC 的 jar 包
3. web.xml 中配置启动 Spring IOC 的 ContextLoaderListener:
<!-- 配置启动 Spring IOC 的 Listener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param> <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
其中 楼主配置的 Spring 的配置文件在 classpath 下,取名为 applicationContext.xml
4. 这一步当然就是在类路径下创建 Spring 的配置文件:applicationContext.xml 了,在这里先创建好,稍后进行配置。
二、加入 SpringMVC
1. 首先呢肯定要想到的是先导入 jar 包,这里在加入 Spring 的时候已经导入,前面也已经做了说明。
2. web.xml 中配置 SpringMVC 的 DispatcherServlet
<!-- 配置 SpringMVC 的 DispatcherServlet -->
<!-- 使用默认的 SpringMVC 的配置文件,为 [servlet-name]-servlet.xml 放到 WEB-INF 目录下 -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet> <servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
在这里呢 楼主删除了一部分配置,我们使用默认的 SpringMVC 的配置文件,这个默认的 SpringMVC 的配置文件的名字为 :springDispatcherServlet-servlet.xml ,需要注意的是,若使用默认的配置文件,文件的位置需要在 WEB-INF 目录下
3. 在 WEB-INF 目录下新建 SpringMVC 的配置文件: springDispatcherServlet-servlet.xml (注意:楼主的 Eclipse 中是安装了 Spring 插件的,实质上楼主使用 Spring 的插件创建了 SpringMVC 的配置文件,只是文件名不同而已)
4. 然后我们对 SpringMVC 的配置文件 springDispatcherServlet-servlet.xml 进行配置
1)加入命名空间,因为我们在新建配置文件的时候没有加入命名空间,所以先加入 context 和 mvc 的命名空间。那么如何加入呢,当我们打开 SpringMVC 的配置文件后,大家可以看到文件的左下角有一些选项卡(如下面图片所示),大家点击第二个选项 Namespaces,
点开后大家吧 context 和 mvc 选项挑上对勾即可。
2)配置自动扫描的包
<!-- 配置自动扫描的包:只扫描有 @Controller 和 @ControllerAdvice 注解的包 -->
<context:component-scan base-package="com.software.sssp" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" />
</context:component-scan>
在配置自动扫描的包时,楼主使用了 context:include-filter 子标签,目的就是让 SpringMVC 只扫描带有 @Controller 和 @ControllerAdvice 注解的包中的类,为什么要这样做呢?因为我们加入 Spring 的时候只创建了 Spring 的配置文件,还没有进行配置,一会我们配置的时候,也会先配置 Spring 的 IOC 扫描的包,这样就有可能出现某些包 Spring 的容器扫描了一遍,SpringMVC 又扫描了一遍,这样就会造成有些对象会创建多次,造成资源的浪费,配置 context:include-filter 标签就是为了解决这个问题,让 Spring 和 SpringMVC 只扫描各自关注的包即可。
3)配置视图解析器:
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
这里我们使用的是默认的 InternalResourceViewResolver 视图解析器,然后配置了一个前缀,一个后缀。这里 InternalResourceViewResolver 视图解析器是如何解析工作的,我们配置的 prefix 和 suffix 有什么用,在楼主的 深入浅出 SpringMVC - 1 中已经详细介绍,大家可以自行查看。
4)既然在配置视图解析器的时候我们配置了 prefix 和 suffix ,那么就需要我们在 WEB-INF 目录下新建一个 views 文件夹,用来存放我们需要的 jsp 页面
5)然后我们把 SpringMVC 的两个标配配置上:处理静态请求资源的 <mvc:default-servlet-handler/> 以及 <mvc:annotation-driven></mvc:annotation-driven>
<mvc:default-servlet-handler/>
<mvc:annotation-driven></mvc:annotation-driven>
三、加入 JPA
1)使用 JPA 需要导入 HIbernate 和 JPA 的 jar 包
Hibernate 的 jar 包:
JPA 的 jar 包:
2)加入 c3p0 和 MySQL 的驱动
c3p0:
MySQL 驱动:
3)其实在这个小案例中楼主还是用了 JPA 的二级缓存,所以还加入了二级缓存相关的 jar 包,和配置文件,这里就不详细说明了。
关于 JPA 的知识呢,楼主也写了几篇播客,大家可以参考:
JPA + SpringData 操作数据库原来可以这么简单 ---- 深入了解 JPA - 1
JPA + SpringData 操作数据库原来可以这么简单 ---- 深入了解 JPA - 2
JPA + SpringData 操作数据库原来可以这么简单 ---- 深入了解 JPA - 3
四、配置 Spring 的配置文件
1.加入 context 和 tx 的命名空间,关于如何加入命名空间,上文中进行了详细的说明,此处不再赘述。
2.配置自动扫描的包
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.software.sssp">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
注意,此处我们使用 context:exclude-filter 来设置不进行扫描的包,原因在上文中也已经详细说明。
3.配置数据源
1)在类路径下新建一个 db.properties 文件,设置连接数据库的基本信息,在这楼主只设置必须的属性
jdbc.user=root
jdbc.password=qiqingqing
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/sssp
2)在 Spring 的配置文件中导入 db.properties 文件,进行数据源的配置
<!-- 配置数据源 -->
<!-- 导入资源配置文件 -->
<context:property-placeholder location="classpath:db.properties"/> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
</bean>
至此数据源的配置已经结束,在楼主的博客中,楼主不只强调了一次进行分步测试或单元测试的重要性,可以为我们避免不必要的麻烦,接下来就看看我们的数据源是否配置成功。楼主新建一个测试类 SSSPTest,先来测试一下数据源:
public class SSSPTest { private ApplicationContext ctx = null; {
ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
} @Test
public void testDataSource() throws SQLException {
DataSource dataSource = ctx.getBean(DataSource.class);
System.out.println(dataSource.getConnection());
} }
执行 testDataSource 方法,结果为:
这就证明我们的数据源获取成功!
4. 配置 JPA 的 EntityManagerFactory
<!-- 配置 JPA 的 EntityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="packagesToScan" value="com.software.sssp"></property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop> <prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
</props>
</property>
<!-- 配置使用二级缓存的模式:只允许带有 @Cacheable 的类使用二级缓存 -->
<property name="sharedCacheMode" value="ENABLE_SELECTIVE"></property>
</bean>
解释一下,第 3 行配置数据源,4 行配置扫描的包,5 行配置 JPA 提供商的适配器,8 行配置 JPA 实现产品即 Hibernate 的基本属性,22 行配置二级缓存相关。
5. 配置 JPA 的注解和基于注解的事务操作
<!-- 配置 JPA 的注解 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean> <!-- 配置基于注解的事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
到这里 JPA 的配置已经完成了,我们再来测试一下 JPA 是否配置成功
我们新建我们需要的两个实体类,Employee 和 Department,为它们添加基本的 JPA 注解
package com.software.sssp.entity; import java.util.Date; import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType; import org.springframework.format.annotation.DateTimeFormat; @Table(name="SSSP_EMPLOYEES")
@Entity
public class Employee { private Integer id; private String lastName; private String email; @DateTimeFormat(pattern="yyyy-MM-dd")
private Date Birth; private Date createTime; private Department department; @GeneratedValue
@Id
public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getLastName() {
return lastName;
} public void setLastName(String lastName) {
this.lastName = lastName;
} public String getEmail() {
return email;
} public void setEmail(String email) {
this.email = email;
} @Temporal(TemporalType.DATE)
public Date getBirth() {
return Birth;
} public void setBirth(Date birth) {
Birth = birth;
} @Temporal(TemporalType.TIMESTAMP)
public Date getCreateTime() {
return createTime;
} public void setCreateTime(Date createTime) {
this.createTime = createTime;
} @JoinColumn(name="DEPARTMENT_ID")
@ManyToOne(fetch=FetchType.LAZY)
public Department getDepartment() {
return department;
} public void setDepartment(Department department) {
this.department = department;
} }
package com.software.sssp.entity; import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table; @Cacheable
@Table(name="SSSP_DEPARTMENT")
@Entity
public class Department { private Integer id; private String departmentName; @GeneratedValue
@Id
public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getDepartmentName() {
return departmentName;
} public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
} }
然后同样是在 SSSPTest 中执行测试数据源的那个方法,大家会发现,数据库中多出了两张表
这就证明 JPA 配置成功
6. 加入 SpringData
<!-- 配置 SpringData -->
<jpa:repositories base-package="com.software.sssp"
entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>
五、web.xml 中杂项配置
1. 因为案例中会用到中文,我们配置一个字符编码的过滤器
<!-- 配置字符编码过滤器 -->
<!-- 字符编码过滤器必须配置在所有过滤器的最前面! -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter> <filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
需要注意的是,这个字符编码过滤器需要配置在所有过滤器的最前面。
2.因为我们的案例中使用 ResultFul 风格的 URL ,所以在配置一个将 POST 请求转换为 PUT DELETE 请求的 Filter
<!-- 配置将 POST 请求转换为 PUT DELETE 请求的 Filter -->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter> <filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
至此呢,我们的 SSSP 整合所有的配置和测试就完成了!
六、实现分页操作
SSSP 整合完成后呢,数据库中也生成了对应的数据表,楼主向数据库中写入了十几条测试数据。然后我们实现分页查询显示的效果。
思路分析:
1.DAO 层:直接调用 PagingAndSortingRepository 的 findAll(Pageable pageable) 方法,返回 Page 对象即可(注:关于 PagingAndSortingRepository 的使用楼主在介绍 SpringData 的博客已经详细讲解过了)。
2.Service 层:把 Controller 传入的 pageNo 和 pageSize 封装成为 Pageable 对象,然后调用 DAO 层的方法即可。
3.Controller 层:获取 pageNo 并对 pageNo 进行校验,然后调用 Service 层的方法返回 Page 对象,将 Page 对象放入到 Request 域中进行页面转发。
4.JSP 页面:数据的显示
思路分析完成之后进行编码实现。
EmployeeRepository:只定义一个继承 JpaRepository 的接口即可。
public interface EmployeeRepository extends JpaRepository<Employee, Integer> { }
EmployeeService:
@Service
public class EmployeeService { @Autowired
private EmployeeRepository employeeRepository; @Transactional(readOnly=true)
public Page<Employee> getPage(int pageNo, int pageSize) {
PageRequest pageable = new PageRequest(pageNo - 1, pageSize);
return employeeRepository.findAll(pageable);
} }
定义了一个 getPage 方法,为该方法添加只读的事务操作注解,然后调用 DAO 的 findAll() 方法即可,注意 pageNo 是从 0 开始的,所以要对传入的 pageNo 进行 - 1 的处理。
EmployeeHandler:
@Controller
public class EmployeeHandler { @Autowired
private EmployeeService employeeService; @RequestMapping("/emps")
public String list(@RequestParam(value="pageNo", required=false, defaultValue="1") String pageNoStr,
Map<String, Object> map) { int pageNo = 1; try {
//对 pageNo 的校验
pageNo = Integer.parseInt(pageNoStr);
if(pageNo < 0) {
pageNo = 1;
}
} catch (Exception e) {} Page<Employee> page = employeeService.getPage(pageNo, 5);
map.put("page", page); return "emp/list";
} }
创建了一个 list 方法,传入的 pageNoStr 被定义成了 String 类型的,11 行定义了一个 int 型的 pageNo,将 pageNoStr 强转为 int 型,若传入的是一个非数值型的字符串,则会出异常,出了异常不必理会,pageNo 还是一开始定义的那个 pageNo,为 1。然后调用 Service 层的方法,定义 pageSize 为 5,得到 Page 对象,放入到 request 域中。
list.jsp 进行数据的显示即可:
<c:if test="${page == null || page.numberOfElements == 0 }">
<h3>没有员工记录!</h3>
</c:if> <c:if test="${page != null && page.numberOfElements > 0 }"> <table border="1" cellspacing="0" cellpadding="10"> <tr>
<th>Id</th>
<th>LastName</th> <th>Email</th>
<th>Birth</th> <th>CreateTime</th>
<th>DepartmentName</th> <th>Edit</th>
<th>Delete</th>
</tr> <c:forEach items="${page.content }" var="emp"> <tr>
<td>${emp.id }</td>
<td>${emp.lastName }</td> <td>${emp.email }</td>
<td>${emp.birth }</td> <td>${emp.createTime }</td>
<td>${emp.department.departmentName }</td> <td>
<a href="${pageContext.request.contextPath }/emp/${emp.id}">Edit</a>
</td>
<td>
<a href="${pageContext.request.contextPath }/emp/${emp.id}" class="delete">Delete</a>
<input type="hidden" value="${emp.lastName }">
</td>
</tr> </c:forEach> <tr>
<td colspan="8">
共 ${page.totalElements} 条记录
共 ${page.totalPages} 页
当前为 ${page.number + 1 } 页 <c:if test="${page.number + 1 > 1 }">
<a href="?pageNo=${page.number + 1 - 1 }">上一页</a>
</c:if> <c:if test="${page.number + 1 < page.totalPages}">
<a href="?pageNo=${page.number + 1 + 1 }">下一页</a>
</c:if>
</td>
</tr> </table> </c:if>
我们注意第 33 行,在显示 DepartmentName 时使用的是级联属性,为了提高效率,减少 SQL 语句,需要设置 Employee 中的 @ManyToOne(fetch=FetchType.LAZY),但是进行了如此设置使用级联属性会发生懒加载异常(添加了 @Transactional 注解的事务方法,entityManager 的作用范围是从方法开始到方法结束,使用 fetch 为 LAZY,获取的是一个代理对象,若再获取级联属性,则会发生懒加载异常),所以需要在 web.xml 中配置能够解决懒加载异常问题的 OpenEntityManagerInViewFilter:
<!-- 配置 OpenEntityManagerInViewFilter,解决懒加载异常的问题 -->
<filter>
<filter-name>OpenEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter> <filter-mapping>
<filter-name>OpenEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
最后呢定义一个程序的入口 index.jsp ,其中定义一个显示员工的超链接:
<h4>
<a href="emps">List All Employees</a>
</h4>
到此我们分页显示的功能就完成了,贴一下运行结果:
相比于原生的 JavaWeb 实现分页操作是不是很简单呢,效率也提高了很多。
Spring、SpringMVC、SpringData + JPA 整合详解的更多相关文章
- spring : springmvc常用注解标签详解(转)
新的项目,新的学习,好久没用这些注解了,同时在学习使用shiro ,lucene 等等.在网上找了些博文,感谢作者的总结和分享. 欢迎交流,言归正传: 1.@Controller 在SpringMVC ...
- Maven搭建Spring+SpringMVC+Mybatis+Shiro项目详解
一. 环境搭建: 1. 开发工具:myeclipse 2014 / IDEA: 2. maven管理版本:apache-maven-3.0+: 3. jdk 1.7.0+4. Tomcat8.0 二: ...
- 如约而至,Java 10 正式发布! Spring+SpringMVC+MyBatis+easyUI整合进阶篇(十四)Redis缓存正确的使用姿势 努力的孩子运气不会太差,跌宕的人生定当更加精彩 优先队列详解(转载)
如约而至,Java 10 正式发布! 3 月 20 日,Oracle 宣布 Java 10 正式发布. 官方已提供下载:http://www.oracle.com/technetwork/java ...
- idea spring+springmvc+mybatis环境配置整合详解
idea spring+springmvc+mybatis环境配置整合详解 1.配置整合前所需准备的环境: 1.1:jdk1.8 1.2:idea2017.1.5 1.3:Maven 3.5.2 2. ...
- Spring+SpringMVC+MyBatis+easyUI整合基础篇(十一)SVN服务器进阶
日常啰嗦 上一篇文章<Spring+SpringMVC+MyBatis+easyUI整合基础篇(十)SVN搭建>简单的讲了一下SVN服务器的搭建,并没有详细的介绍配置文件及一些复杂的功能, ...
- Spring+SpringMVC+MyBatis+easyUI整合进阶篇(六)一定要RESTful吗?
作者:13 GitHub:https://github.com/ZHENFENG13 版权声明:本文为原创文章,未经允许不得转载. 写在前面的话 这个问题看起来就显得有些萌,或者说类似的问题都有些不靠 ...
- Spring Boot的启动器Starter详解
Spring Boot的启动器Starter详解 作者:chszs,未经博主允许不得转载.经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs Spring Boot ...
- 转:springmvc常用注解标签详解
Spring5:@Autowired注解.@Resource注解和@Service注解 - IT·达人 - 博客园--这篇顺序渐进,讲得超级好--此人博客很不错http://www.cnblogs.c ...
- SpringMVC 之类型转换Converter详解转载
SpringMVC之类型转换Converter详解 本文转载 http://www.tuicool.com/articles/uUjaum 1.1 目录 1.1 目录 1.2 ...
随机推荐
- idea启动tomcat报错:Error during artifact deployment. See server log for details.
出现这种情况的原因老夫猜想是改变了artifact然而tomcat的配置中的artifact没有重新配就会出现这种报错 打开tomcat配置 删除原来的artifact 新添加artifact 保存 ...
- Codeforce E. Fire
E. Fire time limit per test 2 seconds memory limit per test 256 megabytes input standard input outpu ...
- AngularJS 1.3中的一次性数据绑定(one-time bindings)
点击查看AngularJS系列目录 谈谈AngularJS 1.3中的一次性数据绑定(one-time bindings) 不久之前,AngularJS 1.3版本正式发布,其中添加了很多的性特性,同 ...
- MySQL主从同步和读写分离的配置
主服务器:192.168.1.126 从服务器:192.168.1.163 amoeba代理服务器:192.168.1.237 系统全部是CentOS 6.7 1.配置主从同步 1.1.修改主服务器( ...
- mysql用户权限配置
创建管理员: mysqladmin -u root password 123456 登录 mysql -u root -p 建库及授权 > create database bdp charact ...
- 批处理之 for/f 详解
含有/F的for格式:FOR /F ["options"] %%i IN (file) DO command FOR /F ["options"] %%i IN ...
- 51nod 1536不一样的猜数游戏 思路:O(n)素数筛选法。同Codeforces 576A Vasya and Petya's Game。
废话不多说,先上题目. 51nod Codeforces 两个其实是一个意思,看51nod题目就讲的很清楚了,题意不再赘述. 直接讲我的分析过程:刚开始拿到手有点蒙蔽,看起来很难,然后......然后 ...
- bzoj4236 JOIOJI hash 模拟
JOIOJI桑是JOI君的叔叔."JOIOJI"这个名字是由"J.O.I"三个字母各两个构成的. 最近,JOIOJI桑有了一个孩子.JOIOJI桑想让自己孩子的 ...
- NDK各个版本链接
ndk_r15c (July 2017) Windows 32-bit : https://dl.google.com/android/repository/android-ndk-r15c-wind ...
- 插入排序的性能测试对比(C与C++实现)
一.概述: [标题]学生成绩管理的设计与实现 [开发语言]C.C++ [主要技术]结构体.STL [基本功能]实现对学生成绩类的基本操作:增加.删除.查询.排序 [测试数据]功能测试:按提示输入5组正 ...