Spring知识整合(主要SSM)

本文深入探讨了Spring Framework、MyBatis的整合过程,包括Maven配置、Spring配置、MyBatis配置、Mapper接口与XML映射文件的结合使用。还介绍了Spring的IoC、AOP、事务管理、日志配置以及MyBatis的动态SQL、缓存机制。此外,文章还涵盖了Spring MVC的配置与工作原理,以及如何在SSM框架中实现文件上传与下载功能。
摘要由CSDN通过智能技术生成

Spring介绍

Spring实际上指的是Spring Framework
使用Spring可以让java Bean之间进行有效的解耦

IOC(Inversion of Control)中文控制反转

使用Spring之后我们可以将对象的创建、初始化和销毁等操作交给Spring容器来管理。如果其他Bean需要使用这个Bean,可以直接去Spring容器去要。

1.创建一个Maven工程
在这里插入图片描述
2.从https://mvnrepository.com/查询sprint-context
在这里插入图片描述
在pom.xml文件中添加

  <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.4</version>
        </dependency>    
    </dependencies>

3.在resources文件下创建applicationContext文件
在这里插入图片描述
4.获取容器
applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--用户bean java反射实现的 -->
    <bean class="org.brills.model.User" id="user"></bean>
</beans>

Main.java

 public static void main(String[] args) {
        //绝对路径加载 FileSystemXmlApplicationContext ftx= new FileSystemXmlApplicationContext("G:\\ideaWork\\ioc01\\src\\main\\resources\\applicationContext.xml");
        ClassPathXmlApplicationContext ctx= new ClassPathXmlApplicationContext("applicationContext.xml");
        //User u=(User)ctx.getBean("user");
        // User u = ctx.getBean(User.class);
        User u = ctx.getBean("user",User.class);
        System.out.println("username:"+u.getName());
    }

属性注入

1.通过bean构造方法注入属性

 <!--用户bean java反射实现的  构造方法注入-->
    <bean class="org.brills.model.User" id="user">
        <constructor-arg name="age" value="18"></constructor-arg>
        <constructor-arg name="name" value="垃圾"></constructor-arg>
        <constructor-arg name="sex" value="男"></constructor-arg>
    </bean>

2.set方法注入

<!--set方法注入-->
    <bean class="org.brills.model.User" id="user2">
        <property name="age" value="20"></property>
        <property name="name" value="爸爸"></property>
        <property name="sex" value="?"></property>
     </bean>

3.p名称空间注入

  <!--p空间注入-->
    <bean class="org.brills.model.User" id="user3" p:name="啊哈" p:sex="女" p:age="14"></bean>

4.静态工厂注入
OkHttpStaticFactory.java

public class OkHttpStaticFactory {
    private static OkHttpClient okHttpClient;
    public static OkHttpClient getInstance(){
        if(okHttpClient==null){
            okHttpClient=new OkHttpClient.Builder().build();
        }
        return okHttpClient;
    }
}
    <!--静态工厂注入 -->
    <bean class="org.brills.model.OkHttpStaticFactory" factory-method="getInstance" id="okHttpClient"></bean>

5.实例工厂注入
OkHttpFatcory.java

public class OkHttpFatcory {
    private OkHttpClient okHttpClient;
    public  OkHttpClient getInstance(){
        if(okHttpClient==null){
            okHttpClient=new OkHttpClient.Builder().build();
        }
        return okHttpClient;
    }
}
  <!--动态工厂注入-->
    <bean class="org.brills.model.OkHttpFatcory" id="okHttpFatcory"></bean>
    <bean class="okhttp3.OkHttpClient" factory-bean="okHttpFatcory" factory-method="getInstance" id="okHttpClient2"></bean>

复杂属性注入
6.对象注入

<!--复杂属性注入-->
    <bean class="org.brills.model.Cat" id="cat">
        <property name="name" value="Tom"></property>
        <property name="age" value="3"></property>
    </bean>
<!--set方法注入-->
    <bean class="org.brills.model.User" id="user2">
        <property name="age" value="20"></property>
        <property name="name" value="爸爸"></property>
        <property name="sex" value="?"></property>
        <property name="cat" ref="cat"></property>
     </bean>

7.数组注入

<property name="cats">
            <array>
                <ref bean="cat"></ref>
                <bean class="org.brills.model.Cat" >
                    <property name="name" value="Tom"></property>
                    <property name="age" value="3"></property>
                </bean>
            </array>
        </property>

8.Map注入

<property name="details">
            <map>
                <entry key="gender" value="男"></entry>
                <entry key="age" value="58"></entry>
            </map>
        </property>

9.Properties注入

<property name="info">
            <props>
                <prop key="age">89</prop>
                <prop key="name">javaboy</prop>
            </props>
        </property>

10.列表注入

 <property name="favorites">
            <list>
                <value>看书</value>
                <value>画画</value>
            </list>
        </property>

java配置

使用java代码配置spring而不是xml文件
JavaConfig.java

//@Configuration注释表示这是一个java配置类,配置作用类似applicationContext.xml
@Configuration
public class JavaConfig {
    @Bean
    SayHello sayHello(){
        return new SayHello();
    }
}

