SSM架构,是三层结合所成的框架,分别是Spring、SpringMVC、MyBatis所组成
SpringMVC:视图层,界面层;负责接收请求,显示处理结果,管理Controller控制器对;
Spring:业务层,管理service,dao,工具类对象;依赖注入来管理各层,面向切面编程管理事务,日志和权限
MyBatis:持久层;访问数据库;基于jdbc的框架,主要用来操作数据库,并且将业务实体和数据表联系起来
1、Spring
(1)基本概念
Spring是一个开源开发框架,是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架。
spring主要用来开发java应用,构建J2EE平台的web应用。其核心就是提供一种新的机制管理业务对象及其依赖关系
(2)spring的优点
容器:spring是一个容器,包含并管理对象的生命周期和配置。可以配置每个bean如何被创建,基于一个可配置原型prototype,你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例。
支持AOP:spring提供对AOP的支持,它允许将一些通用任务,如安全、事物、日志等进行集中式处理,从而提高了程序的复用性
轻量级框架:spring是轻量级框架,其基本的版本大约2M
控制反转:spring通过控制反转实现松耦合。对象们给他们依赖,而不是对象本身,方便解耦,简化开发
方便程序测试:spring提供了Junit4的支持,可以通过注解方便的测试spring程序。
降低java EE API的使用难度:spring对java EE开发中非常难用的一些API(比如JDBC),都提供了封装,使这些API应用难度大大降低
方便集成各种优秀框架:spring内部提供了对各种优秀框架(如Struts、mybatis)的直接支持。
支持声明式事务处理:只需要通过配置就可以完成对事务的管理,而无须手动编程
(3)spring的缺点
依赖反射,反射影响进程
太过于依赖设计模式
控制器过于灵活
不支持分布式应用
2、SpringMVC
(1)基本概念
属于spring框架的一部分,用来简化MVC架构的web应用程序开发
(2)SpringMVC的优点
拥有强大的灵活性,非侵入性和可配置性
提供了一个前端控制器dispatcherServlet,开发者无需额外开发控制器对象
分工明确,包括控制器、验证器、命令对象、模型对象、处理程序映射视图解析器,每一个功能实现由一个专门的对象负责完成
可以自动绑定用户输入,并正确的转换数据类型
可重用的业务代码:可以使用现有的业务对象作为命令或表单对象,而不需要去扩展某个特定框架的基类。
(3)SpringMVC的缺点
servlet API耦合难以脱离容器独立运行
太过于细分,开发效率低
3、Mybatis
(1)基本概念
mybatis是一个简化和实现了java数据持久层的开源框架,它抽象了大量的JDBC冗余代码,并提供了一个简单易用的API和数据库交互。
(2)mybatis的优点
与JDBC相比,减少了50%以上的代码量。
mybatis是最简单的持久化框架,小巧并且简单易学
mybatis灵活,不会对应用程序或者数据库的限售设计强加任何影响,SQL写在XML里,从程序
码中彻底分离,降低耦合度,便于统一管理和优化,可重用
提供XML标签,支持编写动态SQL语句(XML中使用if,else)
提供映射标签,支持对象与数据库的ORM字段关系映射(在XML中配置映射关系,也可以使用注解)
(3)mybatis的缺点
SQL语句的编写工作量较大,对开发人员的SQL语句编写有一定的水平要求
SQL语句过于依赖数据库,不能随意更换数据库
拼接复杂SQL语句时不灵活
SSM项目整合
1、创建数据库和表
2、新建maven web项目,选择
maven-archetype-webapp
3、加入依赖 spring,SpringMVC,mybatis,Jackson,MySQL驱动,Druid连接池,jsp,Servlet依赖
pom.xml文件
<dependencies>
<!-- junit单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--springmvc依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!-- spring以及事务等依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<!-- MyBatis依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<!-- spring和mybatis集成依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.1</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
<!-- 阿里数据库连接池Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.6</version>
</dependency>
<!-- servlet依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- jsp依赖 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
<scope>provided</scope>
</dependency>
<!--Jackson依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
4、配置文件 web.xml
(1)注册DispatcherServlet 【1】创建SpringMVC容器对象,创建Controller对象 【2】创建Servlet,接受用户请求
(2)注册spring的监听器:ContextLoaderListener;创建spring容器,创建service,dao对象
(3)注册字符集过滤器,解决POST请求中文乱码问题
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 声明,注册SpringMVC的核心对象DispatcherServlet
在Tomcat服务器启动后,创建DispatcherServlet对象实例
DispatcherServlet在创建过程中,会同时创建SpringMVC容器对象,读取SpringMVC配置文件,把这个配置文件中的对象都创建好,
用户发起请求时就可以直接适用对象
Servlet初始化会执行 init() 方法;DispatcherServlet在 init() 方法中
(1)创建容器,读取配置文件
WebApplicationContext ctx = new ClassPathXmlApplicationContext("springmvc.xml");
(2)将容器对象放入到ServletContext中
getServletContext().setAttribute(key, ctx);
-->
<servlet>
<servlet-name>myweb</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 启动Tomcat报错,无法读取这个文件 /WEB-INF/myweb-servlet.xml
Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/myweb-servlet.xml]
SpringMVC创建容器对象时,默认读取的配置文件是 /WEB-INF/<servlet-name>-servlet.xml
因此需要自定义SpringMVC读取配置文件的位置
<init-param> :在servlet类中通过getInitParamenter(String name)方法访问初始化参数
param-name 就是参数名;param-value就是参数值,支持多个参数
在这个方法中通过 getInitParamter("key"); key 就是 param-name的值,来获取对应的参数值
-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/springmvc.xml</param-value>
</init-param>
<!-- tomcat启动后,创建Servlet对象
load-on-startup:表示Tomcat启动后创建对象的顺序;
它的值是整数,数值越小,Tomcat创建对象的时间越早,大于等于0的整数
-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>myweb</servlet-name>
<!-- url-pattern 拦截匹配规则的 url 请求,进入springmvc 框架处理,
springmvc 就会去找能够处理这个url 的 handler去执行业务逻辑
可使用两种值
(1)使用扩展名方式,语法 *.xx , xx是自定义的扩展名,
常用的方式 *.do, *.action, *.mvc等等
不能使用 *.jsp
http://localhost:8080/myweb/some.do
http://localhost:8080/myweb/other.do
(2)使用斜杠 "/"
当项目中使用了 "/",它会替代 tomcat中的default
导致所有的静态资源都交给DispatcherServlet处理, 默认情况下DispatcherServlet没有处理静态资源的能力
没有控制器对象能处理静态资源的访问,因此静态资源(html,js,图片,css)都是404
动态资源some.do是可以访问,因为我们程序中有MyController控制器对象,能处理some.do请求。
-->
<url-pattern>/</url-pattern>
<!-- <url-pattern>*.do</url-pattern>-->
</servlet-mapping>
<!-- 注册spring的监听器:ContextLoaderListener
监听器被创建对象后,会读取 /WEB-INF/spring.xml(在监听器中要创建ApplicationContext对象,需要加载配置文件)
/WEB-INF/applicationContext.xml就是监听器默认读取的spring配置文件路径
可修改默认的配置文件位置,使用context-param重新制定文件的位置
配置监听器:目的是创建容器对象,就能把spring.xml配置文件中的所有对象都创建好;用户发起请求就可以直接使用对象
-->
<context-param>
<!-- contextConfigLocation:表示配置文件的路径 -->
<param-name>contextConfigLocation</param-name>
<!--自定义配置文件的路径-->
<param-value>classpath:conf/applicationContext.xml</param-value>
</context-param>
<listener>
<!-- Ctrl + F12 查看类的所有方法(选中类名) -->
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 注册声明字符集过滤器,解决POST请求中文乱码 -->
<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>
<!--强制请求对象(HttpServletRequest)使用encoding编码的值-->
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<!--强制响应对象(HttpServletResponse)使用encoding编码的值-->
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<!-- /*:表示强制所有的请求先通过过滤器处理 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
5、创建Controller、service、dao、domain等包
controller类
@Controller
@RequestMapping("/student")
public class MyController {
@Autowired
StudentService studentService;
@RequestMapping("/insertStudent")
public ModelAndView insertStudent(Student student){
ModelAndView mdv = new ModelAndView();
String tips = "注册失败";
//调用service处理student
int nums = studentService.insertStudent(student);
if (nums > 0){
//注册成功
tips = "学生【" + student.getStuName() + "】注册成功";
}
//添加数据
mdv.addObject("tips",tips);
//指定结果页面
mdv.setViewName("result");
return mdv;
}
@RequestMapping("/selectStudentList")
@ResponseBody
public List<Student> selectStudentList(){
//参数检查, 简单的数据处理
List<Student> students = studentService.selectStudentList();
System.out.println(students);
for (Student user:students){
System.out.println("user:" + user);
}
return students;
}
}
service
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
StudentDao studentDao;
@Override
public int insertStudent(Student student) {
return studentDao.insertStudent(student);
}
@Override
public List<Student> selectStudentList() {
return studentDao.selectStudentList();
}
}
dao
public interface StudentDao {
int insertStudent(Student student);
List<Student> selectStudentList();
}
dao.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.mycompany.dao.StudentDao">
<resultMap id="studentMap" type="com.mycompany.domain.Student">
<id column="stu_id" property="stuId" />
<result column="stu_name" property="stuName" />
<result column="stu_age" property="stuAge" />
</resultMap>
<select id="selectStudentList" resultMap="studentMap">
select stu_id,stu_name,stu_age
from ssm_student
order by stu_id desc
</select>
<insert id="insertStudent">
insert into ssm_student(stu_name,stu_age) values (#{stuName},#{stuAge})
</insert>
</mapper>
domain
public class Student {
// 属性名和请求中参数名一样
private Integer stuId;
private String stuName;
private Integer stuAge;
public Student() {
System.out.println("===Student的无参数构造方法===");
}
public Integer getStuId() {
return stuId;
}
public void setStuId(Integer stuId) {
this.stuId = stuId;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public Integer getStuAge() {
return stuAge;
}
public void setStuAge(Integer stuAge) {
this.stuAge = stuAge;
}
@Override
public String toString() {
return "Student{" +
"stuId=" + stuId +
", stuName='" + stuName + '\'' +
", stuAge=" + stuAge +
'}';
}
}
6、SpringMVC,Spring,MyBatis配置文件
springmvc.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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- springmvc配置文件
声明组件扫描器,声明controller和其它web相关的对象
-->
<context:component-scan base-package="com.mycompany.controller" />
<!-- 声明SpringMVC框架中的视图解析器
设置视图文件的路径:InternalResourceViewResolver
注:处理器方法返回String,表示完整视图路径,此时不能配置视图解析器
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀:视图文件的路径 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 后缀:视图文件的扩展名 -->
<property name="suffix" value=".jsp" />
</bean>
<!-- 处理静态资源方式:
<mvc:resources>:加入<mvc:resources>标签后SpringMVC框架会创建ResourceHttpRequestHandler处理器对象
这个对象处理井田资源的访问,不依赖Tomcat服务器
mapping:访问静态资源的 URI 地址,使用通配符 **
location:静态资源在项目中的目录位置(/webapp 目录下)
images/**:表示 images/image-1.jpeg , images/user/logo.gif , images/order/good/list.png
这时 静态资源就可以加载出来,但是发起请求就报错 404;
需要加入<mvc:annotation-driven>标签;<mvc:default-servlet-handler> 和 @RequestMapping注解 有冲突, 需要加入<mvc:annotation-driven>标签解决冲突
-->
<!--<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/html/**" location="/html/" />
<mvc:resources mapping="/js/**" location="/js/" />-->
<!-- 如果静态资源文件目录过多,可以将其统一放在一个static目录下;使用一个通配语句,指定所有静态资源文件访问 -->
<mvc:resources mapping="/static/**" location="/static/" />
<!-- 注解驱动
http://www.springframework.org/schema/mvc
1、响应ajax请求,返回json
2、解决静态资源访问问题
<mvc:annotation-driven> 注解驱动实现的功能:完成Java对象到json,xml,text,二进制等数据格式的转换
<mvc:default-servlet-handler> 和 @RequestMapping注解 有冲突, 需要加入<mvc:annotation-driven>标签解决冲突
-->
<mvc:annotation-driven />
</beans>
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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- spring 加载数据库的属性配置文件 -->
<context:property-placeholder location="classpath:conf/jdbc.properties" />
<!-- 1、声明数据源DataSource,作用:连接数据库
将mybatis主配置文件 configuration 下的environments 标签内容移到了这里
Druid官网:https://github.com/alibaba/druid
DruidDataSource配置:https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE
-->
<bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close" >
<!-- set注入给DruidDataSource提供数据库连接信息 -->
<!-- 使用和读取配置文件中的数据,语法 ${key} -->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}"/>
<property name="maxActive" value="${jdbc.maxActive}"/>
</bean>
<!-- 2、声明mybatis中提供的SQLSessionFactoryBean类 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- set注入,将数据库中连接池赋给dataSource属性 -->
<property name="dataSource" ref="myDataSource" />
<!-- mybatis主配置文件位置
configLocation 属性是Resource类型,读取配置文件
使用value赋值,指定文件路径,使用classpath: 表示文件位置
-->
<property name="configLocation" value="classpath:conf/mybatis.xml" />
</bean>
<!-- 3、创建dao对象,使用SqlSession的getMapper(XXDao.class)方法
MapperScannerConfigurer:内部调用getMapper(XXDao.class)方法生成每个dao接口的代理对象
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定SqlSession对象的id -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<!-- 指定包名,dao接口所在的包名
MapperScannerConfigurer会扫描这个包的所有接口,把每个接口都执行一次getMapper(XXDao.class)方法,得到每个接口的dao对象
创建好的dao对象放入到spring容器中;dao对象默认名称:接口名首字母小写!!!
-->
<property name="basePackage" value="com.mycompany.dao" />
</bean>
<!-- 4、声明service的注解@Service所在的包名位置 -->
<context:component-scan base-package="com.mycompany.service" />
<!--<bean id="userService" class="com.mycompany.service.impl.UserServiceImpl">
<!– 通过MapperScannerConfigurer 扫描包;dao对象的默认名称是 接口名首字母小写!!! –>
<property name="userDao" ref="userDao"/>
</bean>-->
</beans>
mybatis.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>
<!-- settings:控制mybatis全局行为 -->
<settings>
<!-- 设置mybatis输出日志 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!-- 定义别名 -->
<typeAliases>
<!-- 第一种方式
指定一个类型为一个自定义别名
type:自定义类型的全限定名称
alias:别名
-->
<!-- <typeAlias type="com.mycompany.domain.Student" />-->
<!-- 第二种方式
<package>
name:包名,这个包中所有的类,类名就是别名(不区分大小写)
-->
<package name="com.mycompany.domain" />
</typeAliases>
<!--
数据源DataSource 放在spring配置文件中
-->
<!--<environments default="development">
<environment id="online">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/onlinedb"/>
<property name="username" value="root"/>
<property name="password" value="admin123456"/>
</dataSource>
</environment>
</environments>-->
<!-- sql mapper(SQL映射文件)的位置 -->
<mappers>
<!-- 第一种方式:指定多个mapper文件
一个mapper标签指定一个文件位置
从类路径开始(target/classes)
-->
<!-- <mapper resource="com/mycompany/dao/StudentDao.xml"/>-->
<!-- 第二种方式:使用包名
name:xml(mapper)文件所在的包名,这个包中所有xml文件一次都能加载给mybatis
使用package要求:
(1)mapper文件名称需要和接口名称一样(区分大小写)
(2)mapper文件和dao接口需要在同一目录
-->
<package name="com.mycompany.dao" />
</mappers>
</configuration>
jdbc.properties数据库配置信息
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.user=root
jdbc.password=123456
jdbc.maxActive=20
7、写jsp视图页面
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String basePath = request.getScheme() + "://" +
request.getServerName() + ":" +
request.getServerPort() +
request.getContextPath() + "/";
%>
<html>
<head>
<title>功能入口</title>
<base href="<%=basePath%>" />
</head>
<body>
<div align="center">
<p>SSM项目</p>
<img src="static/images/ssm.png" />
<table>
<tr>
<td><a href="insertStudent.jsp"> 注册学生</a></td>
</tr>
<tr>
<td><a href="listStudent.jsp">浏览学生</a></td>
</tr>
</table>
</div>
</body>
</html>
insertStudent.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String basePath = request.getScheme() + "://" +
request.getServerName() + ":" + request.getServerPort() +
request.getContextPath() + "/";
%>
<html>
<head>
<title>注册学生</title>
<base href="<%=basePath%>" />
</head>
<body>
<div align="center">
<form action="student/insertStudent" method="post">
<table>
<tr>
<td>姓名:</td>
<td><input type="text" name="stuName"></td>
</tr>
<tr>
<td>年龄:</td>
<td><input type="text" name="stuAge"></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" value="注册"></td>
</tr>
</table>
</form>
</div>
</body>
</html>
listStudent.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String basePath = request.getScheme() + "://" +
request.getServerName() + ":" + request.getServerPort() +
request.getContextPath() + "/";
%>
<html>
<head>
<title>查询学生ajax</title>
<base href="<%=basePath%>" />
<script type="text/javascript" src="static/js/jquery-3.4.1.js"></script>
<script type="text/javascript">
$(function(){
//在当前页面dom对象加载后,执行loadStudentData()
loadStudentData();
$("#btnLoader").click(function(){
loadStudentData();
// alert($("#country > option:selected").val());
// alert($("#country > option:selected").text());
})
})
function loadStudentData(){
$.ajax({
url:"student/selectStudentList",
type:"get",
dataType:"json",
success:function(data){
//清除旧的数据
$("#info").html("");
//增加新的数据
debugger;
$.each(data,function(i,n){
$("#info").append("<tr>")
.append("<td>"+n.stuId+"</td>")
.append("<td>"+n.stuName+"</td>")
.append("<td>"+n.stuAge+"</td>")
.append("</tr>")
})
}
})
}
</script>
</head>
<body>
<div align="center">
<table>
<thead>
<tr>
<td>学号</td>
<td>姓名</td>
<td>年龄</td>
</tr>
</thead>
<tbody id="info">
</tbody>
</table>
<input type="button" id="btnLoader" value="查询数据">
<select id="country">
<option value="1">中国</option>
<option value="2">俄罗斯</option>
<option value="3">澳大利亚</option>
</select>
</div>
</body>
</html>