Servlet

Servlet基础

定义

Servlet是一种服务器端的Java应用程序,具有独立于平台和协议的特性,可以生成动态的Web页面。 它担当客户请求(Web浏览器或其他HTTP客户程序)与服务器响应(HTTP服务器上的数据库或应用程序)的中间层。   Servlet是位于Web 服务器内部的服务器端的Java应用程序,与传统的从命令行启动的Java应用程序不同,Servlet由Web服务器进行加载,该Web服务器必须包含支持Servlet的Java虚拟机。

WEB

WEB服務器:用于接收请求,产生响应,但是响应信息只能产生静态HTML

WEB容器:将服务器请求,进行一大堆业务处理,然后以数据库作为信息储存介质,动态产生响应信息,再不改变页面的情况下,做到数据的及时更新

http协议

HTTP协议称为超文本传输协议,是TCP协议的应用层协议,是客户端与服务器通信的一种标准。客户端和服务器都遵循HTTP协议,就能从彼此发送的信息中提取自己想要的数据。

http协议的特点

1、http遵循请求/响应模型

2、http协议是一种无状态的协议。当客户端和服务器之间,请求/响应流程结束后,连接会断开。客户端每次请求都需要重新建立连接。所以,服务器会认为每次请求的都是新用户,无法知道两次请求的用户是否为同一个用户。

3、http协议占用80端口。短连接。

http协议的长连接

在网页中,除了有文本数据以外,还有各式各样的连接资源。在网页显示时,不仅仅有文本数据,还需要将链接资源一一下载并显示。这时,如果每次请求都建立连接,效率会比较低。所以,在HTTP/1.1标准中,用长连接来解决。在访问网页时,建立连接,在下载连接资源时,就不用重新建立连接了。

http协议的处理流程

1、客户端和服务器建立连接

2、客户端发出http请求

3、服务器产生http响应

4、关闭连接

http协议请求信息的格式

分为四部分:请求行、请求头、空行、消息体。

请求行:描述请求方式、请求的URL路径、HTTP协议的版本

请求头:以键值对方式描述客户端相关的信息

空行:标识请求头的结束

消息体(POST):描述客户端请求服务器的表单数据

http协议的请求方式

GET,POST,HEAD,OPTIONS,PUT,DELETE,TRACE,CONNECT

其中最常用的是GET、POST两种

现在有一种风格叫rest风格,该风格认为GET请求用于查询操作,POST请求用于添加操作,DELETE请求用于删除操作,PUT请求用于修改操作。

GET请求:1、在浏览器中直接输入URL路径,访问服务器。

​ 2、点击超链接

​ 3、提交表单时。method属性缺省,或为GET

POST请求:提交表单时,method属性为POST

GET请求和POST请求的区别

1、流格式的区别。

GET请求的表单数据附加在URL路径后面,没有消息体。所以,在GET请求时,浏览器地址会显示表单数据。POST请求的表单数据放在消息体中,在POST请求时,浏览器地址栏不会显示表单数据,相对安全。

2、传属性能的区别。

  • GET请求只能传输文本数据,POST请求可以传输文本数据和二进制数据
  • GET请求只能传输小文本数据,POST请求数据传输没有大小限制

3、用途的区别

GET请求用于服务器资源的查找。而POST用于数据的传输,也就是将客户的数据传输给服务器。

http协议的响应信息

状态行、响应头、空行、消息体

状态行:描述HTTP协议的版本、状态码、状态描述

响应头:以键值对方式描述服务器相关信息

空行:标识响应头的结束

消息体:服务器发送给客户端的具体数据。

状态码

100-199:标识信息性代码,请求在进行中

200-299:标识客户端请求成功,服务器数据正确到达客户端

300-399:表示服务器资源已经移走,只是客户端请求新的地址

400-499:表示由客户端引发的错误

500-599:表示由服务器引发的错误

MIME类型

用于指定服务器发送给客户端的数据格式。客户端接收到响应信息后,会根据服务器指定的MIME类型,来决定如何解析响应信息的消息体内容

常见的MIME类型:

text/html:网页格式数据

image/jpeg:jpg图片格式

text/xml:xml格式数据

application/json:json格式数据

辅助应用

传统的web服务器在产生响应信息时,只能产生静态的html页面。极大的影响响应信息的灵活性。