Main.java

 public static void main(String[] args) {
        AnnotationConfigApplicationContext atx= new AnnotationConfigApplicationContext(JavaConfig.class);
        SayHello sayHello= atx.getBean("sayHello",SayHello.class);
        System.out.println( sayHello.sayHello());
    

也可以这样写
JavaConfig.java

//@Configuration注释表示这是一个java配置类,配置作用类似applicationContext.xml
@Configuration
public class JavaConfig {
    @Bean("hl")
    SayHello sayHello(){
        return new SayHello();
    }
}

Main.java

 public static void main(String[] args) {
        AnnotationConfigApplicationContext atx= new AnnotationConfigApplicationContext(JavaConfig.class);
        SayHello sayHello= atx.getBean("hl",SayHello.class);
        System.out.println( sayHello.sayHello());
    }

自动扫描注入(自动化配置)

  • @Component
  • @Repository
  • @Service
  • @Controller

这四个中三个都是基于@Component做出来的。
JavaConfig.java

@Configuration
@ComponentScan(basePackages = "org.brills.service")//自动扫描该包下
public class JavaConfig {
    @Bean("hl")
    SayHello sayHello(){
        return new SayHello();
    }
}

UserService.java

@Service
public class UserService {
    public User getUser(){

        return new User("babba",12,'男');
    }
}

Main.java

 UserService us= atx.getBean(UserService.class);
        System.out.println(us.getUser().getName());

根据注解扫描

@ComponentScan(basePackages = "org.brills.service",useDefaultFilters = false,includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = Service.class)})
useDefaultFilters = false//关闭自动默认扫描
includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = Service.class)//设置自定义扫描,只扫描service

根据XML文件注解

 <context:component-scan base-package="org.brills.service"  use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
    </context:component-scan>

对象注入
自动扫描时对象注入的三种方式

  • @Autowired
  • @Resources
  • @Injected

UserDao.java

@Repository
public class UserDao {
    public String hello(){
        return "hello brillsDao";
    }
}

UserService.java

@Service
public class UserService {
    @Autowired
    UserDao userDao;

    public User getUser(){
        System.out.println(userDao.hello());
        return new User("babba",12,'男');
    }
}

条件注解

案例根据系统是Windows还是Linux输出不同语句
ShowCmd.java接口

public interface ShowCmd {
    String showCmd();
}

WindowsShowCmd.java

public class WindowsShowCmd implements ShowCmd{
    public String showCmd() {
        return "windows";
    }
}

LinuxShowCmd.java

public class LinuxShowCmd implements ShowCmd{
    public String showCmd() {
        return "Linux";
    }
}

windowCondition.java

public class WindowsCondition implements Condition {
    //前一个是环境信息,后一个是Spring信息
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        String osName= conditionContext.getEnvironment().getProperty("os.name");

        return osName.toLowerCase().contains("win");
    }
}

LinuxConditition.java

 @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        String osName = conditionContext.getEnvironment().getProperty("os.name");
        return osName.toLowerCase().contains("linux");
    }

JavaConfig.java

@Configuration
public class JavaConfig {

    @Bean("cmd")
    @Conditional(WindowsCondition.class)
    ShowCmd winCmd(){
        return new WindowsShowCmd();
    }

    @Bean("cmd")
    @Conditional(LinuxCondition.class)
    ShowCmd LinuxCmd(){
        return new LinuxShowCmd();
    }
}

多环境切换
JavaConfig.java

  //开发环境下ds的设置
    @Bean
    @Profile("dev")
    DateSource devDs(){
        DateSource ds=new DateSource();
        ds.setUrl("jdbc://mysql:vhr");
        ds.setPassword("123");
        ds.setUsername("root");
        return ds;
    }
    //产品环境下ds的设置
    @Bean
    @Profile("prod")
    DateSource prodDs(){
        DateSource ds=new DateSource();
        ds.setUrl("jdbc://mysql://192.168.23.56:3306//vhr");
        ds.setPassword("dawdasdzfzf");
        ds.setUsername("root");
        return ds;
    }

Main.java

 public static void main(String[] args) {
        AnnotationConfigApplicationContext atx  =new AnnotationConfigApplicationContext();
        atx.getEnvironment().setActiveProfiles("dev");
        atx.register(JavaConfig.class);
        atx.refresh();
        DateSource ds=atx.getBean(DateSource.class);
        System.out.println(ds.getUrl());
    }

xml配置
applcationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<beans profile="dev">
    <bean class="org.brills.ioc.DateSource" id="devDs">
        <property name="password" value="1234"></property>
        <property name="url" value="jdbc://mysql:vhr"></property>
        <property name="username" value="root"></property>
    </bean>
</beans>
    <beans profile="prod">
        <bean class="org.brills.ioc.DateSource" id="prodDs">
            <property name="password" value="dwadasfza"></property>
            <property name="url" value="jdbc://mysql://192.168.23.56:3306//vhr"></property>
            <property name="username" value="root"></property>
        </bean>
    </beans>
</beans>

Main.java

  ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext();
        ctx.getEnvironment().setActiveProfiles("prod");
        ctx.setConfigLocation("applicationContext.xml");
        ctx.refresh();
        DateSource ds=ctx.getBean(DateSource.class);
        System.out.println(ds.getUrl());

其他

Bean的作用域
手动配置,每次生成不同的bean,不是只返回一个bean(单例)

<bean class="org.brills.ioc.DateSource" id="devDs" scope="prototype">

也可以使用注解

@ Scope("prototype")

id和name区别
id不支持多个值,name支持多个,中间用,隔开。
混合配置

@Configuration
@ImportResource("classpath:applicationContext.xml")
public class JavaConfig {
}

