技术要点: spring5.3.20 spring-webmvc5.3.20 mybatis3.5.10
功能模块: 数据库连接池、注解事务管理、常用增删改查、全局异常处理、解决跨域问题、统一使用VO.Result对象封装数据、拦截器
项目名称: SSM
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for stu_tea
-- ----------------------------
DROP TABLE IF EXISTS `stu_tea`;
CREATE TABLE `stu_tea` (
`id` bigint(20) NOT NULL COMMENT 'id',
`stu_id` bigint(20) NOT NULL COMMENT '学生ID',
`tea_id` bigint(20) NULL DEFAULT NULL COMMENT '教室ID',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of stu_tea
-- ----------------------------
INSERT INTO `stu_tea` VALUES (1, 1, 1);
INSERT INTO `stu_tea` VALUES (2, 1, 2);
INSERT INTO `stu_tea` VALUES (3, 1, 3);
INSERT INTO `stu_tea` VALUES (4, 1, 2);
INSERT INTO `stu_tea` VALUES (5, 2, 2);
INSERT INTO `stu_tea` VALUES (6, 3, 2);
INSERT INTO `stu_tea` VALUES (7, 3, 3);
INSERT INTO `stu_tea` VALUES (8, 4, 4);
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int(10) NOT NULL,
`name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`tid` int(10) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `fktid`(`tid`) USING BTREE,
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '小明', 1);
INSERT INTO `student` VALUES (2, '小红', 2);
INSERT INTO `student` VALUES (3, '小张', 2);
INSERT INTO `student` VALUES (4, '小李', 3);
INSERT INTO `student` VALUES (5, '小王', 1);
INSERT INTO `student` VALUES (6, '小赵', 2);
INSERT INTO `student` VALUES (7, '小梁', 2);
-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
`id` int(10) NOT NULL,
`name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of teacher
-- ----------------------------
INSERT INTO `teacher` VALUES (1, '秦老师');
INSERT INTO `teacher` VALUES (2, '王老师');
INSERT INTO `teacher` VALUES (3, '张老师');
INSERT INTO `teacher` VALUES (4, '梁老师');
SET FOREIGN_KEY_CHECKS = 1;
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>org.examplegroupId>
<artifactId>SSMartifactId>
<version>1.0-SNAPSHOTversion>
<packaging>warpackaging>
<name>SSM Maven Webappname>
<url>http://www.example.comurl>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.8maven.compiler.source>
<maven.compiler.target>1.8maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.12.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
<version>5.1.10.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.1.10.RELEASEversion>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.10version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-springartifactId>
<version>2.0.7version>
dependency>
<dependency>
<groupId>org.mybatis.generatorgroupId>
<artifactId>mybatis-generator-coreartifactId>
<version>1.4.0version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.49version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.2.4version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>servlet-apiartifactId>
<version>2.5version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.12.6version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>2.12.6version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.12.6version>
dependency>
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-slf4j-implartifactId>
<version>2.14.0version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.11version>
<scope>testscope>
dependency>
dependencies>
<build>
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
<include>**/*.confinclude>
includes>
<filtering>falsefiltering>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
<include>**/*.confinclude>
includes>
<filtering>falsefiltering>
resource>
resources>
build>
project>
创建spring-ioc
<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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.example.ssm">
<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>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/localhost"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
bean>
<bean id="sqlFactorySession" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="com.example.ssm.entity"/>
<property name="mapperLocations" value="classpath:mappers/*.xml"/>
bean>
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.example.ssm.dao"/>
bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
beans>
创建spring-mvc
<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 http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.example.ssm.controller"/>
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="suffix" value=".jsp"/>
<property name="prefix" value="/WEB-INF/"/>
bean>
<mvc:cors>
<mvc:mapping path="/**" allowed-origins="https://localhost:8080" allowed-methods="POST,GET"/>
mvc:cors>
beans>
修改web.xml 头文件约束
<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">
web-app>
在web.xml中配置springweb
<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">
<display-name>Archetype Created Web Applicationdisplay-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:spring-ioc.xmlparam-value>
context-param>
<servlet>
<servlet-name>dispatcherServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:spring-mvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>dispatcherServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<filter>
<filter-name>characterEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>forceRequestEncodingparam-name>
<param-value>trueparam-value>
init-param>
<init-param>
<param-name>forceResponseEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>characterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
web-app>
创建日志配置文件
<Configuration status="info">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
Console>
Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
Root>
Loggers>
Configuration>
测试配置文件是否成功,创建一个controller
@Controller
public class TestController {
@RequestMapping("/test")
public String test(){
return "jsp/index";
}
}
移动index.jsp 文件到jsp目录下,完整的项目结构如下。
配置Tomcat
点击小灯泡修复 (会创建一个部署的工件)
war模式:将WEB工程以包的形式上传到服务器 ;
war exploded模式:将WEB工程以当前文件夹的位置关系上传到服务器;
(1)war模式这种可以称之为是发布模式,先打war包,再发布;
(2)war exploded模式是直接把文件夹、jsp页面 、classes等等移到Tomcat 部署文件夹里面,进行加载部署。因此这种方式支持热部署,一般在开发的时候也是用这种方式。
启动项目,访问 http://localhost:8080/test
到此springmvc项目已经配置成功。
创建配置文件
DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="default" targetRuntime="MyBatis3">
<property name="javaFileEncoding" value="UTF-8"/>
<commentGenerator>
<property name="suppressDate" value="true"/>
<property name="suppressAllComments" value="true"/>
commentGenerator>
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/localhost"
userId="root"
password="root">
jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
javaTypeResolver>
<javaModelGenerator targetPackage="com.example.entity" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
javaModelGenerator>
<sqlMapGenerator targetPackage="mappers" targetProject="src/main/resources">
<property name="enableSubPackages" value="true"/>
sqlMapGenerator>
<javaClientGenerator type="XMLMAPPER" targetPackage="com.example.dao" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
javaClientGenerator>
<table tableName="student"
enableCountByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
enableUpdateByExample="false"
domainObjectName="Student"
mapperName="StudentMapper">
<generatedKey column="id" sqlStatement="MySql"/>
table>
context>
generatorConfiguration>
生成代码主程序
public class MyGenerator {
public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<>();
// 如果已经存在生成过的文件是否进行覆盖
boolean overwrite = true;
File configFile = new File("E:\\testProject\\SSM\\src\\main\\resources\\mybatis-generator.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator generator = new MyBatisGenerator(config, callback, warnings);
generator.generate(null);
}
}
public class ResultVo<T> implements Serializable {
private static final long serialVersionUID = -4583890969892107839L;
private Integer code;
private String msg;
private T data;
/**
* 默认返回成功的信息
*/
public ResultVo(T data){
code = 200;
msg = "操作成功";
this.data = data;
}
public ResultVo(Integer code, String msg ,T data){
this.code = code;
this.msg = msg;
this.data = data;
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<p><strong>错误描述:strong>${ex.code}p>
<p><strong>错误提示:strong>${ex.message}p>
body>
html>
自定义异常
package com.example.ssm.exception;
/**
* @Author: lyf
* @CreateTime: 2022-12-09
* @description:
*/
public class BusinessException extends RuntimeException{
private static final long serialVersionUID = -3155751506303675411L;
private Integer code;
private String msg;
public BusinessException(Integer code,String msg){
this.code =code;
this.msg =msg;
}
public Integer getCode() {
return code;
}
public String getMsg() {
return msg;
}
public void setCode(Integer code) {
this.code = code;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
异常拦截
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(BusinessException.class)
public ModelAndView handleBusinessError(BusinessException ex){
ModelAndView mv = new ModelAndView();
mv.addObject(ex);
mv.setViewName("jsp/error");
return mv;
}
}
测试
@Controller
public class TestController {
@RequestMapping("/test")
public String test(){
try {
int i= 1/0;
}catch (Exception e){
throw new BusinessException(500,"系统出错,请联系管理员");
}
return null;
}
}
public class MyHandlerInterceptor implements HandlerInterceptor {
//控制器之前执行,如果返回true,则继续执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
//控制器执行完之后,视图解析器之前执行
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
// 视图解析器完成后执行
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
在spring-mvc中配置拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/login"/>
<ref bean="interceptor"/>
mvc:interceptor>
<bean id="interceptor" class="com.example.ssm.interceptor.MyHandlerInterceptor"/>
mvc:interceptors>
StudentMapper
package com.example.ssm.dao;
import com.example.ssm.entity.Student;
public interface StudentMapper {
int deleteByPrimaryKey(Integer id);
int insert(Student record);
int insertSelective(Student record);
Student selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(Student record);
int updateByPrimaryKey(Student record);
}
StudentService
public interface StudentService {
int deleteByPrimaryKey(Integer id);
int insert(Student record);
int insertSelective(Student record);
Student selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(Student record);
int updateByPrimaryKey(Student record);
}
StudentServiceImpl
package com.example.ssm.service;
@Service
public class StudentServiceImpl implements StudentService{
@Autowired
private StudentMapper studentMapper;
@Override
public int deleteByPrimaryKey(Integer id) {
return studentMapper.deleteByPrimaryKey(id);
}
@Transactional
@Override
public int insert(Student record) {
return studentMapper.insert(record);
}
@Transactional
@Override
public int insertSelective(Student record) {
return studentMapper.insertSelective(record);
}
@Override
public Student selectByPrimaryKey(Integer id) {
return studentMapper.selectByPrimaryKey(id);
}
@Override
public int updateByPrimaryKeySelective(Student record) {
return studentMapper.updateByPrimaryKeySelective(record);
}
@Override
public int updateByPrimaryKey(Student record) {
return studentMapper.updateByPrimaryKey(record);
}
}
StudentController
@RestController
public class StudentController {
@Autowired
private StudentService studentService;
@RequestMapping("/delete")
public ResultVo<Integer> deleteByPrimaryKey(Integer id) {
int i = studentService.deleteByPrimaryKey(id);
return new ResultVo<>(i);
}
@RequestMapping("/insert")
public ResultVo<Integer> insert(Student record) {
int insert = studentService.insert(record);
return new ResultVo<>(insert);
}
@RequestMapping("/insertSelective")
public ResultVo<Integer> insertSelective(Student record) {
int i = studentService.insertSelective(record);
return new ResultVo<>(i);
}
@RequestMapping("/selectByPrimaryKey")
public ResultVo<Student> selectByPrimaryKey(Integer id) {
Student student = studentService.selectByPrimaryKey(id);
return new ResultVo<>(student);
}
@RequestMapping("/updateByPrimaryKeySelective")
public ResultVo<Integer> updateByPrimaryKeySelective(Student record) {
int i = studentService.updateByPrimaryKeySelective(record);
return new ResultVo<>(i);
}
@RequestMapping("/updateByKey")
public ResultVo<Integer> updateByPrimaryKey(Student record) {
int i = studentService.updateByPrimaryKey(record);
return new ResultVo<>(i);
}}
注解配置主要修改 web.xml spring-mvc.xml spring-ioc.xml 文件。
web.xml 修改
public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
// spring-ioc
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringIOC.class};
}
//spring -mvc
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMVC.class};
}
// 拦截路径
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
// 过滤器
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
encodingFilter.setEncoding("UTF-8");
encodingFilter.setForceResponseEncoding(true);
encodingFilter.setForceRequestEncoding(true);
HiddenHttpMethodFilter httpMethodFilter = new HiddenHttpMethodFilter();
return new Filter[]{encodingFilter,httpMethodFilter};
}
}
spring-mvc
@Import(Application.class)
@Configuration
@EnableWebMvc // 开启spring注解支持 等同
public class SpringMVC implements WebMvcConfigurer {
/**
* 开启静态资源过滤
* 等同
* @param configurer
*/
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
/**
* 添加拦截器
* 等同 标签
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyHandlerInterceptor()).addPathPatterns("/he").excludePathPatterns("/hello");
}
/**
* 视图控制器
* 等同
* @param registry
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("jsp/index");
}
/**
* 视图解析器
*
* @return
*/
@Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
数据库连接信息
jdbc.dev.driverClass=com.mysql.jdbc.Driver
jdbc.dev.url=jdbc:mysql://localhost:3306/localhost
jdbc.dev.username=root
jdbc.dev.password=root
spring-ioc
@Configuration
@PropertySource("classpath:datasource.properties")
public class SpringIOC {
@Autowired
private Environment env;
// 数据源
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(env.getProperty("jdbc.dev.driverClass"));
dataSource.setUrl(env.getProperty("jdbc.dev.url"));
dataSource.setUsername(env.getProperty("jdbc.dev.username"));
dataSource.setPassword(env.getProperty("jdbc.dev.password"));
return dataSource;
}
// mybatis sqlsession 工厂
@Bean
SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setTypeAliasesPackage("com.example.ssm.entity");
ResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
try {
sqlSessionFactoryBean.setMapperLocations(patternResolver.getResources("classpath*:mappers/*Mapper.xml"));
}catch (Exception e){
System.out.println(e.getMessage());
}
return sqlSessionFactoryBean;
}
// 事务
@Bean
DataSourceTransactionManager transactionManager(DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
}
组件扫描配置类
@ComponentScan("com.example.ssm")
@MapperScan("com.example.ssm.dao")
@Configuration
public class Application{
}
项目完整结构
测试 注释掉web.xml 中的配置代码,访问http://localhost:8080/selectByPrimaryKey?id=6