解决方案是在传统的web服务器基础上,增加辅助应用。辅助应用可以在web服务器接收到客户端请求之后,进行一大堆业务处理。并以数据库作为数据存储界质,从而动态显示处理的响应信息。

java采用WEB容器+Servlet作为辅助应用解决方案的

web容器

在java中,web容器完成底层操作。预留Servlet接口,交给开发者书写业务操作。web容器调用servlet业务方法,动态产生相应信息。

web容器的作用

1、通讯支持

由于请求/响应信息比较庞大。容器需要将请求/响应信息,封装为请求对象和响应对象。以便更好的接收和发送数据。

2、Servlet组件生命周期管理

Servlet是WEB容器预留给开发者书写业务操作的接口。开发者实现了Servlet接口后,Servlet组件对象的产生、方法调用、销毁全部由WEB容器进行。

3、线程支持

WEB容器采用多线程作为多任务处理解决方案。线程的创建、启动、同步、销毁全部由WEB容器管理。

4、JSP支持

由WEB容器完成对JSP引擎的编写,完成JSP页面的翻译

5、处理安全性

tomcat

tomcat源自于apache软件基金会jakata项目。tomcat是一款免费的、开源的、性能稳定、技术成熟的WEB容器产品。

导入tomcat依赖

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>9.0.36</version>
        </dependency>

Servlet是运行在Web服务器或应用服务器上的java程序,是WEB容器和开发者业务组件通信的标准。由Sun规范了其功能。

Servlet的API结构

按照Servlet规范,Servlet为业务接口,提供service()交给开发者书写业务操作,ServletConfig为配置接口。由于两个接口中的方法较多,如果都实现会很繁琐,servlet规范中提供了一个GeneriServlet类,该类同时实现了Servlet和ServletConfig两个接口,并实现了大部分方法。但是没有实现service方法,该方法应该由子类,根据协议的特点进行重写。

HttpServlet继承了GenericServlet,根据http协议的特点,重写doGet和doPost方法就可以了。

步骤

1、书写Servlet类并继承HttpServlet,重写doGet和doPost方法

public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //设置响应信息的MIME类型和编码集
        resp.setContentType("text/html;charset=utf-8");
        //向客户端输出信息
        resp.getWriter().print("hello,中国");
    }
}

2、创建并启动Tomcat,同时注册servlet