Aware接口

@Service
@PropertySource(value = "javaboy.properties")
public class AwareService implements BeanNameAware, BeanFactoryAware, ResourceLoaderAware, EnvironmentAware {
    private String beanName;
    private ResourceLoader resourceLoader;
    private Environment environment;
    //获取生成工厂
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {

    }
    //获取bean名字
    @Override
    public void setBeanName(String s) {
    this.beanName=s;
    }
    //获得环境信息
    @Override
    public void setEnvironment(Environment environment) {
    this.environment=environment;
    }
    //获得
    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
    this.resourceLoader=resourceLoader;
    }

    public void output() throws IOException {
        System.out.println(beanName);
        Resource resource=resourceLoader.getResource("javaboy.txt");
        BufferedReader br = new BufferedReader(new InputStreamReader(resource.getInputStream()));
        String s = br.readLine();
        System.out.println(s);
        br.close();
        String property = environment.getProperty("javaboy.address");
        System.out.println(property);
    }
}

Aop(Aspect Oriented Programming)面向切面编程

  • 切点 要添加代码的地方
  • 通知(增强)通知就是向切点动态添加的代码
  • 切面 切点+通知
  • 连接点 切点的定义

基于JDK动态代理Aop效果
MyCalculator.java接口

public interface MyCalculator {
    int add(int a,int b);
}

MyCalculatorImpl.java

public class MyCalculatorImpl implements MyCalculator{
    @Override
    public int add(int a, int b) {
        return (a+b);
    }
}

CalculatorProxy.java