public class MainTomCat {
    public MainTomCat() {
        Tomcat tomcat = new Tomcat();
        //设置启动端口
        tomcat.setPort(8088);
        //设置http引擎
        tomcat.getConnector();
        //定义上下文
        Context context = tomcat.addContext("", null);
        //注册servlet。第一个参数为上下文对象,第二个参数为servlet名称,第三个参数为servlet对象
        Wrapper w = Tomcat.addServlet(context, "test", new TestServlet());
        //注册servlet访问路径
        w.addMapping("/tt");
        try {
            //启动tomcat
            tomcat.start();
        } catch (LifecycleException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new MainTomCat();
    }
}
servlet访问路径

1、精确匹配:/test 表示客户端以/test请求服务器,由该servlet处理。

2、扩展匹配:*.do 表示凡是以do结尾的请求,都该由servlet处理。

3、路径匹配:/abc/* 表示凡是在/abc/目录下的请求,都该由servlet处理。

常用API
        //设置请求信息编码集,只对POST有效
        req.setCharacterEncoding("utf-8");
        //设置响应信息的MIME类型的编码集
        resp.setContentType("text/html;charset=utf-8");
        //根据表单名得到表单值
        String userName = req.getParameter("userName");
        //客户端提交多个同名的键值对,由getParameterValues接收,返回数组
        String[] likeArray = req.getParameterValues("like");
        resp.getWriter().print("姓名:" + userName + "<br>");
        resp.getWriter().print("爱好:" + Arrays.toString(likeArray) + "");

服务器产生响应信息有两种格式

1、向客户端发送文本数据

resp.getWriter().printLn("信息")

2、向客户端发送二进制数据

OutputStream out =  resp.getOutputStream()

将对象转化为json格式字符串

1、导入依赖

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.11.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-parameter-names</artifactId>
            <version>2.11.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jdk8</artifactId>
            <version>2.11.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>2.11.0</version>
        </dependency>

2、对于实体类的日期类型,需要加上输入格式

public class ClassBean {
    private Integer id;
    private String name;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate createDate;
}

3、利用ObjectMapper将对象,转化为json字符串

        ObjectMapper om = new ObjectMapper();
        //添加日期格式的支持
        om.registerModule(new JavaTimeModule());
        //将对象转化为json格式字符串
        String str = om.writeValueAsString(list);

Servlet生命周期

1、容器加载并实例化Servlet

2、调用init()完成初始化

3、当请求达到,调用service(),接收请求,产生响应。

4、销毁阶段,调用destory(),完成资源清理。

在整个生命周期中,1、2、4只做一次。只有3,每次请求都会执行。而Servlet组件是单实例,多线程的类。

Servlet接口中定义的init()方法,用于servlet组件类的初始化。初始化的时机是可以配置的。如果配置了LoadOnStartup,并设置为0或正数。表示容器启动就完成该servlet初始化。如果没有配置LoadOnStartup,或设置为负数。表示第一次访问servlet时,完成初始化。

SpringMVC

是一个基于MVC模式的表现层框架,在spring2.5以后新增了注解功能。

特点

1、基于的是servlet模式

2、控制器不再需要继承其它类,只需要用@Controller注解

3、应用控制器方法参数,由前端控制器负责封装,方法签名定义灵活。

4、返回页面直接在方法中指定,可以是String,也可以是其它的,比如:ModelAndView或void等

5、性能很优秀

控制器

在springMVC中存在两种控制器:前端控制器和应用控制器。

前端控制器(DispatcherServlet),负责接收客户端请求,根据请求路径访问应用控制器,负责将页面参数填充JavaBean,负责转发页面,对标签类进行调用。

应用控制器(用户书写的Controller),负责产生业务组件,调用业务组件的方法完成业务,根据结果返回转发的页面对象。

工作流程

1、当客户端请求服务器,服务器使用前端控制器DispatcherServlet接收请求。

2、DispatcherServlet借助HandlerMapping,根据请求的URL路径,定位到具体的Controller,和应用控制器的具体方法。并将封装好数据的实体对象传入应用控制器。

3、由应用控制器方法,完成业务组件的业务方法的调用,然后根据业务方法处理的结果,返回需要转发的页面路径。DispatcherServlet根据路径,完成页面转发。

Spring Boot

SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程中。

特点

1、创建独立的Spring应用程序

2、嵌入的Tomcat,无需部署WAR文件

3、简化Maven配置

4、自动配置Spring

5、对XML没有要求配置

环境搭建

1、导入依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.7</version>
        <relativePath/>
    </parent>

SpringBoot 是由一系列启动器组成的,这些启动器构成一个强大的灵活的开发助手。开发人员根据项目需求,选择并组合相应的启动器,就可以快速搭建一个适合项目需要的基础运行框架。

2、添加web启动器的坐标

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
</dependency>

3、添加启动类

/**
 * 扫描该类所在的包,及子包中的spring组件类
 */
@SpringBootApplication
public class BootMain {
    public static void main(String[] args) {
        SpringApplication.run(BootMain.class);
    }
}

4、书写应用控制器

@RestController
public class TestController {
    @RequestMapping("info")
    public String getInfo() {
        return "hello,典韦";
    }

    @RequestMapping("sp")
    public String speak() {
        return "说话";
    }
}

springboot的配置文件

SpringBoot有很多的自动配置,在开发中,我们可能需要修改SpringBoot自动配置的默认值。比如,服务器启动端口,数据源等。

springBoot的配置文件必须放在类路径下,名称是固定。application.yml和application.properties

applicationContext.properties  内容:

server.port=8088

server.context=/boot
applicationContext.yml  内容:

server:

   port:8088

   context:/boot

SpringBoot静态资源存放目录,需要在classPath类路径下。如果是maven项目,则在resource,目录下。

classPath:

META-INF/resources>resources>static>public

springBoot得到表单数据

    @RequestMapping("add")
    public String add(EmployeeBean em) {
        return "添加成功" + em ;
    }

springBoot会按表单名和属性名相同的原则,进行实体对象属性的封装。简单类型形参,按照表单名和形参名相同的原则进行封装。

当形参名和表单名不一致时,可以用@RequestParam指定什么表单值填充该形参。

    @RequestMapping("add")
    public String add(EmployeeBean em, @RequestParam("money") Integer mone) {
        return "添加成功" + em + mone;
    }

SpringBoot类型转换

在springBoot中内置大量的类型转换器。可以完成大部分类型的转化。不过,如果是一些特殊类型(LocalDate),或需要自定义转换规则时,就要自定义类型转换器。

@Component
public class DateChange implements Converter<String, LocalDate> {
    @Override
    public LocalDate convert(String source) {
        if (source.matches("\\d{4}-\\d{2}-\\d{2}")) {
            return LocalDate.parse(source);
        }
        return null;
    }
}

springBoot命名空间

在开发中,为了防止URL同名而导致的异常。可以在方法申明URL路径时,加上命名空间

@RestController
@RequestMapping("room")
public class RoomController {
    @RequestMapping("add")
    public String add() {
        return "添加房间";
    }
}

这时,add方法的访问路径,就应该是“/room/add”

有时候,在应用控制器方法中,也需要使用servlet容器中对象,这时,可以直接在应用控制器方法中,添加形参。

public class RoomController {
    @RequestMapping("add")
    public String add(HttpServletRequest req, HttpServletResponse resp) {
        return "添加房间";
    }

在springMVC中,应用控制器方法可以返回字符串,这时客户会原样输出该字符串(@RestController)。如果应用控制器方法返回实体对象,或集合,那么会将实体对象或集合转化为json字符串,输出到客户端。

    @RequestMapping("findAll")
    public List<EmployeeBean> findAll() {
        List<EmployeeBean> list = new ArrayList<>();
        list.add(new EmployeeBean(2, "佳伟", "19273919211", 2830, LocalDate.parse("1998-09-01")));
        list.add(new EmployeeBean(4, "大卫", "19323919211", 8818, LocalDate.parse("1998-09-01")));
        return list;
    }

关于表单、超链接访问路径的问题

表单的action属性和超链接的href属性,表示该表单或超链接的访问服务URL路径。有两种写法:

<form action="user/reg">
    <input type="submit" value="提交">
</form>

如果URL路径以/开始,表示在根目录下查找指定资源

<form action="/user/reg">
    <input type="submit" value="提交">
</form>

在应用控制器方法中,可以指定该方法必须以什么方式来请求

14:27@RequestMapping(value = "reg",method = RequestMethod.GET)
public String add(){
    return "注册";
}

表示该方法只能以GET方式来访问,如果以别的方式访问,会抛出405状态码。

也可以直接使用@PostMapping、@GetMapping代替@RequestMapping。指定请求方式

从请求URL路径中,得到客户端提交的数据

在客户端提交URL路径时,通过/附加数据

<a href="/user/del/1/tom/123">删除</a>

服务端,接收URL路径中的数据

    @RequestMapping("del/{id}/{name}/{grade}")
    public String del(@PathVariable("id") Integer id,
                      @PathVariable("name") String userName,
                      @PathVariable("grade") Integer grade) {
        return "删除成功" + id + userName + grade;
    }

请求参数的默认值