public class CalculatorProxy {
    public static Object getInstance(MyCalculatorImpl myCalculator){
        return Proxy.newProxyInstance(CalculatorProxy.class.getClassLoader(), myCalculator.getClass().getInterfaces(), new InvocationHandler() {
            /**
             *
             * @param proxy 代理对象
             * @param method 代理的方法
             * @param args 方法的参数
             * @return 方法的返回值
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println(method.getName()+"方法开始执行力");
                Object invoke =method.invoke(myCalculator,args);
                System.out.println("方法结束了");
                return invoke;
            }
        });
    }
}

Main.java

public class Main {
    public static void main(String[] args) {
        MyCalculatorImpl myCalculator=new MyCalculatorImpl();
        MyCalculator calculator=(MyCalculator) CalculatorProxy.getInstance(myCalculator);
        int add=calculator.add(3,3);
        System.out.println("add="+add);
    }
}

Spring中的Aop
注解方式(不常用)
Action.java

//使用范围是方法
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)//运行时候还要存在
public @interface Action {

}

MyCalculator.java

    public interface MyCalculator {
    int add(int a,int b);
    void min(int a,int b);
}

MyCalculatorImpl.java

@Component
public class MyCalculatorImpl implements MyCalculator{
    @Action
    public int add(int a, int b) {
        return a+b;
    }

    @Override
    public void min(int a, int b) {
        System.out.println(a-b);
    }
}

LogAspect.java

@Component
//表示这是一个切面
@Aspect
public class LogAspect {
    //前置通知
    @Before("@annotation(Action)")
    public void before(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        System.out.println("方法名:"+name);
    }
}

JavaConfig.java

@Configuration
@ComponentScan
//开启自动代理
@EnableAspectJAutoProxy
public class JavaConfig {

}

Main.java

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext atx=new AnnotationConfigApplicationContext(JavaConfig.class);
        MyCalculator c= atx.getBean(MyCalculator.class);
        System.out.println("1+2=" + c.add(1,2));
    }
}

五种通知

  • @Before
  • @After
  • @AfterReturning返回通知
 @AfterReturning(value = "@annotation(Action)",returning = "r")
    public void returing(JoinPoint joinPoint,Integer r){
        System.out.println("返回值是"+r);
    }
  • @AfterThrowing异常通知
@AfterThrowing(value = "@annotation(Action)",throwing = "r")
    public void afterThrowing(JoinPoint joinPoint,Exception e){
        System.out.println("异常是"+e.getMessage());
    }
  • @Around环绕通知
@Around(value = "@annotation(Action)")
    public Object around(ProceedingJoinPoint pjp){
       //这个类似method.invoke()
       Object proceed= pjp.proceed(new Object[]{5,5});
       

以上的内容可以优化

 @Pointcut("@annotation(Action)")
    public void poitcut(){
        
    }
    //前置通知
    @Before("poitcut()()")
    public void before(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        System.out.println("方法名:"+name);
    }

非入侵式定义切点

   @Pointcut("execution(org.brills.aop.*.*(..)")
    public void before(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        System.out.println("方法名:"+name);
    }

XML配置Aop
applicationContext.xml

<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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean class="org.brills.LogAspect" name="logAspect"></bean>
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* org.brills.*.*(..))"/>
        <aop:aspect ref="logAspect">
            <aop:before method="before" pointcut-ref="pointcut"></aop:before>
            <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"></aop:after-throwing>
        </aop:aspect>
    </aop:config>
    <bean class="org.brills.MyCalulatorIml" name="myCalulatorIml"></bean>
</beans>

pom.xml


    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.6</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.6</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.3</version>
        </dependency>


    </dependencies>

SpringMVC

在这里插入图片描述

  1. 通过分析,如上url表示为:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器。
  2. HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。
  3. HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello。
  4. HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。
  5. HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。
  6. Handler让具体的Controller执行。
  7. Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。
  8. HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。
  9. DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。
  10. 视图解析器将解析的逻辑视图名传给DispatcherServlet。
  11. DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。最终视图呈现给用户。

添加web.xml
在这里插入图片描述
在这里插入图片描述
配置web.xml

<?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">
    <!--注册servlet-->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--初始化指定springMVC配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
    <!--启动顺序,数字越少,启动越早-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <!--所有请求都会被springMVC拦截-->
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

配置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">

    <!--自动扫包,由IOC容器统一管理-->
    <context:component-scan base-package="com.brills.controller"></context:component-scan>

    <!--让SpringMVC不处理静态资源.css .js .html .mp3 .mp4-->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>

    <!--mvc注解驱动-->
    <mvc:annotation-driven></mvc:annotation-driven>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <!--后缀-->
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>

编写HelloController.java

@Controller
public class HelloController {
    
    @RequestMapping("/hello")
    public String hello(Model model){
        //封装数据
        model.addAttribute("msg","这是后端发送的消息");

        return "hello";//会被视图解析器解析
    }
}

如果使用@RestController就不会被视图解析器解析,直接返回字符串

	<mvc:annotation-driven></mvc:annotation-driven>
简化了
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>

RestFul风格
HelloController.java

@Controller
public class HelloController {

    @RequestMapping("/hello/{msg}/{name}")
    public String hello(@PathVariable String msg,@PathVariable String name, Model model){
        //封装数据
        model.addAttribute("msg",name+msg);

        return "hello";//会被视图解析器解析
    }
}

在这里插入图片描述

  • @PostMapping
  • @RequestMapping
  • @GetMapping

重定向和转发
转发

return "forward:/WEB-INF/jsp/test.jsp"

有视图解析器后直接return “test”
重定向(地址会变化)

return "redirect:/index.jsp

接收请求参数

  public String hi(@RequestParam("msg") String msg,Model model){

传输对象(要求参数必须一致)

@GetMapping("/hu")
    public String hi(User user, Model model){
        model.addAttribute("msg",user.toString());
        return "hello";
    }

在这里插入图片描述

  • LinkedHashMap
  • ModeMap继承了LinkeMap
  • ModelAndView可以在储存数据的同时,返回逻辑视图
  • Model只有几个方法适合用于储存

乱码问题解决

在web.xml中配置乱码过滤器

  <!--配置SpringMVC中的乱码过滤器-->
    <filter>
        <filter-name>encoding</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>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

JSON

Fastjson
在这里插入图片描述

@Controller
public class UserController {

    @RequestMapping(value = "/j1",produces = "application/json;charset=utf-8")//解决json乱码问题
    @ResponseBody //他就不会走视图解析器,会直接返回一个字符串
    public String json1() throws JsonProcessingException {
        User u=new User();
        u.setId(123);
        u.setName("哈哈哈");
        ObjectMapper mapper =new ObjectMapper();
        String str= mapper.writeValueAsString(u);
        return str;
    }
}

在这里插入图片描述

也可以在springmvc.xml里面配置json乱码问题

 <!--JSON乱码问题配置-->
    <!--mvc注解驱动-->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"></constructor-arg>
            </bean>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                        <property name="failOnEmptyBeans" value="false"></property>
                    </bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

输出时间,修改时间格式

@RequestMapping("/j2")
    @ResponseBody //他就不会走视图解析器,会直接返回一个字符串
    public String json2() throws JsonProcessingException {
        Date date=new Date();
        SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yy-MM-dd");
        ObjectMapper mapper =new ObjectMapper();
        mapper.setDateFormat(simpleDateFormat);

        return mapper.writeValueAsString(date);
    }

FastJson

@RequestMapping("/j3")
    @ResponseBody //他就不会走视图解析器,会直接返回一个字符串
    public String json3() throws JsonProcessingException {
        User u=new User();
        u.setId(123);
        u.setName("哈哈哈");
        return JSON.toJSONString(u);
    }

    @RequestMapping("/j4")
    @ResponseBody //他就不会走视图解析器,会直接返回一个字符串
    public String json4() throws JsonProcessingException {

        Date date =new Date();
        return JSON.toJSONStringWithDateFormat(date,"yyyy-MM-dd");
    }
  • JSON.toJSONString()//java对象转JSON字符串
  • JSON.parseObject(str,User.class)//json字符串转Java对象
  • (JSONObject)JSON.toJSON(user)//java对象转JSON对象
  • JSON.toJavaObject(jsonObject,User.class)//json对象转java对象

Mbatis

引入依赖

<dependencies>
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.21</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

编写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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/study?serverTimezone=GMT"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
 <mappers>
        <mapper resource="com/brills/dao/UserMapper.xml"></mapper>
    </mappers>

</configuration>

编写MybatisUtils工具类

public class MyBatisUtils {
    private static SqlSessionFactory sqlSessionFactory=null;
    static {
        String resource = "mybatis-config.xml";
        try {
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //获取sqlsession
    public static SqlSession getSqlSession(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        return sqlSession;
    }

}

编写UserMapper.xml

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--绑定一个对应的接口-->
<mapper namespace="com.brills.dao.UserDao">

    <select id="getUserList" resultType="com.brills.pojo.User">
        select * from t_user
    </select>


</mapper>

编写测试方法

  @Test
    public void test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        UserDao userDao =sqlSession.getMapper(UserDao.class);
        List<User> userList=userDao.getUserList();

        for (User u : userList){
            System.out.println(u);
        }

        sqlSession.close();
    }

注意,如果报Type interface com.brills.dao.UserDao is not known to the MapperRegistry.错误,就是xml配置中没有mappers
解决maven资源过滤问题在pom.xml文件添加

   <!--maven资源过滤解决-->
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>

CRUD增删改查

  • id:就是对于namespace中的方法
  • resultType:sql语句执行的返回值
  • parameterType:参数类型
<!--绑定一个对应的接口-->
<mapper namespace="com.brills.dao.UserDao">

    <select id="getUserList" resultType="com.brills.pojo.User">
        select * from t_user
    </select>

    <insert id="addUser" parameterType="com.brills.pojo.User">
        insert into t_user(uid,uname) values(#{uid},#{uname})
    </insert>

    <select id="getUser" resultType="com.brills.pojo.User">
        select * from t_user where uid=#{uid}
    </select>

    <update id="updateUser" parameterType="com.brills.pojo.User" >
        update t_user set uid=#{uid},uname=#{uname} where uid=#{uid}
    </update>

    <delete id="deleteUser">
        delete from t_user where uid =#{uid}
    </delete>
</mapper>

增删改最后要提交事务sqlSession.commit();
Map传输储存

UserMapper.xml
 <insert id="addUser2" parameterType="map">
        insert into t_user (uid,uname) values(#{uid},#{uname})
    </insert>
UserDao.java
  int addUser2(Map<String,Object> map);
  UserDaoTest.java
 Map<String,Object> map =new HashMap<>();
        map.put("uid",1553);
        map.put("uname","Map储存");
        userDao.addUser2(map);
  • Map传输参数,直接在sql中取出key即可!【parameterType= “map”】
  • 对象传输参数,直接在sql中取出对象的属性即可【parameterType=“Object”】
  • 只有一个基本类参数的情况下,可以直接在sql中取到!
  • 多个参数用Map,或者注解

配置解析

环境配置(environments)
MyBatis 可以配置成适应多种环境,但每个 SqlSessionFactory 实例只能选择一种环境。
事务管理器(transactionManager)
在 MyBatis 中有两种类型的事务管理器(也就是 type="[JDBC|MANAGED]"):
JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接。然而一些容器并不希望连接被关闭,因此需要将 closeConnection 属性设置为 false 来阻止默认的关闭行为。例如:
数据源(dataSource)

  • UNPOOLED– 这个数据源的实现会每次请求时打开和关闭连接。虽然有点慢,但对那些数据库连接可用性要求不高的简单应用程序。
  • POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这种处理方式很流行,能使并发 Web 应用快速响应请求。
  • JNDI – 这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的数据源引用。

属性(properties)
首先编写db.properties文件储存配置

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/study?serverTimezone=GMT
username=root
password=123456

其次在mybaties-config.xml中引入

<properties resource="db.properties"></properties>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

也可以在其中增加一些属性配置,优先使用外部配置

<properties resource="org/mybatis/example/config.properties">
  <property name="username" value="dev_user"/>
  <property name="password" value="F2Fa3!33TYyg"/>
</properties>

类型别名(typeAliases)
可以为java写一个缩写,仅限xml配置中

<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
  <typeAlias alias="Blog" type="domain.blog.Blog"/>
  <typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>

也可以指定一个包名,Mybatis会在包名下扫描Java Bean

<typeAliases>
  <package name="domain.blog"/>
</typeAliases>

也可以注解修改别名

@Alias("author")
public class Author {
    ...
}

设置(settings)

设置名描述
cacheEnabled全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 true /false
lazyLoadingEnabled延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。true /false
<settings>
  <setting name="cacheEnabled" value="true"/>
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="multipleResultSetsEnabled" value="true"/>
  <setting name="useColumnLabel" value="true"/>
  <setting name="useGeneratedKeys" value="false"/>
  <setting name="autoMappingBehavior" value="PARTIAL"/>
  <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
  <setting name="defaultExecutorType" value="SIMPLE"/>
  <setting name="defaultStatementTimeout" value="25"/>
  <setting name="defaultFetchSize" value="100"/>
  <setting name="safeRowBoundsEnabled" value="false"/>
  <setting name="mapUnderscoreToCamelCase" value="false"/>
  <setting name="localCacheScope" value="SESSION"/>
  <setting name="jdbcTypeForNull" value="OTHER"/>
  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

plugins插件

  • mybatis-generator-core
  • mybatis-plus
  • 通用mapper

映射器

  1. 配置相对路径资源引用<mapper resource="com/brills/dao/UserMapper.xml"></mapper>
  2. 使用映射器接口实现类<mapper class="com.brills.dao.UserDao"></mapper>
  3. 将包内映射器接口实现全部注册为映射器<package name="com.brills.dao"/>
    接口和配置文件必须同名在同一个包下

生命周期

SqlSessionFactoryBuilder//一旦创建就不需要它

SqlSessionFactory//数据库连接池,一旦创建就一直存在

SqlSession//连接到连接池的一个请求,线程不是安全的所以不能共享,用完关闭避免资源被占用

Mapper//代表具体的一个业务

ResultMap解决属性名和字段名不一致的问题

  • 起别名select uid as id from t_user
  • 结果集映射
    <resultMap id="UserMap" type="User">
        <result column="uid" property="id" ></result>
    </resultMap>

日志工厂

  • SLF4J
  • Apache Commons Logging
  • Log4j 2
  • Log4j(掌握)
  • JDK logging
  • STDOUT_LOGGING(掌握)

在mybaties配置文件中设置

<configuration>
  <settings>
    ...
    <setting name="logImpl" value="LOG4J"/>
    ...
  </settings>
</configuration>

log4j
导入依赖

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

在resources中创建log4j.properties文件

log4j.rootLogger=DEBUG,console,file

#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=【%c】-%m%n

#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/logging.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=【%p】【%d{yy-MM-dd}】【%c】%m%n

#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

log4j的使用

 static Logger logger = Logger.getLogger(UserDaoTest.class);
		  logger.info("这是提示信息");
        logger.debug("这是测试信息");
        logger.error("这是错误信息");

分页插件MyBatis分页插件PageHelper
使用注解开发
需要绑定接口<mapper class="com.brills.work.dao.UserDao"></mapper>

    //底层主要运用反射
   @Select("select * from t_user")
    List<User> getUsers() ;

    //方法存在多个参数
 @Select("select * from t_user" where id=#{id})
    List<User> getUsers(@Param("id") int id) ;

@Insert(“insert into user(id,name,pwd) values (#{id},#{name},#{password})”)
	int addUser(User user);

@Update("update user set name = #{name},pwd=#{password} where id =#{id}")
 int updateUser(User user);
 
 @Delete("Delete from  user where id =#{id}")
 int deleteUser(@Param("uid" int id));

使用注解来映射简单语句,会使得代码显得更加简洁,相对于一些复杂的语句,java显得力不从心。如果需要完成很复杂的查询,最好使用XML映射语句
在这里插入图片描述
设置自动提交SqlSession sqlSession = sqlSessionFactory.openSession(true);

复杂查询环境

多表查询举例
mysql> select u.uname '名字' , g.num '成绩' from t_user u,t_grade g where u.uid = g.gid;
在这里插入图片描述
在User实体类中增加Grade属性

    //新增成绩
    private Grade grade;

修改UserMapper.xml

 <select id="getUserGradeList" resultMap="UserGrade">
        select u.uid , u.uname  , g.num  from t_user u,t_grade g where u.uid = g.gid
    </select>

    <resultMap id="UserGrade" type="com.brills.pojo.User">
        <result property="uid" column="uid"></result>
        <result property="uname" column="uname"></result>
        <!--复杂属性需要单独处理, 对象 association  集合  collection -->
        <association property="grade" javaType="com.brills.pojo.Grade">
            <result property="gid" column="uid"></result>
            <result property="num" column="num"></result>
        </association>
    </resultMap>
    

查询结果:

User{uid=10, uname='前端', grade=Grade{gid=10, num=98}}
User{uid=1553, uname='Map储存', grade=Grade{gid=1553, num=125}}

多对一查询
查询每个老师带领的学生们

<select id="getTeacher" resultMap="TeacherStudent">
        select s.id sid, s.name sname , t.id tid, t.name tname from student s, teacher t where s.tid = t.id
    </select>

    <resultMap id="TeacherStudent" type="com.brills.pojo.Teacher">
        <result property="id" column="tid"></result>
        <result property="name" column="tname"></result>
        <!--复杂属性需要单独处理, 对象 association  集合  collection 
	javaType="" 指定属性的类型
	集合中泛型信息,我们使用ofType获取
-->
        <collection property="students" ofType="com.brills.pojo.Student">
            <result property="id" column="sid"></result>
            <result property="name" column="sname"></result>
        </collection>
    </resultMap>

动态SQL

  • if
  • choose(when , otherwise)
  • trim(where , set)
  • foreach

创建一个表

create table blog (
 id varchar(50) not null comment '博客id',
 title varchar(100) not null comment '博客标题',
 author varchar(30) not null comment '博客作者',
 create_time datetime not null comment '创建时间',
 views int(30) not null comment '浏览量'
) ENGINE=InnoDB DEFAULT CHARSET=utf8

创建一个实体类

public class Blog {
    private String id;
    private String title;
    private  String author;
    private Date createTime;
    private int views;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public int getViews() {
        return views;
    }

    public void setViews(int views) {
        this.views = views;
    }
}

创建id生成工具类

@SuppressWarnings("all") //抑制警告
public class IDutills {

    public static String getId(){
        return UUID.randomUUID().toString().replaceAll("-","");
    }
}

因为数据库中create_time对应实体类中的createTime,不能够直接映射,所以需要在mybatis-config.xml配置中添加驼峰命名模式映射

<settings>
        <!-- 是否开启驼峰命名模式  映射 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

if标签
BlogMapper.xml

 <select id="queryBlogIF" parameterType="map" resultType="com.brills.pojo.Blog">
        select * from blog where title like '%${title}%'
    <if test="author !=null">
        and author =#{author}
    </if>
    </select>

Test方法

  @Test
    public void queryBlogIF(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        BlogDao blogDao = sqlSession.getMapper(BlogDao.class);
        HashMap<String,String> map = new HashMap<>();
        map.put("title","不");
        map.put("author","彬彬");
        List<Blog> blogList=blogDao.queryBlogIF(map);
        for(Blog bl:blogList){
            System.out.println(bl);
        }
        sqlSession.close();
    }

chose标签

  <select id="queryBlogChose" parameterType="map" resultType="com.brills.pojo.Blog">
        select * from blog where title like '%${title}%'
    <choose>
           <when test="author != null">
               AND author like '%${author}%'
           </when>
            <when test="views != null">
                AND views = #{views}
            </when>
            <otherwise>
                AND views = 7
            </otherwise>
       </choose>
    </select>

Where标签

<select id="queryBlogWhere" parameterType="map" resultType="com.brills.pojo.Blog">
        select * from blog
    <where>
        <if test="title !=null">
            title like '%${title}%'
        </if>
        <if test="author !=null">
            and author =#{author}
        </if>
        <if test="views !=null">
            and views =#{views}
        </if>

    </where>
    </select>

set标签

<update id="updateBlog" parameterType="map" >
        update blog
    <set>
        <if test="title !=null">
            title = #{title},
        </if>
        <if test="author !=null">
            author = #{author},
        </if>
        <if test="views !=null">
            views = #{views}
        </if>
    </set>
    where id =#{id}
    </update>

foreach 标签

  <select id="queryBlogIn"  resultType="com.brills.pojo.Blog">
        select * from blog where id in
        <foreach item="id" index="index" collection="list"
        open="(" separator="," close=")">
            #{id}
        </foreach>
    </select>

运行效果

 Preparing: select * from blog where id in ( ? , ? )

也可以用map当参数传入list参数(map中必须存一个键值为list的列表)

  <select id="queryBlogIn"  resultType="com.brills.pojo.Blog" parameterType ="map">
        select * from blog where id in
        <foreach item="id" index="index" collection="list"
        open="(" separator="," close=")">
            #{id}
        </foreach>
    </select>

Mybatis缓存

用户将查询到数据不用在磁盘上查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题
Memcache 服务器实现三方面:Memcache内存缓存技术、静态化技术、mysql优化
减少和数据库交互的次数,减少系统开销,提高系统效率。
mybatis中定义了两级缓存:一级缓存和二级缓存

  • 默认情况下,只有一级缓存开启。(SqlSession级别的呼延村,也成为本地缓存)
  • 二级缓存需要手动开启和配置,它是基于namespace级别的缓存。
  • 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存

缓存失效情况

  1. 查询不同的东西
  2. 增删改操作,可能改变原来的数据,所以必定会刷新缓存
  3. 查询不同的Mapper.xml
  4. 手动清理缓存sqlSession.clearCache();

二级缓存

在mapper.xml文件中加

<cache/>

1.首先开启全局缓存

   <settings>
  <!--开启全局缓存-->
        <setting name="cacheEnabled" value="true"/>
   </settings>

配置标签也可以这样详细设计

<cache eviction="FIFO"
           flushInterval="60000"
            size="512"
            readOnly="true">
    </cache>

2.将实体类实现序列化

public class Blog implements Serializable 

自定义缓存-ehcache

SSM整合

1.导入依赖

    <!--依赖: junit :数据库驱动,连接池,servlet,jsp,mybatis,mybattis-spring-->
    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.6</version>
        </dependency>


        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.21</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

            <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.3.4</version>
            </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.6</version>
            <scope>runtime</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.3.8</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.3.9</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/jstl/jstl -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.9</version>
        </dependency>

    </dependencies>

2.maven资源过滤设置

 <!--maven资源过滤解决-->
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>

3.创建包
在这里插入图片描述

在这里插入图片描述
写实体类、dao层和service层
例:

public class UserServiceImpl {
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    List<User> getUserList() {
    return userDao.getUserList();
    }
    void addUser(User user) {
        userDao.addUser(user);
    }
    User getUser(int uid) {
    return userDao.getUser(uid);
    }
    void updateUser(User user) {
    userDao.updateUser(user);
    }
    void deleteUser(int uid) {
        userDao.deleteUser(uid);
    }
    int addUser2(Map<String,Object> map){
        return userDao.addUser2(map);
        }

    List<User> getUserGradeList(){
        return userDao.getUserGradeList();
}
}

4.配置
1.db.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/study?serverTimezone=GMT
jdbc.username=root
jdbc.password=123456

2.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <import resource="spring-dao.xml"></import>
    <import resource="spring-service.xml"></import>
    <import resource="spring-mvc.xml"></import>
</beans>

3.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>

    <settings>

        <setting name="logImpl" value="LOG4J"/>

    </settings>

    <!--配置数据源,交给Spring(让他们自己起别名)-->
    <typeAliases>
        <package name="com.brills.pojo"/>
    </typeAliases>
    
    <mappers>
        <mapper resource="com/brills/dao/UserMapper.xml"></mapper>
        <mapper resource="com/brills/dao/BlogMapper.xml"></mapper>
    </mappers>

</configuration>

4.spring-dao.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">

    <!--1.关联数据库配置文件-->
    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
    <!--2.连接池-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <!--3.sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:mybatis-config.xml" />
    </bean>
    <!--配置dao接口扫描包,动态实现Dao接口可以注入到Spring容器中-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--扫描dao包-->
        <property name="basePackage" value="com.brills.dao"/>
    </bean>
</beans>

5.spring-service.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">

    <!--扫描service下的包-->
    <context:component-scan base-package="com.brills.service"></context:component-scan>
    <!--2.将所有的业务类,注入到spring,可以通过配置或者注解实现-->
    <bean id="UserServiceImpl" class="com.brills.service.UserServiceImpl">
        <property name="userDao" ref="userDao"></property>
    </bean>
    <!--声明式事务配置-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--4.aop事务支持-->
</beans>

6.添加web支持
在这里插入图片描述
7.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:mvc="http://www.springframework.org/schema/mvc"
       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/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--1.注解驱动-->
    <mvc:annotation-driven/>
    <!--2.静态资源过滤-->
    <mvc:default-servlet-handler/>
    <!--3.扫描包:controller-->
    <context:component-scan base-package="com.brills.controller"/>
    <!--4.视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF"></property>
        <property name="suffix" value=".html"></property>
    </bean>
</beans>

8.拦截器
创建MyInterceptor

public class MyInterceptor  implements HandlerInterceptor {
        //处理前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
       // System.out.println("拦截器已经运行");
       // request.getRequestDispatcher("/WEB-INF/").forward(request,response);
        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.xml文件添加如下代码

    <!--拦截器配置-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.brills.config.MyInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

文件上传和下载

pom.xml中加入需要的依赖

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.8.0</version>
        </dependency>

在SpringMVC中注入文件上传配置

<!--文件上传配置-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--请求的编码格式,必须和pageEncoding属性一致,默认为ISO-8859-1-->
        <property name="defaultEncoding" value="utf-8"></property>
        <!--上传文件大小上线,单位为字节(10485760=10m)-->
        <property name="maxUploadSize" value="10485760"></property>
        <property name="maxInMemorySize" value="40960"></property>
    </bean>

在File.html中加入前端代码实现上传下载

<fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;">
    <legend>拖拽上传</legend>
</fieldset>
<div class="layui-upload-drag" id="file">
    <i class="layui-icon">🧑‍💻</i>
    <p>点击上传,或将文件拖拽到此处</p>
    <div class="layui-hide" id="uploadDemoView">
        <hr>
        <img src="" alt="上传成功后渲染" style="max-width: 196px">
    </div>
</div>
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;">
    <legend>下载文件</legend>
</fieldset>
<div class="layui-btn-container" >

   <a href="/SSM/file/download"><button type="button" class="layui-btn layui-btn-normal layui-btn-radius">下载按钮</button></a>

</div>
<script>
    layui.use(['upload', 'layer'], function(){
        var $ = layui.jquery
            ,upload = layui.upload
            ,layer = layui.layer;
    //拖拽上传
    upload.render({
        elem: '#file'
        ,url: '/SSM/file/upload' //此处用的是第三方的 http 请求演示,实际使用时改成您自己的上传接口即可。
        ,done: function(res){
            layer.msg(res.msg);
            layui.$('#uploadDemoView').removeClass('layui-hide').find('img').attr('src', res.file);
            console.log(res)
            console.log("上传执行完成")
        }
    });
    });
</script>

在这里插入图片描述
在FileController中添加代码实现文件上传下载

 public class FileUpState{
        int code;
        String msg;
        Map<String,String> data;
        String file;

        @Override
        public String toString() {
            return "FileUpState{" +
                    "code=" + code +
                    ", msg='" + msg + '\'' +
                    ", data=" + data +
                    ", file='" + file + '\'' +
                    '}';
        }

        public String getFile() {
            return file;
        }

        public int getCode() {
            return code;
        }

        public String getMsg() {
            return msg;
        }

        public Map<String, String> getData() {
            return data;
        }

        public FileUpState(int code, String msg, Map<String, String> data, String file) {
            this.code = code;
            this.msg = msg;
            this.data = data;
            this.file = file;
        }
    }


    @RequestMapping("/index")
    public String fileIndex(Model model){

        return "file";
    }

    //批量上传CommonsMultipartFile为数组即可
    @ResponseBody
    @RequestMapping("/upload")
    public String fileUpload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request)throws IOException {
    //上传路径保存设置
        String path = request.getServletContext().getRealPath("/upload");
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }

        //通过CommonsMultipartFile的方法直接写文件
        file.transferTo(new File(realPath+"/"+file.getOriginalFilename()));
        System.out.println("上传成功");
        Map<String,String> map =new HashMap<>();
        map.put("src","www.baidu.com");
        FileUpState fileUpState =new FileUpState(0,"你干的漂亮,崽种!",map,"http://localhost:8080/SSM/upload/"+file.getOriginalFilename());
        System.out.println(JSON.toJSONString(fileUpState));
        return JSON.toJSONString(fileUpState);

    }

    @RequestMapping("/download")
    public String fileDownload(HttpServletRequest request, HttpServletResponse response)throws IOException {
        String  path = request.getServletContext().getRealPath("/upload");
        String  fileName = "a.jpg";

        //1、设置response 响应头
        response.reset(); //设置页面不缓存,清空buffer
        response.setCharacterEncoding("UTF-8"); //字符编码
        response.setContentType("multipart/form-data"); //二进制传输数据
        //设置响应头
        response.setHeader("Content-Disposition",
                "attachment;fileName="+ URLEncoder.encode(fileName, "UTF-8"));

        File file = new File(path,fileName);
        //2、 读取文件--输入流
        InputStream input=new FileInputStream(file);
        //3、 写出文件--输出流
        OutputStream out = response.getOutputStream();

        byte[] buff =new byte[1024];
        int index=0;
        //4、执行 写出操作
        while((index= input.read(buff))!= -1){
            out.write(buff, 0, index);
            out.flush();
        }
        out.close();
        input.close();
        return null;

    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一天发火两次

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值