    @RequestMapping("find")
    public String find(@RequestParam(value = "id", defaultValue = "2") Integer id) {
        return "id=" + id;
    }

表示,如果客户端提交了id表单数据,就以客户端提交的id值填充形参,如果客户端没有提交id表单数据,这时,以默认值1填充形参。

MyBatis-Plus

是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。

官网:https://mp.baomidou.com/

环境搭建

1、导入依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.7</version>
        <relativePath/>
    </parent>
  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.9</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.9.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

2、创建实体类,同时映射表名和列名,将属性名映射列名

@TableName("t_student")//表示该类映射的表名
public class StudentBean {
    //表示该属性映射主键列,同时指定主键生成策略。IdType.AUTO表示使用数据库的自动增长列填充该属性。Value表示该属性映射的主键列名
    @TableId(value = "pk_studentId", type = IdType.AUTO)
    private Integer id;
    //映射普通列
    @TableField("s_name")
    private String name;
    @TableField("s_birthday")
    private LocalDate birthday;
    @TableField("s_phone")
    private String phone;

3、创建配置文件application.yml

server:
  port: 8088
spring:
  datasource: #定义数据源
    driver-class-name: com.mysql.cj.jdbc.Driver #驱动类
    url: jdbc:mysql://localhost:3306/db?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false&allowMultiQueries=true #URL
    username: root #mysql登录用户名
    password: yks957 #mysql登录密码
    #指定连接池产品
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      one:
        max-active: 100 #最大连接
        min_idle: 20 #最小连接
        max-wait: 2000 #超时时间

mybatis-plus:
  configuration:
  #定义日志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
   #允许指定包中的实体类,用类名做为别名
  type-aliases-package: com.project.bean
  #扫描mapper文件
  mapper-locations: classpath:*/*Mapper.xml 

4、创建springBoot启动类,启动类必须放在父包中

@SpringBootApplication
public class MainBoot3 {
    public static void main(String[] args) {
        SpringApplication.run(MainBoot3.class);
    }
}

5、定义业务接口

public interface IStudentService {
    public void add(StudentBean studentBean);
    public void del(Integer id);
    public void update(Integer id, String phone);
    public List<StudentBean> findAll();
    public StudentBean findById(Integer id);
}

6、定义mapper接口

@Mapper
public interface IStudentMapper extends BaseMapper<StudentBean> {

}

7、书写业务接口实现类

@Service
@Transactional
public class StudentServiceImpl implements IStudentService {
    @Autowired
    private IStudentMapper mapper;

    @Override
    public void add(StudentBean studentBean) {
        mapper.insert(studentBean);//添加,同时将自动增长列的值填充主键属性
    }

    @Override
    public void del(Integer id) {
        mapper.deleteById(id); //按Id删除
    }

    @Override
    public void update(Integer id, String phone) {
        StudentBean studentBean = mapper.selectById(id);
        studentBean.setPhone(phone);
        mapper.updateById(studentBean);//按id修改
    }

    @Override
    public List<StudentBean> findAll() {
        return mapper.selectList(null);//查询所有
    }

    @Override
    public StudentBean findById(Integer id) {
        return mapper.selectById(id);//按Id查询
    }

8、测试

@SpringBootTest(classes = MainBoot3.class)
public class StudentTest {
    @Autowired
    private IStudentService service;

    @Test
    public void test() {
     System.out.println(service.findAll());
      service.add(new StudentBean("猪猪", LocalDate.parse("2020-01-01"),"18726362718"));
 System.out.println(service.findByName("张"));     System.out.println(service.findByBirthday(LocalDate.parse("2000-01-01"),LocalDate.parse("2020-01-01")));
      IPage<StudentBean> ip = service.cutAll(1);
      System.out.println(ip.getRecords() + " " + ip.getTotal() + " " + ip.getPages());
    }
}

条件查询

使用QueryWrappe绑定条件

    @Override
    public List<StudentBean> findByName(String name) {
        QueryWrapper<StudentBean> qw = new QueryWrapper<>();
        //精确查询,相当于= 判断是否相等
//        qw.eq("s_name", name);
        //模糊查询,相当于%aaa%
        qw.like("s_name", name);
        return mapper.selectList(qw);
    }
    public List<StudentBean> findByBirthday(LocalDate startDate, LocalDate endDate) {
        QueryWrapper<StudentBean> qw = new QueryWrapper<>();
        //大于等于
        qw.ge("s_birthday", startDate);
        //小于等于
        qw.le("s_birthday", endDate);
        return mapper.selectList(qw);
    }

分页查询

1、注册分页插件

@Configuration
public class MyBatisConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(
                new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

2、动态条件分页查询

    @Override
    public IPage<StudentBean> cutByItem(Integer pageNO, String name, LocalDate startDate, LocalDate endDate) {
     QueryWrapper<StudentBean> qw = new QueryWrapper<>();
        if (name != null && name.length() != 0) {
            qw.like("s_name", name);
        }
        if (startDate != null) {
            qw.ge("s_birthday", startDate);
        }
        if (endDate != null) {
            qw.le("s_birthday", endDate);
        }
     return mapper.selectPage(new Page<>(pageNO, 3), qw);
    }

关联查询

Mybatis-plus设计的初衷,是为了简化单表查询。如果需要进行联表操作,这时之前在实体类中定义的映射全部失效。需要重新定义resultMap映射。

一对多

1、定义实体类

@TableName("t_dept")
public class DeptBean {
    @TableId(value = "pk_deptId", type = IdType.AUTO)
    private Integer id;
    @TableField("d_name")
    private String name;
    @TableField("d_master")
    private String master;
    @TableField(exist = false)
    private List<EmployeeBean> emList;
}

在实体类中,如果属性没有映射数据表的列时,需要加@TableField(exist = false)标识该属性没有对应的数据库列。否则,mybatis-puls查询该属性同名的列。

@TableName("t_employee")
public class EmployeeBean {
    @TableId(value = "pk_emId",type = IdType.AUTO)
    private Integer id;
    @TableField("e_name")
    private String name;
    @TableField("e_birthday")
    private LocalDate birthday;
    @TableField(exist = false)
    private DeptBean dept;
    @TableField("fk_deptId")
    private Integer deptId;
}
多方操作

添加操作

1、定义业务接口方法

  public void add(EmployeeBean em);

2、业务接口实现类

emMapper.insert(em);

查询员工,同时查询员工所在的部门名称

导入分页插件

@Configuration
public class MyBatisConfig {
    @Bean
    public MybatisPlusInterceptor getInterceptor() {
        MybatisPlusInterceptor plus = new MybatisPlusInterceptor();
        plus.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return plus;
    }
}

1、定义业务接口方法

    /**
     * 按编号查询员工,同时查询员工所在部门信息
     *
     * @param id 员工编号
     * @return 员工对象
     */
    public EmployeeBean findById(Integer id);

2、业务接口实现类

@Service
@Transactional
public class EmployeeServiceImpl implements IEmployeeService {
    @Autowired
    private IEmployeeMapper emMapper;
    @Autowired
    private IDeptMapper deptMapper;
    
       @Override
    public EmployeeBean findById(Integer id) {
 EmployeeBean employeeBean = emMapper.selectById(id);
  employeeBean.setDept(deptMapper.selectById(employeeBean.getDeptId()));
        return employeeBean;
    }
}

联表动态条件分页查询

1、定义业务接口

  public IPage<EmployeeBean> cutByItem(Integer pageNO, String emName, String deptName);

2、定义mapper接口

    public IPage<EmployeeBean> cutByItem(Page pg, @Param("emName") String emName,@Param("deptName") String deptName);

3、书写mapper文件

    <resultMap id="emMap" type="EmployeeBean">
        <id property="id" column="pk_emId"></id>
        <result property="name" column="e_name"></result>
        <result property="birthday" column="e_birthday"></result>
        <result property="dept.name" column="d_name"></result>
    </resultMap>
    <select id="cutByItem" resultMap="emMap">
        select e.*,d.d_name from t_employee e,t_dept d where e.fk_deptId=d.pk_deptId
        <if test="emName !=null and emName!=''">
            and e_name like "%"#{emName}"%"
        </if>
        <if test="deptName!=null and deptName!=''">
            and d_name like "%"#{deptName}"%"
        </if>
    </select>

4、书写业务方法

public IPage<EmployeeBean> cutByItem(Integer pageNO, String emName, String deptName);
一方操作

批量添加。添加部门同时添加部门员工

1、定义业务接口

    /**
     * 添加部门,同时添加该部门的员工
     *
     * @param deptBean 部门对象
     * @param emList   员工集合
     */
    public void add(DeptBean deptBean, List<EmployeeBean> emList);

2、定义mapper接口

    public void addEmployeeList(@Param("deptId") Integer deptId, @Param("emList") List<EmployeeBean> emList);

3、书写mapper文件

    <insert id="addEmployeeList">
        insert into t_employee(e_name,e_birthday,fk_deptId) values
<foreach collection="emList" separator="," item="em">
            (#{em.name},#{em.birthday},#{deptId})
 </foreach>
    </insert>

4、书写业务方法

    public void add(DeptBean deptBean, List<EmployeeBean> emList) {
        deptMapper.insert(deptBean);
        deptMapper.addEmployeeList(deptBean.getId(), emList);
    }

批量删除,删除部门同时删除部门员工

1、定义业务接口

    /**
     * 删除部门,同时删除该部门的员工
     *
     * @param id 部门id
     */
    public void del(Integer id);

2、业务接口实现类

    public void del(Integer id) {
     QueryWrapper<EmployeeBean> qw = new QueryWrapper<>();
        qw.eq("fk_deptId", id);
        emMapper.delete(qw);
        deptMapper.deleteById(id);
    }

也可以在mapper接口中定义方法,书写SQL语句完成。

@Delete("delete from t_employee where fk_deptId=#{id};" + "delete from t_dept where pk_deptId=#{id}")
    public void del(Integer id);

关联查询,查询部门。同时查询部门的员工信息

1、定义业务接口

    /**
     * 按id查询部门,同时查询该部门的员工信息
     * @param id  部门id
     * @return 部门对象
     */
    public DeptBean findById(Integer id);

2、书写业务接口实现类

    @Override
    public DeptBean findById(Integer id) {
        DeptBean deptBean = deptMapper.selectById(id);
        QueryWrapper<EmployeeBean> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fk_deptId", id);
        deptBean.setEmList(emMapper.selectList(queryWrapper));
        return deptBean;
    }
多对多

多对多操作。大部分时候都是对中间表进行操作。一般情况,设置为单向的多对多。

用户实体类

@TableName("t_user")
public class UserBean {
    @TableId(value = "pk_userId", type = IdType.AUTO)
    private Integer id;
    @TableField("u_name")
    private String name;
    @TableField(exist = false)
    private List<GradeBean> gradeList;
}

权限实体类

@TableName("t_grade")
public class GradeBean {
    @TableId(value = "pk_gradeId", type = IdType.AUTO)
    private Integer id;
    @TableField("g_name")
    private String name;
}

添加用户,同时添加用户的权限

1、定义业务接口方法

    /**
     * 添加用户同时添加用户的权限
     *
     * @param userBean     用户对象
     * @param gradeIdArray 权限id数组
     */
    public void add(UserBean userBean, Integer[] gradeIdArray);

2、定义mapper方法

    public void addGradeList(@Param("userId") Integer userId,
                             @Param("gradeArray") Integer[] gradeArray);

3、书写mapper文件

    <insert id="addGradeList">
        insert into t_user_grade(fk_userId,fk_gradeId) values
        <foreach collection="gradeArray" item="gradeId" separator=",">
            (#{userId},#{gradeId})
        </foreach>
    </insert>

4、书写业务方法

    public void add(UserBean userBean, Integer[] gradeIdArray) {
        userMapper.insert(userBean);
        userMapper.addGradeList(userBean.getId(), gradeIdArray);
    }

删除用户,同时删除用户权限

1、定义业务方法

    /**
     * 删除用户,同时删除用户权限
     *
     * @param id 用户id
     */
    public void del(Integer id);

2、定义mapper方法

  @Delete("delete from t_user_grade where fk_userId=#{userId}")
    public void delUserGrade(Integer userId);

3、书写业务方法

    public void del(Integer id) {
        userMapper.deleteById(id);
        userMapper.delUserGrade(id);
    }

修改用户权限

1、定义业务方法

    /**
     * 修改用户权限
     *
     * @param id            用户id
     * @param newGradeArray 新的权限id数组
     */
    public void update(Integer id, Integer[] newGradeArray);

2、书写业务方法

    public void update(Integer id, Integer[] newGradeArray) {
        userMapper.delUserGrade(id);
        userMapper.addGradeList(id, newGradeArray);
    }

按id查询用户,同时查询用户的权限

1、定义业务方法

    /**
     * 按ID查询用户,同时查询用户权限
     * @param id 用户id
     * @return 用户对象
     */
    public UserBean findById(Integer id);

2、定义mapper方法

public List<GradeBean> findByUser(Integer userId);

3、书写mapper文件

<mapper namespace="com.project.mapper.IGradeMapper">
    <resultMap id="gradeMap" type="GradeBean">
        <id property="pk_gradeId" column="id"></id>
        <result property="name" column="g_name"></result>
    </resultMap>
    <select id="findByUser" resultMap="gradeMap">
        SELECT g.*
        FROM t_grade g,
             t_user_grade ug
        WHERE g.pk_gradeId = ug.fk_gradeId
          AND ug.fk_userId = #{id}
    </select>

4、书写业务方法

    public UserBean findById(Integer id) {
        UserBean userBean = userMapper.selectById(id);
        userBean.setGradeList(gradeMapper.findByUser(id));
        return userBean;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值