ssm_springboot

Spring_AOP

1. AOP相关概念

常用的术语如下:
●Target (目标对象) :代理的目标对象
●Proxy (代理) :一个类被AOP织入增强后,就产生一 个结果代理类
●Joinpoint (连接点) :所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方
法类型的连接点
●Pointcut (切入点) :所谓切入点是指我们要对哪些Joinpoint进行拦截的定义
●Advice (通知/增强) :所谓通知是指拦截到Joinpoint之后所要做的事情就是通知

●Weaving (织入) :是指把增强应用到目标对象来创建新的代理对象的过程。spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入。

2. Srping_aop的动态代理
2.1.基于jdk动态代理
public class ProxyTest {
    public static void main(String[] args) {
        //目标对象
        final Target target = new Target();
        //增强对象
        final  Advice advice = new Advice();
        //返回值是动态生成的代理对象
        MyInterface proxyInstance = (MyInterface) Proxy.newProxyInstance(
                //目标对象类加载器
                target.getClass().getClassLoader(),
                //目标对象的相同接口字节码数组对象
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    //调用代理对象的任何方法,实质都是调用invoke方法
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //前置增强
                        advice.before();
                        method.invoke(target, args);
                        //后置增强
                        advice.after();
                        return null;
                    }
                }
        );
        proxyInstance.running();
    }
}
2.2.基于cglib动态代理
public class ProxyTest {
    public static void main(String[] args) {
        //目标对象
        final Target target = new Target();
        //增强对象
        final Advice advice = new Advice();
        //返回值是动态生成的代理对象
        //创建增强器
        Enhancer enhancer = new Enhancer();
        // 2. 设置父类
        enhancer.setSuperclass(Target.class);
        //设置回调
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                advice.before();
                Object invoke = method.invoke(target, args);
                advice.after();
                return invoke;
            }
        });
        //创建代理对象
        Target proxy =(Target) enhancer.create();

        proxy.running();
    }
}
3. XML方式实现AOP
3.1实现步骤:

①导入AOP相关坐标

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.0.5.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>5.0.5.RELEASE</version>
  <scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.9.6</version>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-test</artifactId>
  <version>5.0.5.RELEASE</version>
  <scope>test</scope>
</dependency>

②创建目标接口和目标类(内部有切点)
③创建切面类(内部有增强方法)
④将目标类和切面类的对象创建权交给spring

<!--目标对象-->
<bean id="target" class="cn.xxxx.proxy.aop.Target"/>
<!--切面对象-->
<bean id="myAspect" class="cn.xxxx.proxy.aop.MyAspect"/>

⑤在applicationContext.xml中配置织入关系

<!--配置织入:告诉spring那些(切点)需要增强-->
<aop:config>
    <!--声明切面-->
    <aop:aspect ref="myAspect">
        <!--切面: 切点+通知-->
        <aop:before method="beforeqian" pointcut="execution(public void cn.xxxx.proxy.aop.Target.running())"></aop:before>
    </aop:aspect>
</aop:config>

⑥测试代码

3.2 切点表达式

表达式语法:

execution ([修饰符]返回值类型 包名.类名.方法名(参数))

●访问修饰符可以省略
返回值类型、包名、类名、方法名可以使用星号*代表任意
●包名与类名之间一个点代表当前包下的类,两个点…表示当前包及其子包下的类
●参数列表可以使用两个点 … 表示任意个数,任意类型的参数列表
例如:

execut ion (public void com. ithe ima. aop. Target .method() ) 
execution (void com. itheima .aop. Target. *(..))
execution(* com. itheima.aop. *.*(..)
execution(* com. itheima.aop. .*.* (. .) )
execution(* *..*.*(..))
3.3 通知的类型

通知的配置语法:

<aop:通知类型method=“切面类中方法名”pointcut= "切点表达式"> </aop:通知类型>
名称标签说明
前置通知<aop:before >用于配置前置通知。指定增强的方法在切入点方法之前执行
后置通知< aop:after-returning>用于配置后置通知。指定增强的方法在切入点方法之后执行
环绕通知< aop:around>用于配置环绕通知。指定增强的方法在切入点方法之前和之后都执行
异常抛出通知< aop:throwing>用于配置异常抛出通知。指定增强的方法在出现异常时执行
最终通知< aop:after>用于配置最终通知。无论增强方式执行是否有异常都会执行

示例:

  <aop:config>
        <!--声明切面-->
        <aop:aspect ref="myAspect">
            <!--切面: 切点+通知-->
            <!--前置通知-->
            <!--<aop:before method="beforeqian" pointcut="execution(public void cn.xxxx.proxy.aop.Target.running())"></aop:before>-->
            <!--后置通知-->
            <!--<aop:after-returning method="afterRunning" pointcut="execution(public void cn.xxxx.proxy.aop.Target.running())"></aop:after-returning>-->
            <!--环绕通知 execution(任意修饰符 cn.xxxx.proxy.aop.任意类.任意方法(任意多个参数))-->
            <!--<aop:around method="around" pointcut="execution(* cn.xxxx.proxy.aop.*.*(..))"></aop:around>-->
            <!--异常增强-->
            <aop:after-throwing method="excption" pointcut="execution(* cn.xxxx.proxy.aop.*.*(..))"></aop:after-throwing>
            <!--最中增强-->
            <aop:after method="after" pointcut="execution(* cn.xxxx.proxy.aop.*.*(..))"></aop:after>
        </aop:aspect>
    </aop:config>

切面类:

public class MyAspect {
    //前置增强
    public void beforeqian(){
        System.out.println("前置增强");
    }

    //后置增强
    public void afterRunning(){
        System.out.println("后置增强");
    }
    //环绕增强
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("环绕前增强");
        Object proceed = pjp.proceed();
        System.out.println("环绕后增强");
        return proceed;
    }
    //异常抛出增强
    public void excption(){
        System.out.println("异常抛出增强!!!");
    }

    //最终增强
    public void after(){
        System.out.println("最终增强!!!");
    }
}
3.4.切点表达式的抽取
<!--切点表达式的抽取-->
<aop:pointcut id="myPointcut" expression="execution(* cn.xxxx.proxy.aop.*.*(..))"></aop:pointcut>

<aop:around method="around" pointcut-ref="myPointcut"></aop:around>
<aop:after-returning method="afterRunning" pointcut-ref="myPointcut"></aop:after-returning>

4. 基于注解的AOP开发

开发步骤:
①创建目标接口和目标类(内部有切点)
②创建切面类(内部有增强方法)
③将目标类和切面类的对象创建权交给spring

@Component("myAspect")      @Component("target")

④在切面类中使用注解配置织入关系

@Aspect   //标注当前类是一个切面类
public class MyAspect {
    //前置增强
    @Before("execution(* cn.xxxx.anno.*.*(..))")
    public void beforeqian(){
        System.out.println("前置增强");
    }
}

⑤在配置文件中开启组件扫描和AOP的自动代理

<!--扫描包-->
<context:component-scan base-package="cn.xxxx.anno"/>

<!--aop自动代理-->
<aop:aspectj-autoproxy/>

⑥测试

4.2 注解配置aop详解

前置通知 @Before
后置通知 @AfterReturning
环绕通知 @Around
异常抛出通知 @AfterThrowing
最终通知 @After

4.2.1 使用注解切点表达式的抽取
//抽取切点表达式
@Pointcut("execution(* cn.xxxx.anno.*.*(..))")
public void pointcut(){}

//异常抛出增强
@AfterThrowing("MyAspect.pointcut()")
public void excption(){
    System.out.println("异常抛出增强!!!");
}

//最终增强
@After("pointcut()")
public void after(){
    System.out.println("最终增强!!!");
}

Spring 简介:

1、Spring的体系结构:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MiJ7UfML-1652404831826)(https://pic.baixiongz.com/uploads/2021/10/28/27a625f3634fd.png)]

2.Spring 程序开发步骤

  1. 导入Spring开发的基本包坐标
 <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
  1. 编写Dao接口和实现类
   @Override
    public void sava() {
        System.out.println("sava running");
    }

3.创建Spring核心配置文件

4.在Spring配置文件中配置UserDaoImpl

//在Resource 目录下创建 configuration file --> spring sonfiguration 
<?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">
    //配置ID 
      <bean id="user" class="cn.xxxx.domain.User" scope="prototype">
        <property name="name" value=""/>  // 赋初始值
        <property name="age" value="15"/>
        <property name="gender" value=""/>
    </bean>
</beans>
  1. 使用Spring的API获得Bean实例
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationControl.xml");
    UserDao userDao = (UserDao) app.getBean("userDao");
    userDao.sava();
}

3. Spring 配置文件

3.1 Bean标签范围

scope : 值对象的作用范围

取值范围说明
singleton默认值,单例的
prototype多例的 获取的地址是不同的
requestWEB 项目中,Spring创建一个Bean对象。将一个对象存入request域中
sessionWEB 项目中,Spring创建一个Bean对象。将一个对象存入session域中
global sessionWEB项目中,应用在Portlet环境,如果没有Portlet环境那么globalSession相当于session

a)、当scope 的取值为 singleton时

<bean id="userDao" class="cn.xxxx.dao.impl.UserDaoImpl" scope="singleton"></bean>   //获取的地址是同一个 ,Bean的实例化个数为一个;
Bean实例化实际:当Spring核心文件被加载时 实例化配置的Bean实例
    Bean的生命周期  :
    对象创建:当应用加载 ,创建容器时,对象就被创建了
    对象运行: 只要容器在,对象就一直活着
        对象销毁: 当应用卸载,销毁容器时,对象就销毁了

b)、当scope 的取值为 prototype 时

<bean id="userDao" class="cn.xxxx.dao.impl.UserDaoImpl" scope="prototype "></bean>   //获取的地址是多个 ,Bean的实例化个数多个;
    Bean实例化实际:当调用getBean()方法时实例化Bean
    Bean的生命周期  :
    对象创建:当使用对象时,创建新的对象实例
    对象运行: 只要对象在使用中,就一直活着
    对象销毁: 当对象长时间不用时,被Java的回收器回收了

**3.2 依赖注入: **

3.2.1 > 分析:

因为UserService和UserDao 都在Spring容器中,而最终程序直接使用的是UserService,

所以可以在Spring容器中,将UserDao设置到UserService内部。

3.2.2 > 依赖注入概念 :

它是Spring 框架核心IOC的具体实现。

3.2.3 > 依赖注入的方式:

  • 构造方法:
<bean id="userService" class="cn.xxxx.service.UserSersiceImpl" >
    <constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>

userServiceimpl:

public UserSersiceImpl(UserDao userDao) {
    this.userDao = userDao;
}

public void sava(){
    userDao.sava();
}
  • set方法:
<bean id="userService" class="cn.xxxx.dao.impl.UserDaoImpl">
    <!--对象引用类型 使用ref  普通类型使用value-->
    <property name="userDao" ref="userDao"></property>

</bean>
<!--       p命名空间 注入本质也是set方法注入 首先导入P命名空间-->
xmlns:p="http://www.springframework.org/schema/p"
<bean id="userDao" class="cn.xxxx.dao.impl.UserDaoImpl" scope="prototype"></bean>
<bean id="userService" class="cn.xxxx.service.UserSersiceImpl" p:userDao-ref="userDao"> </bean>

main:  
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) app.getBean("userDao");
userDao.sava();

3.2.4 : 集合注入的类型 :

  • 普通数据类型

  • 引用数据类型

  • 集合数据类型

  <!--测试集合注入-->
    <bean id="userDao" class="cn.xxxx.dao.impl.UserDaoImpl">
        <property name="strList">
            <list>
                <value>aaa</value>
                <value>bbb</value>
                <value>ccc</value>
            </list>
        </property>

        <property name="mapuser">
            <map>
                <entry key="user1" value-ref="user1"></entry>
                <entry key="user2" value-ref="user2"></entry>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="aaa">12323</prop>
                <prop key="bbb">144545</prop>
            </props>
        </property>

    </bean>
    <!--domian 实体类 -->
    <bean id="user1" class="cn.xxxx.domain.User">
        <property name="name" value="jack"/>
        <property name="age" value="18"/>
        <property name="gender" value="男"/>
    </bean>
    <bean id="user2" class="cn.xxxx.domain.User">
        <property name="name" value="luck"/>
        <property name="age" value="12"/>
        <property name="gender" value="女"/>
    </bean>

3.3 引入其他配置文件
   <import resource="applicationContext-user.xml"/>

Spring的重点配置 :

<bean> 标签
    id属性:在容器中bean实例的唯一标识,不允许重复
    class 属性:要实例化的bean的全限定名
    scope 属性:Bean 的作用范围,常是Singleton(默认)和 prototype
    <property> 标签:属性注入
        name属性:属性名称
        value属性:注入的普通属性值
        ref属性:注入的对象引用值
    <list>标签
    <map> 标签
    <properties>标签
    <constructor-arg>标签

4.Spring相关API

4.1 ApplicationContext的实现类

1> ClassPathPathXmlApplicationContext

从类的根路径下加载配置文件

2>FileSystemXmlApplicationConText

从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置

public void test01() {
    ApplicationContext ac = new FileSystemXmlApplicationContext("F:\\y2\\SSMKJ\\SSM_Studay\\Spring_01\\src\\main\\resources\\applicationContext.xml");
    UserDao userDao = (UserDao) ac.getBean("userDao");
    userDao.sava();
}

3>AnnotationConfigApplicationContext

当使用注解配置容器对象时,需要使用此类来创建spring容器,他用看来读取注解;

4.2 getBean() 方法使用
public Object getBean()throws BeansException{
    sava();
    return getBean(name);
}

public <T> T getBean(Class<T> requiredType) {
    sava();
    return getBean(requiredType);
}

ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
//UserDao userDao = (UserDao) app.getBean("id");
UserDao userDao = app.getBean(UserDao.class);
userDao.sava();

5 .配置数据源

@Test
//测试创建c3p0数据源
public void test001() throws Exception {
    ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
    comboPooledDataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
    comboPooledDataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/ssm");
    comboPooledDataSource.setUser("root");
    comboPooledDataSource.setPassword("lyg146837");
    Connection connection = comboPooledDataSource.getConnection();
    System.out.println(connection);
    connection.close();
}
//c3p0加载properties文件
ResourceBundle rb = ResourceBundle.getBundle("jdbc");
ComboPooledDataSource cd = new ComboPooledDataSource();
cd.setDriverClass(rb.getString("jdbc.driver"));
cd.setJdbcUrl(rb.getString("jdbc.url"));
cd.setUser(rb.getString("jdbc.username"));
cd.setPassword(rb.getString("jdbc.password"));
Connection connection = cd.getConnection();
System.out.println(connection);
connection.close();

@Test
//测试创建Druid数据源
public void testDruid() throws SQLException {
    DruidDataSource druidDataSource = new DruidDataSource();
    druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    druidDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/ss");
    druidDataSource.setUsername("root");
    druidDataSource.setPassword("lyg146837");
    DruidPooledConnection connection = druidDataSource.getConnection();
    System.out.println(connection);
    connection.close();
}
5.1 Spring 容器产生数据源

创建bean实例:

<!--cp30-->
<bean id="dateSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property>
    <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/ssm"></property>
    <property name="user" value="root"></property>
    <property name="password" value="lyg146837"></property>
</bean>

<!--druid数据源-->
<bean id="dateSourceds" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
    <property name="url" value="jdbc:mysql://127.0.0.1:3306/ssm"></property>
    <property name="username" value="root"></property>
    <property name="password" value="lyg146837"></property>
</bean>

测试Spring 容器配置产生cp30数据源:

public void test001() throws Exception {
    ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
    DataSource dateSource = (DataSource) app.getBean("dateSource");
    Connection connection = dateSource.getConnection();
    System.out.println(connection);
    connection.close();
}
5.2 Spring 加载properties文件
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<!--引入context命名空间-->
       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
<!--引入context地址-->
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:property-placeholder location="jdbc.properties"/>
    <bean id="dateSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

6. Spring 注解开发

1. Spring 原始注解

注解名作用
@Component使用在类上用于实例化Bean
@Controller使用在web层类上用于实例化Bean
@Service使用在service层类上用于实例化Bean
@Repository使用在dao层类上用于实例化Bean
@Autowired使用在字段上用于根据类型依赖注入
@Qualifier结合@Autowired一起使用用于根据名称进行依赖注入
@Resource相当于@Autowired+@Qualifier,按照名称进行注入
@Value注入普通属性
@Scope标注Bean的作用范围
@PostConstruct使用在方法上标注该方法是Bean的初始化方法
@PreDestroy使用在方法上标注该方法是Bean的销毁方法
1.1 使用注解创建bean对象
//<bean id="userDao" class="cn.xxxx.dao.impl.UserDaoImpl"></bean>
@Component("userDao")
1.2 使用注解注入参数
// <property name="userDao" ref="userDao"/>
@Autowired
@Qualifier("userDao")

@Resource(name="userDao")  //效果同上
1.3 配置组件扫描
<!--配置组件扫描-->  告诉spring 需要扫描的包,从而找到它下面的注解
<context:component-scan base-package="cn.xxxx"/>
1.4 @Value 注入普通属性
@Value("${jdbc.driver}");  //从Spring容器中加载值,注入到属性上
private String driver;
1.5 @Scope 标注作用范围
@Scope("singleton")  //允许实例化单个bean
@Scope("prototype")  //允许实例化多个bean

2. Spring 新注解

注解名使用说明
@Configuration指定当前类是一个配置类
@ComponentScan(basePackage=“{包名1,包名2}”)用于通过注解指定sprig在创建容器时扫描的包
@Bean(name=“id叫啥”)用于把当前方法的返回值作为bean对象添加到IOC容器中,添加到IOC中,Bean在IOC中是以set类型存储的就必须有键值对,所以这个name属性就是当前bean的id
如果不写的话,默认是方法的全名,不做改变
当我们使用注解配置方法是,如果方法有参数,spring框架会在容器中寻找有没有可用的bean对象,寻找的方法和@Autowired是一样的
@Import(value=“XXX.class”)用于导入其他的配置类
那么有import注解的类就是父配置类,引入的就是子配置类
@PropertySource(value=“classpath:jdbc.properties”)用于指定properties文件的位置
关键字classpath代表的当前类路径下的
@Qualifier()可以用在参数修饰中,当一个类有多个对象的时候,来确定这个函数用哪一个
public QueryRunner createQueryRunner(@Qualifier(“ds2”) DataSource datasource)

测试实例:

创建dataSource类:

// <context:property-placeholder location="jdbc.properties"/>
@PropertySource("classpath:jdbc.properties")    //解析properties配置文件到容器中
public class DataSourceConfig {
    @Value("${jdbc.driver}")  //从容其中获取,并赋给下面对应的属性
    private  String driver;
    @Value("${jdbc.url}")
    private  String url;
    @Value("${jdbc.username}")
    private  String username;
    @Value("${jdbc.password}")
    private  String password;

    @Bean("dataSource")   //将该方法的返回值,以指定的名称存到Spring容器中
    public DataSource getDataSource() throws PropertyVetoException {
        ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
        comboPooledDataSource.setDriverClass(driver);
        comboPooledDataSource.setJdbcUrl(url);
        comboPooledDataSource.setUser(username);
        comboPooledDataSource.setPassword(password);
        return comboPooledDataSource;
    }
}

创建SpringConfig类:

@Configuration
//<context:component-scan base-package="cn.xxxx"/>
//扫描配置
@ComponentScan("cn.xxxx")
@Import({DataSourceConfig.class})  //导入DataSourceConfig数据源类
public class SpringConfig {

}

3. Spring集成Junit

导入坐标:

junit 坐标
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
springJunit 测试坐标
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.0.5.RELEASE</version>
</dependency>

创建测试类:

  1. 测试XXX.xml配置文件形式
@RunWith(SpringJUnit4ClassRunner.class) //让SpringJUnit代替原来的运行期进行测试
@ContextConfiguration("classpath:applicationContext.xml")  //使用配置文件的方式告诉SpringJUnit需要测试的Spring容器
public class SpringJunitTest {
    @Autowired    //自动注入 如果有值 代表测试成功
    private UserDaoService userService;

    @Autowired
    private DataSource dataSource;
    @Test
    public void test1() throws SQLException {
        userService.save();
        System.out.println(dataSource.getConnection());
    }
}
  1. 测试使用全注解方式:
@ContextConfiguration(classes = {SpringConfig.class})  //使用quan注解方式告诉SpringJunit

7.Spring 集成Web环境

7.1基本环境搭建:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");  //读取配置创建Spring容器
    UserService bean = app.getBean(UserService.class);
    bean.save();
}

web.xml代码
<servlet>
    <servlet-name>usercontrol</servlet-name>
    <servlet-class>cn.xxxx.control.UserControl</servlet-class>
        </servlet>
        <servlet-mapping>
        <servlet-name>usercontrol</servlet-name>
        <url-pattern>/userc</url-pattern>
        </servlet-mapping>
</servlet>
7.2 ApplicationContext 获取上下文方式

7.1.1 使用监听器创建Spring容器

  1. 创建ContextLoad类,实现ServletContextListener接口的初始化和销毁方法:
public class ContextLoad implements ServletContextListener {
    //初始化方法 当Spring创建容器时 会执行此方法
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); //读取配置文件
        ServletContext servletContext = servletContextEvent.getServletContext();
        servletContext.setAttribute("app",app); //将容器存到最大的作用域中
        System.out.println("创建完毕");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }


}
  1. 在web.xml 文件中配置监听器
<listener>
    <listener-class>cn.xxxx.listener.ContextLoad</listener-class>
</listener>
  1. 在servlet中使用
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    ServletContext servletContext = request.getServletContext(); //创建ServletContext对象
    ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app"); //从ServletContext对象中获取容器
    UserService bean = app.getBean(UserService.class);
    bean.save();
}

7.1.2 优化上方代码:

<!--    创建初始化参数-->
    <context-param>
        <param-name>springResource</param-name>
        <param-value>applicationContext.xml</param-value>
    </context-param>

ContextLoad类代码:

 ServletContext servletContext = servletContextEvent.getServletContext();
 String springResource = servletContext.getInitParameter("springResource");

 ApplicationContext app = new ClassPathXmlApplicationContext(springResource);

7.1.3 Spring 提供获取上下文工具

  1. 导入坐标:
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>5.0.5.RELEASE</version>
</dependency>
  1. 使用:
 protected void doGet(HttpServletRequest request, HttpServletResponse response)  {
        ServletContext servletContext = this.getServletContext();
        ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        UserService bean = app.getBean(UserService.class);
        bean.save();
 }

Sping MVC

1. 简介:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TmbF9K5f-1652404831827)(https://www.fnkc.net/public/2022/01/07/47b5100bb3212.png)]

1.1 使用步骤:
  1. 导入坐标
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>5.0.5.RELEASE</version>
</dependency>
  1. 配置SpringMVC核心控制器DispatherServlet

    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
  2. 创建Controller类和视图页面

  3. 使用注解配置Controller类中的业务方法的映射地址

    @Controller
    public class UserMVCControl {
        @RequestMapping("/quick")
        public String save(){
            System.out.println("Control save running!!");
            return "success.jsp";
        }
    }
    
  4. 配置SpringMVC核心文件spring-mvc.xml

    <context:component-scan base-package="cn.xxxx.control"/>
    

2. SpringMVC 组件解析

2.1 SpringMVC 注解解析

@RequestMapping

作用: 作用于建立请求URl和处理请求方法之间的对应关系

位置: 类上,请求URl的第一级访问目录 ,不写的话,相当于应用的根目录

   	方法上,请求URl的第二级访问目录 ,于类上使用的@RequestMapping标注的一级目录一起组成一串虚拟路径。
@RequestMapping("/user")
public class UserMVCControl {
    @RequestMapping("/quick")
    public String save(){
        System.out.println("Control save running!!");
        return "/success.jsp";  //斜杠表示从当前应用下查找
    }
}
//http://localhost:8088/spring_mvc/user/quick

参数:

@RequestMapping(value = "/quick",method = RequestMethod.POST,params = {"username"})
  • value 用于指定请求的URl ,作用和path一样
  • method 用于指定请求方式
  • params 用于指定限制请求参数的条件,参数的key和value必须和配置的一样。
2.2 SpringMVC的XML配置解析
<!--原地址-->
return "/jsp/success.jsp";  
<!--配置内部资源视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/jsp/"></property>  <!--前缀-->
    <property name="suffix" value=".jsp"></property>   <!--后缀-->
</bean>
<!--解析后-->
return "success"; 

小结 :

相关组件:

  1. 前端控制器: DispatcherServlet
  2. 处理器映射器 : HandlerMapping
  3. 处理器适配器 : HandlerAdapter
  4. 处理器 : Handler
  5. 视图解析器 : ViewResolver
  6. 视图 : View

3. SpringMVC 的数据响应

3.1 SpringMVC 的数据响应方式

1)页面跳转

  • 直接返回字符串
  • 通过ModelAndView对象返回
//第一种
@RequestMapping(value = "/quick2")
    public ModelAndView save2(){
        /*
        Model:模型: 作用封装数据
        View: 视图: 作用展示数据
       */
        ModelAndView modelAndView =new ModelAndView();
        //设置模型数据
        modelAndView.addObject("username","lyg");
        //设置视图名称
        modelAndView.setViewName("success");
        return modelAndView;
    }
//第二种
    @RequestMapping(value = "/quick3")
    public ModelAndView save3(ModelAndView modelAndView){
        //设置模型数据
        modelAndView.addObject("username","光");
        //设置视图名称
        modelAndView.setViewName("success");
        return modelAndView;
    }

success.jsp页面
    ${username}

2)回写数据

  • 直接返回字符串
@RequestMapping(value = "/quick4")
public void save4(HttpServletResponse response) throws IOException {
    //设置模型数据
    response.getWriter().print("hello22222");
}
@RequestMapping(value = "/quick5")
@ResponseBody     //告诉Spring不要进行页面跳转   直接返回数据
public String save5(){
    //设置模型数据
    return "hello33333333";
}
  • 返回对象或集合
  1. 导入mvc命名空间
  2. 配置处理器映射器
<!--第一种 手动配置 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
        </list>
    </property>
</bean>
<!--第二种:注解驱动-->
<mvc:annotation-driven/>
  1. 创建对象并以json形式返回
@RequestMapping(value = "/quick6")
@ResponseBody
public User save6()  {
    User user = new User();
    user.setName("阿光");
    user.setAge(21);
    return user;
}

4.获得请求数据

4.1 获得请求数据
  1. 基本类型参数

    //Control类的方法的形参名称,要和请求的name一致
    http://localhost:8088/spring_mvc/user/quick7?username=guang&age=18
    
    @RequestMapping(value = "/quick7")
    @ResponseBody
    public  void save7(String username,int age)  {
        System.out.println(username+","+age);
    }
    
  2. POJO类型参数 (简单javabean)

    //Control中的业务方法的POJO参数的属性名与请求的name一致,参数值会自动映射
    // 其次User类中 要有getter 和setter 方法
    http://localhost:8088/spring_mvc/user/quick8?name=liguang&age=21
    @RequestMapping(value = "/quick8")
    @ResponseBody
    public  void save8(User user)  {
        System.out.println(user);
    }
    
  3. 数组类型参数

  4. 集合类型参数

1. 创建Vo类  创建字段类型是User的泛型集合
public class UserVo {
    private List<User> userList;

    public UserVo(List<User> userList) {
        this.userList = userList;
    }
}

2. 创建页面
    <form action="<%=request.getContextPath()%>/user/quick10" method="post">
    <input type="text" name="userList[0].name"/><br>
    <input type="text" name="userList[0].age"/><br>
    <input type="text" name="userList[1].name"/><br>
    <input type="text" name="userList[1].age"/><br>
    <input type="submit" value="提交">
    </form>    

3. 控制台输出
    @RequestMapping(value = "/quick10")
    @ResponseBody
    public  void save10(UserVo userVo)  {
        System.out.println(userVo);
    }
4.1.2开启静态资源访问
<!--    <mvc:resources mapping="/js/**" location="/js/"/>-->
    <mvc:default-servlet-handler/>
4.1.3 配置全局乱码过滤器
<!--配置全局编码过滤器-->
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
4.1.4 参数绑定注解@RequestParam()

参数:

  • value : 与请求数据名称匹配
  • required : 此在指定的请求参数是否必须包括,默认是true,提交时如果没有参数会报错 如果是flase,代表请求时参数非必须,如果没参数输出null,不报错。
  • defaultValue : 当没有指定请求参数时,则使用指定的默认值赋值 默认值
http://localhost:8088/spring_mvc/user/quick12?name=222

@RequestMapping("/quick12")
@ResponseBody
public  void save12(@RequestParam(value = "name",required = false,defaultValue = "guang") String username)  {
System.out.println(username);
}
4.1.5 获得Restful 风格的参数

HTTP协议里的四种操作方式:

  • GET : 用于获取资源 例:/user/1 GET : 得到id =1 的user
  • POST : 用于新建资源 例:/user POST : 新增user
  • PUT : 用于更新资源 例:/user/1 PUT :更新id=1的user
  • DELETE : 用于删除资源 例:/user/1 GET : 得到id =1 的user
http://localhost:8088/spring_mvc/user/quick13/songdan

@RequestMapping("/quick13/{username}")
@ResponseBody
public  void save13(@PathVariable(value = "username") String username)  {
System.out.println(username);
}
//输出:
 songdan
4.1.6 自定义类型转换器
  1. 定义转换器类实现Converter接口

    public class DataConverter implements Converter<String, Date> {
        @Override
        public Date convert(String dateStr) {
            SimpleDateFormat format =new SimpleDateFormat("yyyy-MM-dd");
            Date parse = null;
            try {
                parse = format.parse(dateStr);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return parse;
        }
    }
    
  2. 在配置文件中声明转换器

    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <bean class="cn.xxxx.converter.DataConverter"></bean>
            </list>
        </property>
    </bean>
    
  3. 在中引用转换器

<mvc:annotation-driven conversion-service="conversionService"/>
4.2 文件上传
4.2.1 文件上传客户端的三要素
  • 表单项type = “file”
  • 表单的提交方式是post
  • 表单的enctype属性是多部份表单形成,及enctype =“multipart/form-data”
4.2.2 单文件上传步骤
  1. 导入fileupload和io坐标

    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.3</version>
    </dependency>
    
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.8.0</version>
    </dependency>
    
  2. 配置文件上传解析器

    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="UTF-8"/>
        <property name="maxUploadSize" value="500000"/>
    </bean>
    
  3. 编写文件上传代码

    多文件上传

    3.1)、编写form表单代码

    1. 第一种不同上传的文件name也不一样
    <form method="post" action="<%=request.getContextPath()%>/user/quick15" enctype="multipart/form-data">
        名称<input type="text" name="username"/><br>
        文件<input type="file" name="upfile"/><br>
        文件<input type="file" name="upfile2"/><br>
        <input type="submit" value="提交"><br>
    </form>
    
    2. 第二种不同上传的文件name属性一样
    <form method="post" action="<%=request.getContextPath()%>/user/quick16" enctype="multipart/form-data">
        名称<input type="text" name="username"/><br>
        文件<input type="file" name="upfile"/><br>
        文件<input type="file" name="upfile"/><br>
        <input type="submit" value="提交"><br>
    </form>
    

​ 3.2、选择文件

​ 3.3、编写代码转移文件到新地址

1. 第一种接收的name属性不一样
    @RequestMapping("/quick15")
    @ResponseBody
    public  void save15(String username,MultipartFile upfile,MultipartFile upfile2) throws IOException {
    System.out.println(username);
    String originalFilename = upfile.getOriginalFilename();
    upfile.transferTo(new File("F:\\newfile\\"+originalFilename));
    String originalFilename2 = upfile2.getOriginalFilename();
    upfile2.transferTo(new File("F:\\newfile\\"+originalFilename2));
}
transferTo("新地址提前创建"+获取到的要上传的文件)2. 第二种接受的name属性一样
    @RequestMapping("/quick16")
    @ResponseBody                      //多个name属性一样时,使用数组接收   
    public  void save16(String username,MultipartFile[] upfile) throws IOException {
    System.out.println(username);
    for (MultipartFile multipartFile : upfile) {
        String originalFilename = multipartFile.getOriginalFilename();
        multipartFile.transferTo(new File("F:\\newfile\\"+originalFilename));
    }
}

JdbcTemplate

1. Spring JdbcTemplate 基本使用

1.1开发步骤:
  1. 导入spring-jdbc和spring-tx坐标

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
    
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
    
  2. 创建数据库表和实体

  3. 创建JdbcTemplate对象

  4. 执行数据库操作

    //新增
    @Test
    public void test1() throws PropertyVetoException {
        //创建数据源
        ComboPooledDataSource dataSource =new ComboPooledDataSource();
        dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/ssm");
        dataSource.setUser("root");
        dataSource.setPassword("lyg146837");
        JdbcTemplate jdbcTemplate =new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        //执行操作
        int tom = jdbcTemplate.update("insert Account values(?,?)", "tom", 5000.22);
        System.out.println(tom);
    }
    
1.2 Spring产生JdbcTemplate对象

第一步:(配置数据源bean和jdbc模板bean)

<!--加载jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--数据源对象-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driver}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
<!--jdbc模板对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
</bean>

第二步:(加载ApplicationContext.xml文件)

//删除
@Test
public void test2(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate bean = app.getBean(JdbcTemplate.class);
bean.update("delete  from  Account where name=?","tom");
}
1.3 使用SpringTest测试JdbcTemplate模板

1.3.1 执行更新操作:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JdbcTemplateCRUDTest {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Test
    public void test1(){
        int tom = jdbcTemplate.update("update Account set money=? where name=?", 8000, "tom");
        System.out.println(tom);
    }
}

1.3.2 执行查询操作

@Test
public void queryAll(){
    //查询全部使用query("sql语句",new BeanPropertyRowMapper<对应的实体类>(类的字节码))
    List<Account> query = jdbcTemplate.query("select * from Account", new BeanPropertyRowMapper<Account>(Account.class));
    System.out.println(query);
}


  //查询单个对象queryForObject("sql语句",new BeanPropertyRowMapper<对应的实体类>(类的字节码),"sql参数")
Account tom = jdbcTemplate.queryForObject("select * from Account where  name =?", new BeanPropertyRowMapper<Account>(Account.class), "tom");
System.out.println(tom);

1.3.4 查询记录数

@Test
public void queryCount() {
    //返回值是一个普通类型,Mapper参数也是简单类型
    Long count = jdbcTemplate.queryForObject("select count(*) from Account", Long.class);
    System.out.println(count);
}

spring Test(练习)

1.1 Spring 环境搭建步骤
  1. 创建工程(Project&Module)
  2. 导入静态页面(jsp页面)
  3. 导入需要坐标(pom.xml)
  4. 创建包结构(controller、service、dao,domain)
  5. 导入数据库脚本
  6. 创建POJO类
  7. 创建配置文件(applicationContext.xml、spring-mvc.xml、jdbc.properties)
1.2 配置 web.xml 和spring、spring-mvc
<!---web.xml->
   <!--全局初始化参数-->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--  spring 监听器-->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>


<!--  spring-mvc 前端控制器  -->
<servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<!--spring-->

<!--    加载jdbc.properties文件-->
<context:property-placeholder location="jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="jdbc.driver"/>
    <property name="jdbcUrl" value="jdbc.url"/>
    <property name="user" value="jdbc.user"/>
    <property name="password" value="jdbc.password"/>
</bean>

<!--    配置jdbc模板对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
</bean>


<!--spring-mvc-->
<!--注解驱动-->
<mvc:annotation-driven/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/pages"/>
    <property name="suffix" value=".jsp"/>
</bean>

<!--  静态资源开放-->
<mvc:default-servlet-handler/>

非重点:(从数据库获取刚插入的主键)

@Override
public Long save(User user) {
    PreparedStatementCreator creator = new PreparedStatementCreator() {
        @Override
        public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
            PreparedStatement preparedStatement = connection.prepareStatement("insert sys_user values(?,?,?,?,?)", PreparedStatement.RETURN_GENERATED_KEYS);
            preparedStatement.setObject(1, null);
            preparedStatement.setString(2, user.getUsername());
            preparedStatement.setString(3, user.getEmail());
            preparedStatement.setString(4, user.getPassword());
            preparedStatement.setString(5, user.getPhoneNum());
            return preparedStatement;
        }
    };
    //创建keyholder
    KeyHolder keyHolder = new GeneratedKeyHolder();
    jdbcTemplate.update(creator, keyHolder);
    //jdbcTemplate.update("insert sys_user values(?,?,?,?,?)",null,user.getUsername(),user.getEmail(),user.getPassword(),user.getPhoneNum());
    //获得生成的主键
    long userId = keyHolder.getKey().longValue();
    return userId;
}

spring 的事务

1. 编程式事务相关对象
  1. PlatformTransactionManager
  2. TransactionDefinition
  3. TransactionStatus
2. 基于XML的声明事务相关
<!--目标对象-->
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
    <property name="accountDao" ref="accountDao"/>
</bean>
<!--配置平台事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
 </bean>

<!--通知:事务的增强-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
     <!--设置事物的属性信息-->
        <tx:attributes>
            <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"></tx:method>
            
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>
<!--事务的aop织入-->
<aop:config>
    <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.service.impl.*.*(..))"></aop:advisor>
</aop:config>
3.基于注解的事务

applicationContext文件:

<!-- 配置平台事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>

<!--事务驱动注解-->
<tx:annotation-driven transaction-manager="transactionManager"/>
@Repository("accountDao")   //创建dao层实例
@Service("accountService")  //创建service实例

Sping MVC

1. 简介:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jf8XFx9W-1652404831828)(https://www.fnkc.net/public/2022/01/07/47b5100bb3212.png)]

1.1 使用步骤:
  1. 导入坐标
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>5.0.5.RELEASE</version>
</dependency>
  1. 配置SpringMVC核心控制器DispatherServlet

    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
  2. 创建Controller类和视图页面

  3. 使用注解配置Controller类中的业务方法的映射地址

    @Controller
    public class UserMVCControl {
        @RequestMapping("/quick")
        public String save(){
            System.out.println("Control save running!!");
            return "success.jsp";
        }
    }
    
  4. 配置SpringMVC核心文件spring-mvc.xml

    <context:component-scan base-package="cn.xxxx.control"/>
    

2. SpringMVC 组件解析

2.1 SpringMVC 注解解析

@RequestMapping

作用: 作用于建立请求URl和处理请求方法之间的对应关系

位置: 类上,请求URl的第一级访问目录 ,不写的话,相当于应用的根目录

   	方法上,请求URl的第二级访问目录 ,于类上使用的@RequestMapping标注的一级目录一起组成一串虚拟路径。
@RequestMapping("/user")
public class UserMVCControl {
    @RequestMapping("/quick")
    public String save(){
        System.out.println("Control save running!!");
        return "/success.jsp";  //斜杠表示从当前应用下查找
    }
}
//http://localhost:8088/spring_mvc/user/quick

参数:

@RequestMapping(value = "/quick",method = RequestMethod.POST,params = {"username"})
  • value 用于指定请求的URl ,作用和path一样
  • method 用于指定请求方式
  • params 用于指定限制请求参数的条件,参数的key和value必须和配置的一样。
2.2 SpringMVC的XML配置解析
<!--原地址-->
return "/jsp/success.jsp";  
<!--配置内部资源视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/jsp/"></property>  <!--前缀-->
    <property name="suffix" value=".jsp"></property>   <!--后缀-->
</bean>
<!--解析后-->
return "success"; 

小结 :

相关组件:

  1. 前端控制器: DispatcherServlet
  2. 处理器映射器 : HandlerMapping
  3. 处理器适配器 : HandlerAdapter
  4. 处理器 : Handler
  5. 视图解析器 : ViewResolver
  6. 视图 : View

3. SpringMVC 的数据响应

3.1 SpringMVC 的数据响应方式

1)页面跳转

  • 直接返回字符串
  • 通过ModelAndView对象返回
//第一种
@RequestMapping(value = "/quick2")
    public ModelAndView save2(){
        /*
        Model:模型: 作用封装数据
        View: 视图: 作用展示数据
       */
        ModelAndView modelAndView =new ModelAndView();
        //设置模型数据
        modelAndView.addObject("username","lyg");
        //设置视图名称
        modelAndView.setViewName("success");
        return modelAndView;
    }
//第二种
    @RequestMapping(value = "/quick3")
    public ModelAndView save3(ModelAndView modelAndView){
        //设置模型数据
        modelAndView.addObject("username","光");
        //设置视图名称
        modelAndView.setViewName("success");
        return modelAndView;
    }

success.jsp页面
    ${username}

2)回写数据

  • 直接返回字符串
@RequestMapping(value = "/quick4")
public void save4(HttpServletResponse response) throws IOException {
    //设置模型数据
    response.getWriter().print("hello22222");
}
@RequestMapping(value = "/quick5")
@ResponseBody     //告诉Spring不要进行页面跳转   直接返回数据
public String save5(){
    //设置模型数据
    return "hello33333333";
}
  • 返回对象或集合
  1. 导入mvc命名空间
  2. 配置处理器映射器
<!--第一种 手动配置 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
        </list>
    </property>
</bean>
<!--第二种:注解驱动-->
<mvc:annotation-driven/>
  1. 创建对象并以json形式返回
@RequestMapping(value = "/quick6")
@ResponseBody
public User save6()  {
    User user = new User();
    user.setName("阿光");
    user.setAge(21);
    return user;
}

    <mvc:annotation-driven conversion-service="conversionService">
        <!--消息转换器:不使用默认的jackson组件-->
        <mvc:message-converters register-defaults="true">
            <!--  配置FastJson工具中的消息转换器类-->
            <bean id="fastJsonConverters" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <!--                消息转换器类中的字段赋值,支持的枚举类型-->
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json;charset=utf-8</value>
                    </list>
                </property>
            </bean>

        </mvc:message-converters>
    </mvc:annotation-driven>
4. 重定向到某个页面
return "redirect:/role/list";

4.获得请求数据

4.1 获得请求数据
  1. 基本类型参数

    //Control类的方法的形参名称,要和请求的name一致
    http://localhost:8088/spring_mvc/user/quick7?username=guang&age=18
    
    @RequestMapping(value = "/quick7")
    @ResponseBody
    public  void save7(String username,int age)  {
        System.out.println(username+","+age);
    }
    
  2. POJO类型参数 (简单javabean)

    //Control中的业务方法的POJO参数的属性名与请求的name一致,参数值会自动映射
    // 其次User类中 要有getter 和setter 方法
    http://localhost:8088/spring_mvc/user/quick8?name=liguang&age=21
    @RequestMapping(value = "/quick8")
    @ResponseBody
    public  void save8(User user)  {
        System.out.println(user);
    }
    
  3. 数组类型参数

  4. 集合类型参数

1. 创建Vo类  创建字段类型是User的泛型集合
public class UserVo {
    private List<User> userList;

    public UserVo(List<User> userList) {
        this.userList = userList;
    }
}

2. 创建页面
    <form action="<%=request.getContextPath()%>/user/quick10" method="post">
    <input type="text" name="userList[0].name"/><br>
    <input type="text" name="userList[0].age"/><br>
    <input type="text" name="userList[1].name"/><br>
    <input type="text" name="userList[1].age"/><br>
    <input type="submit" value="提交">
    </form>    

3. 控制台输出
    @RequestMapping(value = "/quick10")
    @ResponseBody
    public  void save10(UserVo userVo)  {
        System.out.println(userVo);
    }
4.1.2开启静态资源访问
<!--    <mvc:resources mapping="/js/**" location="/js/"/>-->
    <mvc:default-servlet-handler/>
4.1.3 配置全局乱码过滤器
<!--配置全局编码过滤器-->
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
4.1.4 参数绑定注解@RequestParam()

参数:

  • value : 与请求数据名称匹配
  • required : 此在指定的请求参数是否必须包括,默认是true,提交时如果没有参数会报错 如果是flase,代表请求时参数非必须,如果没参数输出null,不报错。
  • defaultValue : 当没有指定请求参数时,则使用指定的默认值赋值 默认值
http://localhost:8088/spring_mvc/user/quick12?name=222

@RequestMapping("/quick12")
@ResponseBody
public  void save12(@RequestParam(value = "name",required = false,defaultValue = "guang") String username)  {
System.out.println(username);
}
4.1.5 获得Restful 风格的参数

HTTP协议里的四种操作方式:

  • GET : 用于获取资源 例:/user/1 GET : 得到id =1 的user
  • POST : 用于新建资源 例:/user POST : 新增user
  • PUT : 用于更新资源 例:/user/1 PUT :更新id=1的user
  • DELETE : 用于删除资源 例:/user/1 GET : 得到id =1 的user
http://localhost:8088/spring_mvc/user/quick13/songdan

@RequestMapping("/quick13/{username}")
@ResponseBody
public  void save13(@PathVariable(value = "username") String username)  {
System.out.println(username);
}
//输出:
 songdan
4.1.6 自定义类型转换器
  1. 定义转换器类实现Converter接口

    @Component
    public class DataConverter implements Converter<String, Date> {
        @Override
        public Date convert(String dateStr) {
            SimpleDateFormat format =new SimpleDateFormat("yyyy-MM-dd");
            Date parse = null;
            try {
                parse = format.parse(dateStr);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return parse;
        }
    }
    
  2. 在配置文件中声明转换器

    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <bean class="cn.xxxx.converter.DataConverter"></bean>
            </list>
        </property>
    </bean>
    
  3. 在中引用转换器

<mvc:annotation-driven conversion-service="conversionService"/>
4.2 文件上传
4.2.1 文件上传客户端的三要素
  • 表单项type = “file”
  • 表单的提交方式是post
  • 表单的enctype属性是多部份表单形成,及enctype =“multipart/form-data”
4.2.2 单文件上传步骤
  1. 导入fileupload和io坐标

    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.3</version>
    </dependency>
    
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.8.0</version>
    </dependency>
    
  2. 配置文件上传解析器

    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="UTF-8"/>
        <property name="maxUploadSize" value="500000"/>
    </bean>
    
  3. 编写文件上传代码

    多文件上传

    3.1)、编写form表单代码

    1. 第一种不同上传的文件name也不一样
    <form method="post" action="<%=request.getContextPath()%>/user/quick15" enctype="multipart/form-data">
        名称<input type="text" name="username"/><br>
        文件<input type="file" name="upfile"/><br>
        文件<input type="file" name="upfile2"/><br>
        <input type="submit" value="提交"><br>
    </form>
    
    2. 第二种不同上传的文件name属性一样
    <form method="post" action="<%=request.getContextPath()%>/user/quick16" enctype="multipart/form-data">
        名称<input type="text" name="username"/><br>
        文件<input type="file" name="upfile"/><br>
        文件<input type="file" name="upfile"/><br>
        <input type="submit" value="提交"><br>
    </form>
    

​ 3.2、选择文件

​ 3.3、编写代码转移文件到新地址

1. 第一种接收的name属性不一样
    @RequestMapping("/quick15")
    @ResponseBody
    public  void save15(String username,MultipartFile upfile,MultipartFile upfile2) throws IOException {
    System.out.println(username);
    String originalFilename = upfile.getOriginalFilename();
    upfile.transferTo(new File("F:\\newfile\\"+originalFilename));
    String originalFilename2 = upfile2.getOriginalFilename();
    upfile2.transferTo(new File("F:\\newfile\\"+originalFilename2));
}
transferTo("新地址提前创建"+获取到的要上传的文件)2. 第二种接受的name属性一样
    @RequestMapping("/quick16")
    @ResponseBody                      //多个name属性一样时,使用数组接收   
    public  void save16(String username,MultipartFile[] upfile) throws IOException {
    System.out.println(username);
    for (MultipartFile multipartFile : upfile) {
        String originalFilename = multipartFile.getOriginalFilename();
        multipartFile.transferTo(new File("F:\\newfile\\"+originalFilename));
    }
}

JdbcTemplate

1. Spring JdbcTemplate 基本使用

1.1开发步骤:
  1. 导入spring-jdbc和spring-tx坐标

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
    
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
    
  2. 创建数据库表和实体

  3. 创建JdbcTemplate对象

  4. 执行数据库操作

    //新增
    @Test
    public void test1() throws PropertyVetoException {
        //创建数据源
        ComboPooledDataSource dataSource =new ComboPooledDataSource();
        dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/ssm");
        dataSource.setUser("root");
        dataSource.setPassword("lyg146837");
        JdbcTemplate jdbcTemplate =new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        //执行操作
        int tom = jdbcTemplate.update("insert Account values(?,?)", "tom", 5000.22);
        System.out.println(tom);
    }
    
1.2 Spring产生JdbcTemplate对象

第一步:(配置数据源bean和jdbc模板bean)

<!--加载jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--数据源对象-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driver}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
<!--jdbc模板对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
</bean>

第二步:(加载ApplicationContext.xml文件)

//删除
@Test
public void test2(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate bean = app.getBean(JdbcTemplate.class);
bean.update("delete  from  Account where name=?","tom");
}
1.3 使用SpringTest测试JdbcTemplate模板

1.3.1 执行更新操作:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JdbcTemplateCRUDTest {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Test
    public void test1(){
        int tom = jdbcTemplate.update("update Account set money=? where name=?", 8000, "tom");
        System.out.println(tom);
    }
}

1.3.2 执行查询操作

@Test
public void queryAll(){
    //查询全部使用query("sql语句",new BeanPropertyRowMapper<对应的实体类>(类的字节码))
    List<Account> query = jdbcTemplate.query("select * from Account", new BeanPropertyRowMapper<Account>(Account.class));
    System.out.println(query);
}


  //查询单个对象queryForObject("sql语句",new BeanPropertyRowMapper<对应的实体类>(类的字节码),"sql参数")
Account tom = jdbcTemplate.queryForObject("select * from Account where  name =?", new BeanPropertyRowMapper<Account>(Account.class), "tom");
System.out.println(tom);

1.3.4 查询记录数

@Test
public void queryCount() {
    //返回值是一个普通类型,Mapper参数也是简单类型
    Long count = jdbcTemplate.queryForObject("select count(*) from Account", Long.class);
    System.out.println(count);
}

数据校验:

//实体类:

@NotNull(message = "用户id不能为空")
private Integer id;
@NotNull
@Length(min = 2, max = 8, message = "用户名不能少于2位大于8位")
private String name;
@Email(regexp = "[a-zA-Z0-9]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9]", message = "邮箱格式不正确")
private String email;

Controller:

@Controller
public class UserController {
    @RequestMapping("/validate")
    public String validate(@Valid User user, BindingResult result) {
        // 如果有异常信息
        if (result.hasErrors()) {
            // 获取异常信息对象
            List<ObjectError> errors = result.getAllErrors();
            // 将异常信息输出
            for (ObjectError error : errors) {
                System.out.println(error.getDefaultMessage());
            }
        }
        return "index";
    }
    @RequestMapping(value = "/addUser")
    public String add() {
        return "addUser";
    }
}

拦截器

1. 方法及介绍
方法名介绍
preHandle()目标方法请求处理执行之前调用返回布尔值,如果返回true,则继续执行,false则不再执行,多个HandInterceptor的情况下,并且返回true 会先执行下一个Interceptor的preHandle()方法;
postHandle()目标方法执行之后,视图返回之前执行
afterCompletion()所有流程执行完毕之后执行
2. 使用步骤
  1. 创建拦截器类实现HandInterceptor接口

    测试要拦截的方法:

    @Controller
    public class MvcControl {
        @RequestMapping("/test")
        public ModelAndView show() {
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("hello", "3爱香香");
            modelAndView.setViewName("index");
            return modelAndView;
        }
    }
    
    public class MyIntercepter implements HandlerInterceptor {
        //目标方法执行之前执行
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            //获取请求参数
            String param = request.getParameter("param");
            if("yes".equals(param)){
                return true;//如为true,可放行,
            }else {       request.getRequestDispatcher("/error.jsp").forward(request,response);
                return false;//如为false,目标方法不执行,postHandle(),afterCompletion()也不执行
            }
    
        }
    
        //目标方法执行之后,视图返回之前执行
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
             modelAndView.addObject("hello","3不爱香香");  //修改modelAndView的值
            System.out.println("方法执行之后,视图返回之前");
        }
    
        //所有流程执行完毕之后执行
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("所有流程执行完毕之后执行");
        }
    }
    
  2. 在spring-mvc配置文件中配置interceptor拦截器

    <!--    配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--path:表示对哪个方法进行拦截-->
            <mvc:mapping path="/**"/>
            <!--对哪些资源放行-->
            <mvc:exclude-mapping path="/user/login"/>
            <bean class="cn.xxxx.interceptor.MyIntercepter"/>
        </mvc:interceptor>
    </mvc:interceptors>
    
  3. 实现拦截效果

SpringMvc 异常处理
  1. 简单映射异常

    <!--创建异常处理器-->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <!--默认异常-->
        <!--        <property name="defaultErrorView" value="error"/>-->
        <!--手动配置捕捉的异常-->
        <property name="exceptionMappings">
            <map>
                <entry key="java.lang.ClassCastException" value="error1"/>
                <entry key="java.lang.ClassCastException" value="error2"/>
            </map>
        </property>
    
    </bean>
    
  2. 自定义异常类处理异常

    步骤:

    1. 创建异常处理器类实现HandlerExceptionResolver
    2. 配置异常处理器
    3. 编写异常页面
    4. 测试异常跳转

1. 框架概述:

a)、三层架构

  1. 页面层: 和用户打交道,接收请求的参数,显示处理结果: jsp html 、servlet
  2. 业务逻辑层: 接收了界面层传递的数据,计算逻辑,调用数据库。获取数据
  3. 数据访问层: 访问数据库 执行对数据的查询、修改删除等操作;

所对应的包 及其框架:

界面层: controller 包(servlet) springmvc (框架)

业务逻辑层: service 包(XXXXservice) 类 spring (框架)

数据访问层 :dao 包 (XXXXXDao类) mybatis (框架)

交互:

用户使用界面层<–>业务逻辑层<–>数据访问层<–>数据库(mysql);

b)、 框架

框架是一个模板; 规定了一些条款,内容,加入自己的东西;

MyBatis SQL Mapper Framework for Java (sql映射框架)

  1. sql mapper :sql 映射

可以把数据库表中的数据,映射为一个java对象一行数据可以被看作一个java对象,操作这个对象 相当于操作表中的数据。

  1. Data Access Objects(DAOs) : 对数据库执行增、删、改、查;

**mybatis 提供的功能: **

创建Connection,Statement、ResultSet的能力,

以及执行sql语句,循环sql 把sql的结果转为java对象,List集合,

还有关闭Connection,Statement、ResultSet资源的能力 ;

开发人员只需提供:sql语句 ;

2. MyBatis 框架快捷入门

a)、实现步骤 例子:

  1. 新建student 表
  2. 加入maven的mybatis 坐标,和mysql的驱动坐标;
  3. 创建实体类,Student 保存表中的一行数据
  4. 创建持久dao接口 定义操作数据库的方法;
  5. 创建一个mybatis使用的配置文件

创建在和dao层接口同一目录下; 名字最好和接口保持一致

叫做sql映射文件 :写sql语句 。一般一个表对应一个sql 映射 ,是xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
<!--约束文件检查标签、属性必须符合规则-->
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--mapper当前文件的跟标签 必须的,namespace 是指命名空间 一般写接口的全限定名称-->
<mapper namespace="org.mybatis.example.BlogMapper">
    <!--id 是select语句的唯一标识  写语句对应的方法名-->
    <!--resultType 是sql语句执行后得到的ResultSet  遍历他得到的java类型    值一般写类型的全限定名称-->
    
    //查询方法
    <select id="selectBlog" resultType="Blog">
        select * from Blog where id = #{id}
    </select>
    
    //新增方法
     <insert id="insertStudent">
     insert student values(#{字段名1},#{字段名2},#{字段名3},#{字段名4});
    </insert>
</mapper>
  1. 创建mybatis 的主配置文件 一个项目只有一个主配置文件

主配置文件包含了数据库连接信息 和sql映射文件的位置

<?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>
    
    <!--设置myBatis日志输出到控制台-->
<settings>
    <setting name="logImpl" value="StDOUT_LOGGING"/>
</settings>
    
    <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>
    <mappers>
        <!-- mapper编译后的路径-->
        <mapper resource="cn/guang/dao/StudentDao.xml"/>
    </mappers>
</configuration>

加入插件 :

<resources>
    <resource>
        <directory>src/main/resources/${env}</directory>
    </resource>
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.xml</include>
            <include>**/*.properties</include>
            <include>**/*.tld</include>
        </includes>
        <filtering>false</filtering>
    </resource>
</resources>
  1. 创建使用mybatis类

通过mybatis访问数据库 ;

import org.apache.ibatis.io.Resources;
//获取主文件
String config = "mybatis.xml";
//读取文件
// InputStream ins = Resources.getResourceAsStream(config);
InputStream ins = myAPP.class.getClassLoader().getResourceAsStream(config);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(ins);
//**重要
SqlSession sqlSession = factory.openSession();
//重要指定要执行的sql语句的标识 namespace +"."+ id
String sqlIdsls = "cn.guang.dao.StudentDao" + "." + "selectAll";
String sqlIdins = "cn.guang.dao.StudentDao" + "." + "insertStudent";

List<Student> studentList = sqlSession.selectList(sqlIdsls);
for (Student stu : studentList) {
    System.out.println(stu);
}
//执行inert的结果
int insert = sqlSession.insert(sqlIdins, student);
//myBatyis 默认不提交事务  执行insert delete update 之后需要手动提交事务
sqlSession.commit();


sqlSession.close();

**b)、 工具类使用 **

创建 MyBatis 工具类:

static SqlSessionFactory sqlSessionFactory = null;

static {
    String config = "mybatis.xml";
    try {
        InputStream in = Resources.getResourceAsStream(config);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public static SqlSession getSqlSession() {
    SqlSession sqlSession = null;
    if (sqlSessionFactory != null) {
        sqlSession = sqlSessionFactory.openSession();
    }
    return sqlSession;
}

创建类获取方式:

public static void main(String[] args) {
    //**重要
    SqlSession sqlSession = MyBatisUtil.getSqlSession();
    //重要指定要执行的sql语句的标识 namespace +"."+ id
    String sqlId = "cn.guang.dao.StudentDao.selectAll";
    List<Student> studentList = sqlSession.selectList(sqlId);
    for (Student stu : studentList) {
        System.out.println(stu);
    }
    sqlSession.close();
}

c)、创建mybatis 的mapper和主配置文件模板

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vm0Chbgt-1652404831829)(C:\Users\李桑\AppData\Roaming\Typora\typora-user-images\image-20211107222423393.png)]

3. MyBatis 框架Dao代理 ※

使用动态代理的要求:

  1. mapper 文件的namespace 一定要是dao接口的全限定名称
  2. mapper 文件中的标签id 是dao 接口的方法名称

a)、mybatis 的动态代理

根据你提供的接口,创键出实现类,并创建这个类的对象搜索,完成qlSession 调用方法 并访问数据库;

使用mybatis的动态代理机制 ,使用sqlSession.getmapper( dao接口) 获取dao接口的实现类对象;

//不用创建到接口impl实现类 
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentDao mapper = sqlSession.getMapper(StudentDao.class);
List<Student> studentList = mapper.selectStudents();
for (Student stu : studentList) {
    System.out.println(stu);
}

*b)、理解参数

parameterType: 表示参数的类型

<select id="selectById" parameterType="java.lang.Integer"   <!--指定mybatis接受的参数类型是Integer类型-->
        resultType="cn.guang.entity.Student">
    select *
    from student
    where id = #{id}
</select>

类型别名: (不区分大小写) parameterType= “可直接写别名”

别名映射的类型
_bytebyte
_longlong
_shortshort
_intint
_integerint
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dateDate
decimalBigDecimal
bigdecimalBigDecimal
objectObject
mapMap
hashmapHashMap
listList
arraylistArrayList
collectionCollection
iteratorIterator

c)、dao接口有一个简单类型参数

dao接口中方法的参数只有一个简单类型,(java基本类型和String ) 占位符 #{任意字符} 和方法的参数名无关;

<select id="selecyByemail" parameterType="string" 
        resultType="cn.guang.entity.Student">
    select *
    from student
    where email = #{email}  <!--任意字符-->
</select>

d)、dao接口有多个简单类型参数:

@Param 命名参数

Student selecyBynameAndage(@Param("myName") String name,@Param("myAge") Integer age);

mapper 配置文件:

<select id="selecyBynameAndage" resultType="cn.guang.entity.Student">
    select *
    from student
    where name = #{myName}
      and age = #{myAge}
</select>

d 2 )、dao接口多个简单参数,使用位置:

语法格式 #{arg0}, #{arg1}

select * from student where name =#{org0} and age =#{org1};

e)、dao接口使用对象作为参数:

#{} 特点 :

  1. 使用的PrepareStatement 对象执行sql 语句 效率更高;

  2. 使用的PrepareStatement 避免sql 注入 更安全;

  3. #{}常常作为列值使用,位于等号的右侧,#{}的值和数据类型有关;

e.2 、 $占位符

语法: ${字符}

<select id="selectByName" parameterType="java.lang.Integer"
        resultType="cn.guang.entity.Student">
    select *
    from student
    where id = ${Myname}
    
    ${} 表示将sql 语句内容 和${} 的内容 使用“+”连接在一起
    String sql ="select * from student where name ="+"name"
</select>
List<Student> selecyByName(@Param("Myname") String name);   //Dao接口方法

${}的特点:

  1. 使用Statement对象, 效率低 ;
  2. 它的值是 连接字符串的方式 ,有sql注入的风险;
  3. 数据是原样使用的 不区分数据类型;
  4. 通常在确保数据安全的情况下使用;
public void test05() {
    SqlSession sqlSession = MyBatisUtil.getSqlSession();
    StudentDao mapper = sqlSession.getMapper(StudentDao.class);
    //**数据是原样使用的  不区分数据类型;
    List<Student> students = mapper.selecyByName("'李四'");  
    for (Student stu : students) {
        System.out.println("学生信息" + stu);
    }
    sqlSession.close();
}

使用$ 占位符 表示表名或者列名 :

<select id="selectOrderById" resultType="cn.guang.entity.Student">
    select *
    from student
    where name =#{Myname}       //#{ } 代表列值  
    order  by  ${stuid} desc    //使用${ }占位符可以代表列名 
</select>
3.2)、封装myBatis 输出结果

f1)、 resultType

查询结果 : 同名的列 赋给同名的属性

resultType属性: 在select 标签中 作为它的属性出现

它的表示结果分为两种类型 1.Java全限定名称 2. 使用别名

自定义别名:

​ 一) 、 resultType 返回对象

  1. 声明别名: 在mybatis的主配置文件中使用typeAliase设置

    <typeAliases>
        第一种
        <!--type属性 填写Java的全限定名称,aliases 属性 “别名”-->
        <typeAlias type="cn.guang.entity.Student" alias="stu"/>
        第二种:
        <!-- 使用package 语句 设置一个包名  mybatis 将其包下的类名变成别名 (不区分大小写)-->
        <package name="cn.guang.entity"/>
    </typeAliases
    
  2. 使用别名 : 在mapper 文件中 设置 resultType = “别名”

    第一种
    select *
    from student
    where name = ${Myname}
</select>

二)、resultType 返回简单数据类型 一个值

dao接口:

long selectCount();

mapper 文件;

<select id="selectCount" parameterType="java.lang.Long" resultType="longs">
    select count(*) from student
</select>

f1)、 resultMap :

  1. 先定义resultMap 标签 ,指定指定列名和属性名称的关系;
  2. 在select标签使用resultMap 属性 指定以上定义的Resultmap的id值;
<resultMap id="proMap" type="cn.guang.entity.ProvinceCity">
    <!--        定义列名和属性名对应 主键列使用 id 标签  其他列使用result 标签-->
    <id column="pid" property="nid"/>
    <!--        column 对应 select标签 里的字段名 ,  property 对应实际数据库的字段名-->
    <result column="pName" property="nName"/>
</resultMap>

<!-- 使用resultmap属性 指定映射关系的id-->      resultMap  和resultType二选一,不能同时使用
<select id="selectAll" resultMap="proMap">
    select pid, pName
    from pro
</select>

f2)、列名和Java对象的属性名不一样:

  1. 使用resultMap指定列名和对象属性的关系;

  2. 使用 resultType :使用列“别名” 让列别名和属性名一致;

    <select id="selectCustStu2" resultType="cn.guang.entity.CustStudent">
        select id as cid, name as cName, email, age
        from student
    </select>
    

f3)、like 模糊查询:

  1. 第一种方式:
public List<CustStudent> selectCustStuByName(@Param("MyName") String sName);

mapper :

<select id="selectCustStuByName" resultType="cn.guang.entity.CustStudent">
    select * from student where name like #{MyName} //传入的值
</select>

执行 模糊查询:

public void selectCustByname() {
    SqlSession sqlSession = MyBatisUtil.getSqlSession();
    CustStudentDao mapper = sqlSession.getMapper(CustStudentDao.class);
    String name = "%李%";   //传入的值
    List<CustStudent> custStudents = mapper.selectCustStuByName(name);
    custStudents.forEach(stu -> System.out.println(stu));
    sqlSession.close();
}

sql  : select * from student  where name like '%李%'

2.第二种方式:

语法: where name like “%“空格#{MyName} 空格”%”

<select id="selectCustStuByName" resultType="cn.guang.entity.CustStudent">
    select * from student where name like "%" #{MyName} "%" //传入的值
</select>

4. MyBatis 框架动态SQL ※

动态SQL的使用场景:

多条件查询 使用动态sql 和实体

4.1 if 标签

语法:

<if test ="boolean判断结果">
    sql 代码
</if>

在mapper文件中
<select id="selectStudent" resultType="cn.guang.entity.Student">
    select * from student 
    <if test="条件">
        sql语句
    </if>
    <if test="条件">
        sql语句
    </if>
</select>

示例: dao接口:

List<Student> selectif( Student student);

mapper 文件:

<select id="selectif" resultType="stu">
    select * from student
    where id =-1  //条件 避免当没满足第一个条件,直接走到第二个条件时 多 or 或者 and 运算符
    <if test="name !=null and name != ''">
        name =#{name}
    </if>
    <if test="age>0">   
        <!--多个if条件需要 按需求使用 “ or ” 或  “  and ” 连接-->
        and age =#{age}
    </if>
</select>

test if :

// 省略从sqlSession 获取
Student student = new Student();
student.setName("李四");
student.setAge(22);
List<Student> selectif = mapper.selectif(student);
//遍历

sql:   select * from student where name =? and age =? 

小于号 ” < “ 在mapper.xml文件中时不能出现的; 所以需要使用实体符号表:

<小于& lt;
>大于& gt;
>=大于等于& gt;=
<=小于等于& lt;=
4.2 where 标签

使用where时。里面是一个或多个if标签,如果其中一个条件为true时,where标签 会自动转成WHERE 关键字,附加在SQL语句之后,如果没有一个条件达成,则会忽略where标签 里的 if;

where 标签会把和它 紧邻的 “ or ” 或者 “ and ” 删掉

<select id="selectwhere" resultType="stu">
    select * from student
    <where>
        <if test="name !=null and name != ''">
            name =#{name}
        </if>
        <if test="age>0">
            and age  &lt;#{age}
        </if>
    </where>
</select>
4.3 foreach 循环标签

第一种: 循环简单的LIst;

语法:

select * from student
<foreach collection="集合类型" open="开始的字符"  close="结束的字符"  item="集合中的成员" separator="成员之间的分隔符">
    #{item 的值}
</foreach>

collection:表示循环的对象的类型,数组还是List集合,数组 =“array ”  集合 =“list”
item= 集合中的成员 (变量名)

示例:

<select id="selectforeach" resultType="stu">
    select * from student
    <!--判断list是否为null 并且 size是否大于零-->
    <if test="list!=null and list.size>0">   
        where id in
        <foreach collection="list" open="(" close=")"  item="myid"  separator=",">
            #{myid}
        </foreach>
    </if>
</select>
//输出foreach
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentDao mapper = sqlSession.getMapper(StudentDao.class);
List<Integer> list = new ArrayList<>();
list.add(1001);
list.add(1002);
list.add(1003);
List<Student> selectforeachlist = mapper.selectforeach(list);
selectforeachlist.forEach(stus -> System.out.println(stus));
sqlSession.close();


sql :  ==>   select * from student where id in ( ? , ? , ? ) 
 Parameters: 1001(Integer), 1002(Integer), 1003(Integer)

第二种: 循环List;

  <foreach collection="list" open="(" close=")"  item="stu"  separator=",">
            #{stu.id}
  </foreach>
List<Student> lists =new ArrayList<>();
Student stu1 =new Student();
stu1.setId(1001);

Student stu2 =new Student();
stu1.setId(1002);
lists.add(stu1);
lists.add(stu2);
List<Student> selectforeachlist = mapper.selectforeach(list);

sql :  select * from student where id in ( ? , ?  ) 
4.4 代码片段 :

sql 标签:

定义一个代码片段,可以在mapper 文件中 的select 、 insert 等地方 使用include;

<!--使用sql代码片段标签   定义定义一条sql语句-->
<sql id="sqlStr">
    select *
    from student
</sql>
<!--使用sql代码片段标签   定义两个 字段名-->
<sql id="columns">
    id,name
</sql>


<select id="selectif" resultType="stu">
    select <include refid="columns"/> from student     == select id,name from Student
    <include refid="sqlStr"/>                          ==   select * from Student
    where
    <if test="name !=null and name != ''">
        name =#{name}
    </if>
    <if test="age>0">
        and age =#{age}
    </if>

</select>

5. MyBatis 配置文件

mybatis 配置文件分为两类: 主配置文件和mapper文件 ;

**1. 标签: **

settings 是mybatis的全局设置,一般写在上面,一般使用默认值就可以了;

2. typeAliase 别名:

<typeAliases>
    <!--type属性 填写Java的全限定名称,aliases 属性 “别名”-->

    <!-- 第一种 :-->
    <!--        <typeAlias type="java.lang.Long" alias="longs"/>-->
    <typeAlias type="cn.guang.entity.Student" alias="stu"/>
    <!--        <typeAlias type="cn.guang.entity.CustStudent" alias="cust"/>-->

    <!-- 第二种 :-->
    <!--        &lt;!&ndash; 使用package 语句 设置一个包名  mybatis 认为它的别名是其包下的类名 (不区分大小写)&ndash;&gt;-->

    <package name="cn.guang.entity"/>
</typeAliases>

3. 配置环境 :

environments: 环境标签,在一个environments标签中 可以配置多个environment,default的值必须是其中一个数据源的Id;
environment: 表示一个数据库的链接信息;
         属性: id自定义环境标识,唯一值
transactionManager: 事务管理器
dataSource : 数据源 ,创建的Connection对象,连接数据库;
    属性:type 数据源的类型,
    属性值: 1)、POOLED,mabatis会在内存中创建 PooledDataSource类,管理连接对象,使用连接池
2)、 UNPOOLED 不使用连接池
3)、 JNDI
<environments default="myStudent">
    <environment id="myStudent">
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
            <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
            <property name="url"
                      value="jdbc:mysql://127.0.0.1:3306/ssm?useUnicode=true&amp;characterEncoding=UTF8&amp;useSSL=false&amp;serverTimezone=UTC"/>
            <property name="username" value="root"/>
            <property name="password" value="lyg146837"/>
        </dataSource>
    </environment>
</environments>
4、使用数据库属性配置文件

需要把数据库的配置信息放到一个单独的文件中,这个文件的后缀是.properties,在这个文件中使用自定义的key =value 的格式 表示数据;

步骤:

  1. 在resources目录中,创建xxxx.properties;

  2. 在文件中使用key=value的格式存储数据;

    例如: jdbc.driver= com.mysql.cj.jdbc.Driver

jdbc.driver:com.mysql.cj.jdbc.Driver
jdbc.url:jdbc:mysql://127.0.0.1:3306/ssm?useUnicode=true&characterEncoding=UTF8&useSSL=false&serverTimezone=UTC
jdbc.username:root
jdbc.password:lyg146837
  1. 在mybatis 主配置文件中,引用jdbc.properties
<!--引入jdbc配志文件-->
<properties resource="jdbc.properties"/>
  1. 在property 中使用 ${key } 获取
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
5. mapper标签:

mapper 文件的配置方式:

resource: mapper的路径
<mappers>
    <mapper resource="cn/guang/dao/StudentDao.xml"/>
</mappers>

第二种:

<!--        mapper name =文件的所在包名
作用: 一次性加载该包下的所有mapper文件
使用要求: 1. mapper 文件必须和dao接口在同一目录下,
         2. mapper 文件必须和dao接口名字保持一致;
-->
<package name="cn.guang.dao"/>

6.扩展

PageHelper 分页插件:
PageHelper 对象

**2. 基于PageHelper分页: **

(1)maven 坐标:

<!--pagehelper 分页依赖-->
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.2.0</version>
</dependency>

(2) 在environments之前 添加:

<plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor"/>
</plugins>

查询语句之前调用 PageHelper.startPage(页码,每页的大小) 静态方法

SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentDao mapper = sqlSession.getMapper(StudentDao.class);
PageHelper.startPage(2,3);   //第二页 显示三条数据
List<Student> students = mapper.selectPageHelper();
students.forEach(stu -> System.out.println(stu));
sqlSession.close();


sql:   select * from student order by id LIMIT ?, ? 
==> Parameters: 3(Long), 3(Integer)
<==    Columns: id, name, email, age
<==        Row: 1004,, songdan@qq.com, 20
<==        Row: 1005,, songdan@qq.com, 20
<==        Row: 1008, 王五, wangwu@qq.com, 25
<==      Total: 3

SSM 整合

所需maven依赖
<dependencies>
  <!--spring相关-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.5.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.7</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.0.5.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>5.0.5.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.0.5.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.0.5.RELEASE</version>
  </dependency>

  <!--servlet和jsp-->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
  </dependency>
  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.0</version>
  </dependency>

  <!--mybatis相关-->
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.5</version>
  </dependency>
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.1</version>
  </dependency>
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.25</version>
  </dependency>
  <dependency>
    <groupId>c3p0</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.1.2</version>
  </dependency>

  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
  </dependency>
  <dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
  </dependency>
</dependencies>

<build>
  <resources>
    <resource>
      <directory>src/main/java</directory>
      <includes>
        <include>**/*.xml</include>
        <include>**/*.properties</include>
        <include>**/*.tld</include>
      </includes>
      <filtering>false</filtering>
    </resource>
    <resource>
      <directory>src/main/resources</directory>
      <includes>
        <include>**/*.xml</include>
        <include>**/*.properties</include>
        <include>**/*.tld</include>
      </includes>
      <filtering>false</filtering>
    </resource>



  </resources>
applicationContext配置文件
<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

    <!--组件扫描 扫描service和mapper-->
    <context:component-scan base-package="cn.xxxx">
        <!--排除controller的扫描-->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter>
    </context:component-scan>

    <!--加载propeties文件-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

    <!--配置数据源信息-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

    <!--配置sessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <!--加载mybatis核心文件-->
        <property name="configLocation" value="classpath:sqlMapConfig-spring.xml"></property>
    </bean>

    <!--扫描mapper所在的包 为mapper创建实现类-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.xxxx.dao"></property>
    </bean>


    <!--声明式事务控制-->
    <!--平台事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--配置事务增强-->
    <tx:advice id="txAdvice">
        <tx:attributes>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>

    <!--事务的aop织入-->
    <aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.service.impl.*.*(..))"></aop:advisor>
    </aop:config>

</beans>
spring-mvc
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

    <!--组件扫描  主要扫描controller-->
    <context:component-scan base-package="cn.xxxx.controller"></context:component-scan>
    <!--配置mvc注解驱动-->
    <mvc:annotation-driven></mvc:annotation-driven>
    <!--内部资源视图解析器-->
    <bean id="resourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
    <!--开发静态资源访问权限-->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>


</beans>
mybatis-config
<?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>

    <!--加载properties文件-->
    <properties resource="jdbc.properties"></properties>

    <!--定义别名-->
    <typeAliases>
        <!--<typeAlias type="com.itheima.domain.Account" alias="account"></typeAlias>-->
        <package name="cn.xxxx.domain"></package>
    </typeAliases>

    <!--环境-->
    <environments default="developement">
        <environment id="developement">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"></property>
                <property name="url" value="${jdbc.url}"></property>
                <property name="username" value="${jdbc.username}"></property>
                <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>
    </environments>

    <!--加载映射-->
    <mappers>
        <mapper resource="mapper/AccountMapper.xml"></mapper>
<!--        <package name="cn.xxxx.mapper"></package>-->
    </mappers>


</configuration>
mybatis-spring
<?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>

    <!--设置myBatis日志输出到控制台-->
    <settings>
        <setting name="logImpl" value="StDOUT_LOGGING"/>
    </settings>

    <!--定义别名-->
    <typeAliases>
        <!--<typeAlias type="com.itheima.domain.Account" alias="account"></typeAlias>-->
        <package name="cn.xxxx.domain"></package>
    </typeAliases>


</configuration>
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">


    <!--spring 监听器-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!--springmvc的前端控制器-->
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--乱码过滤器-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>
controller 层
package cn.xxxx.controller;/**
 * @author:guang
 * @Data:2022/2/28
 * @apiNote
 */

import cn.xxxx.domain.Account;
import cn.xxxx.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;

/**
 * 描述
 *
 * @version 1.0
 * @Title:
 * @author: liyongguang
 * @Description: asd
 * @date 2022/02/28 10:38:22
 */

@Controller
@RequestMapping("/account")
public class AccountController {
    @Autowired
    private AccountService accountService;

    @RequestMapping(value = "/save", produces = "text/html;charset=UTF-8")
    @ResponseBody
    public String save(Account account) {
        accountService.save(account);
        return "保存成功";
    }

    //查询
    @RequestMapping("/findAll")
    public ModelAndView findAll() {
        List<Account> accountList = accountService.findAll();
        ModelAndView modelAndView = new ModelAndView("index");
        modelAndView.addObject("accountList", accountList);
        modelAndView.setViewName("accountList");
        return modelAndView;
    }
}
service层
@Service("accountService")
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountMapper accountMapper;

    @Override
    public void save(Account account) {
        accountMapper.save(account);
    }

    @Override
    public List<Account> findAll() {
        return accountMapper.findAll();
    }
}

spring 整合mybatis的三种方式:

第一种:

<!--扫描mapper和service-->
<context:component-scan base-package="com.t2081.ch03">
    <!--对controller放行 让spring-mvc扫描-->
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--加载proper配置文件-->
<context:property-placeholder location="classpath:/jdbc.properties"/>
<!--配置数据源-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driver}"></property>
    <property name="jdbcUrl" value="${jdbc.url}"></property>
    <property name="user" value="${jdbc.username}"></property>
    <property name="password" value="${jdbc.password}"></property>
</bean>

<!--创建sqlseciton工厂-->
<bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!--指定数据源-->
    <property name="dataSource" ref="dataSource"></property>
    <!--指定mybatis文件路径-->
    <property name="configLocation" value="classpath:mybatis_spring.xml"/>
    <!-- 配置别名扫描 -->
    <property name="typeAliasesPackage" value="com.t2081.ch03.entity"/>
    <!--加载mapper文件 -->
    <property name="mapperLocations" value="classpath:mapper/*Mapper.xml"/>
</bean>
<!--    第一种方式-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    <!--只能通过构造器注入sqlSessionFactory,因为没有set方法-->
    <constructor-arg index="0" ref="sessionFactory"/>
</bean>

创建实现类:(实现dao接口)

@Repository("smbmsBillDaoMapper")
public class SmbmsBillDaoMapperImpl implements SmbmsBillDaoMapper {
    //私有化sqlSessionTemplate
    @Autowired
    private SqlSessionTemplate sqlSession;


    @Override
    public List<SmbmsBill> selectAllBill() {
        return sqlSession.getMapper(SmbmsBillDaoMapper.class).selectAllBill();
    }

    @Override
    public List<SmbmsBill> selctByWhen(HashMap<String, Object> whens) {
        return sqlSession.getMapper(SmbmsBillDaoMapper.class).selctByWhen(whens);
    }

    @Override
    public SmbmsBill selectBillById(Integer id) {
        return sqlSession.getMapper(SmbmsBillDaoMapper.class).selectBillById(id);
    }

    @Override
    public int updataBill(SmbmsBill smbmsBill) {
        return sqlSession.getMapper(SmbmsBillDaoMapper.class).updataBill(smbmsBill);
    }

    @Override
    public int delectbath(List<Integer> ids) {
        return sqlSession.getMapper(SmbmsBillDaoMapper.class).delectbath(ids);
    }
}

service层调用:

//@Autowired
@Resource(name = "smbmsBillDaoMapper")
private SmbmsBillDaoMapperImpl smbmsBillDaoMapper;

public void setSmbmsBillDaoMapper(SmbmsBillDaoMapperImpl smbmsBillDaoMapper) {
    this.smbmsBillDaoMapper = smbmsBillDaoMapper;
}

SpringBoot2

1.开发步骤:
  1. 导入依赖
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.4</version>
</parent>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  1. 创建主程序类(固定写法)
@SpringBootApplication  
public class FirstSpringboot {
    public static void main(String[] args) {
        SpringApplication.run(FirstSpringboot.class, args);
    }
}
  1. 业务层
@RestController   //requetbody+Controller
public class MyControl {
    @RequestMapping("/hello")
    public String home() {
        return "Hello World!";
    }
}
  1. 测试

直接运行main方法

  1. 简化配置

优先级:application.properties >

  1. 创建application.properties 核心配置文件所有配置都可修改
server.port=8089     //更改tomcat端口为8089
server.servlet.context-path=/springboot    //设置上下文根
  1. 创建appliation.yml核心配置文件
##格式:冒号:后面默认有一个空格 不能删除 属性前面默认加一个tab制表符缩进
server:
  port: 8081
  servlet:
    context-path: 
  1. 简化部署
<plugins>
  <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>2.2.6.RELEASE</version>
  </plugin>
</plugins>
1.2.依赖管理
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.4</version>
</parent>
##他的父项目
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.6.4</version>
</parent>
如果要修改版本:
1.先查看spring-boot-dependencies规定的版本
2.在当前项目重写
<properties>
<mysql.version>8.0.25</mysql.version>
</properties>
支持的场景
https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.build-systems.starters
1.3 多环境下核心配置文件的使用

固定格式:application- 开头 .properties结尾

  1. 开发环境 application-dev.properties & application-dev.yml
  2. 测试环境 application-test.properties & application-test.yml
  3. 准生产环境 application-ready.properties & application-ready.yml
  4. 生产环境 application-prop.properties & application-poop.yml
#properties主配置文件
#激活的配置文件
spring.profiles.active=dev
#yml主配置文件
spring:
  profiles:
    active: dev
1.4 获取自定义配置
//在application 文件中自定义配置
school.name=guangge
//获取方式一:
     @Value("${school.name}")
    private String schoolName;

    @RequestMapping("/say")
    public String say() {
        return schoolName;
    }
//获取方式二:
//创建配置类 
@Component    //将该类交给spring容器
@ConfigurationProperties(prefix = "school")   //需指定前缀
public class School {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
//使用 @Autowired获取
@Autowired
private School school;

@RequestMapping("/printschool")
public String print() {
    return "school.name" + school.getName();
}
2.自动配置
  • 自动配好tomcat
  • 自动配好spring-mvc

如果目标和主程序不在同一包或者主程序的子包,使用@SpringBootApplication(scanBasePackages = “cn.xxxx”)指定扫描;

@SpringBootApplication=
//等同于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan

所有的自动配置都在:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-autoconfigure</artifactId>
  <version>2.6.4</version>
</dependency>
2.2、容器功能

2.2.1 组件添加

@Configuration
@Configuration(proxyBeanMethods = true)   //告诉spring_boot这是一个配置类
public class MyConfig {
    //给容器添加组件,默认id为方法名,可以通过@Bean("")修改
    @Bean("user")
    public User user01() {
        return new User("lucy", 18);
    }
    @Bean
    public Pet pet01() {
        return new Pet("tom");
    }
}

//main主程序
@SpringBootApplication
public class FirstSpringboot {
    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(FirstSpringboot.class, args);
        Pet tom = run.getBean("pet01", Pet.class);
        System.out.println(tom);
    }
}

3. springboot 集成jsp页面
  1. 导入依赖
<!--引入Springboot内嵌的tomcat对jsp的依赖,仅展示页面-->
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
</dependency>
  1. 创建webapp文件夹–>在项目结构中将其改为web目录

  2. Springboot项目默认推荐使用的前端引擎是thymeleaf
    要使用springboot集成jsp,手动指定jsp最后编译的路径
    而且springboot集成jsp编译jsp的路径是springboot规定好的位
    META- INF/ resources

<resources>
     <resource>
          <!--源文夹-->
          <directory>src/main/webapp</directory>
          <!--指定编译到META- INF/resources-->
          <targetPath>META-INF/resources</targetPath>
          <!--指定源文件夹中的哪个资源要编译进行-->
          <includes>
              <include>*.*</include>
          </includes>
      </resource>
</resources>
  1. 配置视图解析器
#配置视图解析器
#前缀
spring.mvc.view.prefix=/
#后缀
spring.mvc.view.suffix=.jsp
  1. 测试
@RequestMapping("/testjsp")
public String testjsp(Model model) {
    //方法一:
    //ModelAndView modelAndView =new ModelAndView();
    //modelAndView.addObject("test","hello,jsp");
    //modelAndView.setViewName("jsptest");
    //return modelAndView;
    model.addAttribute("test", "hello,jsp");
    return "jsptest";
}
4. springboot集成mybatis

导入依赖:

<!--mysql驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis整合springboot的起步依赖-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>
4.1 mybatis逆向工程
  1. 在resource下创建generatorConfig.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>

    <!-- 指定连接数据库的 JDBC 驱动包所在位置,指定到你本机的完整路径 -->
    <classPathEntry location="F:\S2\Javaxx\mysql学习\JDBC学习\mysql-connector-java-8.0.25\mysql-connector-java-8.0.25.jar"/>

    <!-- 配置 table 表信息内容体,targetRuntime 指定采用 MyBatis3 的版本 -->
    <context id="tables" targetRuntime="MyBatis3">
        <!-- 抑制生成注释,由于生成的注释都是英文的,可以不让它生成 -->
        <commentGenerator>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>


        <!-- 配置数据库连接信息 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://139.9.42.209:3306/spring"
                        userId="root"
                        password="123456">
        </jdbcConnection>
        <!-- 生成 model 实体类,targetPackage 指定 model 类的包名, targetProject 指定
        生成的 model 放在 idea 的哪个工程下面-->
        <javaModelGenerator targetPackage="com.guang.bootmybatis.domain"
                            targetProject="src/main/java">
            <property name="enableSubPackages" value="false"/>
            <property name="trimStrings" value="false"/>
        </javaModelGenerator>

        <!-- 生成 MyBatis 的 Mapper.xml 文件,targetPackage 指定 mapper.xml 文件的
        包名, targetProject 指定生成的 mapper.xml 放在 eclipse 的哪个工程下面 -->
        <sqlMapGenerator targetPackage="com.guang.bootmybatis.mapper"
                         targetProject="src/main/java">
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>

        <!-- 生成 MyBatis 的 Mapper 接口类文件,targetPackage 指定 Mapper 接口类的包
        名, targetProject 指定生成的 Mapper 接口放在 eclipse 的哪个工程下面 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.guang.bootmybatis.mapper"
                             targetProject="src/main/java">
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>

        <!--tableName表对应的名字,domainObjectName 生成的实体类的名字-->
        <table tableName="student" domainObjectName="Student"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false">
        </table>
    </context>
</generatorConfiguration>
  1. 在pom.xml文件中添加插件
<!--mybatis逆向工程插件-->
<resources>
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.xml</include>
        </includes>
    </resource>
</resources>
<plugins>
    <plugin>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-maven-plugin</artifactId>
        <version>1.3.7</version>
        <configuration>
            <configurationFile>generatorConfig.xml</configurationFile>
            <verbose>true</verbose>
            <overwrite>true</overwrite>
        </configuration>
    </plugin>
</plugins>
4.2、@Mapper 注解

扫描dao接口到spring容器,达到为其创建实现类的效果;

  1. application.properties
#配置数据源
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://139.9.42.209:3306/springboot
spring.datasource.username=root
spring.datasource.password=123456
  1. dao或者mapper层
@Mapper
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);
}
  1. service 层
@Service
public class StudentServiceImpl implements StudentService {
    @Autowired
    private StudentMapper studentMapper;

    @Override
    public Student selectById(Integer id) {
        Student student = studentMapper.selectByPrimaryKey(id);
        return student;
    }
}
  1. controller 层
@Controller
public class StudentController {
    @Autowired
    private StudentService studentService;

    @RequestMapping("/select")
    public @ResponseBody
    Object selectById(Integer id) {
        Student student = studentService.selectById(id);
        return student;
    }
}
4.3 @MapperScan
@MapperScan(basepakges="com.guang.mapper")   //扫描该包下的所有mapper为其创建虚拟实现类
public class BootMybatisApplication {
    public static void main(String[] args) {
        SpringApplication.run(BootMybatisApplication.class, args);
    }
}

附: mapper.xml 文件存放路径问题

第一种:

//存放在com.guang.boot.mapper下和dao接口一块
<resources>
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.xml</include>
        </includes>
    </resource>
</resources>

第二种:

#在resources资源文件下创建mapper文件夹,将xml文件放进去
#然后在指定mybatis映射文件的路径
mybatis.mapper-locations=classpath:mapper/*.xml
4.5 springboot事务

@Transactional //需要对哪个方法加上事务 直接在方法上加上该注解

@Transactional
@Override
public int updateStudentByidAndname(Student student) {
    int result = studentMapper.updateByPrimaryKey(student);
    int aa = 10 / 0;
    return result;
}
5. 集成mvc常用注解

@RestController = @ResponseBody+@Controller

@GetMapping(“/select”)

//@RequestMapping(value = "/select",method = {RequestMethod.GET})
@GetMapping("/select")    //只接受get请求,该注解一般在查询时使用-》查询
public  Object show1() {
return "only get";
}

@Postmapping(“/inset”)

//@RequestMapping(value = "/insert",method = {RequestMethod.POST})
@PostMapping("/insert")    //只接受post请求 该注解一般在新增时使用
public  Object show2() {
    return "only post";
}

@Deletemapping

@RequestMapping(value = "/delete", method = {RequestMethod.DELETE})
@DeleteMapping("/delete")    //只接受DELETE请求 一般在删除请求时使用 -》删除
public Object show3() {
    return "only delete";
}

@Putmapping

@RequestMapping(value = "/update", method = {RequestMethod.PUT})
@PutMapping("/update")    //只接受put请求 一般在更新请求时使用  -》 更新
public Object show4() {
    return "only post";
}
6.spring Boot 实现 RESTFul

例:

Http接口:Http://localhost:8080/student?id=1001&name=zhangsan

RESTFuld风格: Http://localhost:8080/student/1001/zhangsan

Spring boot 开发RESTFul主要是靠几个注解实现

@pathVariable

获取url中的数据,该注解时实现RESTFul最主要的一个注解

@GetMapping("/student/{id}/{age}")
public Object show(@PathVariable("id") Integer id, @PathVariable("age") Integer age) {
    Map<String, Object> map = new HashMap<>();
    map.put("id", id);
    map.put("age", age);
    return map;
}

@DeleteMapping("/student/{id}/{status}")
public Object show1(@PathVariable("id") Integer id, @PathVariable("status") Integer status) {
    Map<String, Object> map = new HashMap<>();
    map.put("id", id);
    map.put("status", status);
    return map;
}
//如遇以上两个方法请求参数类型一样时,应使用不同的注解请求方式区分开,
//如必须有两个相同操作类型,并且参数类型也一样时可以改变参数位置来区分
@GetMapping("/student/stu/{id}/{age}")
@GetMapping("/student/{id}/stu/{age}")
7. Spring Boot 集成redis
  1. 添加操作数据类型的依赖
<!--springboot集成redis所需依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  1. 在springboot核心配置文件中添加redis的配置
#配置redis
spring.redis.host=139.9.42.209
spring.redis.port=6379
spring.redis.password=root123

示例: (往redis里存值)

@RestController
public class RedisController {
    @Autowired
    private RedisService redisService;
    @RequestMapping("/put")
    public Object show(String key,String value){
        redisService.put(key,value);
        return "值已经放进redis数据库";
    }
}

@Service
public class RedisServiceImpl implements RedisService {
    @Autowired   //集成Redis模板对象  RedisTemplate<Object,Object> 源于spring-boot-starter-data-redis依赖
    private RedisTemplate<Object,Object> redisTemplate;
    @Override
    public void put(String key, String value) {
        redisTemplate.opsForValue().set(key,value);  //插入普通值
    }
}

示例: (从redis中取值)

Controller@RequestMapping("/get")
public Object get(String key){
   String value= redisService.get(key);
    return value;
}

service 层 
@Override
public String get(String key) {
    String value = (String) redisTemplate.opsForValue().get(key);
    return value;
}
8. springboot 集成 Dubbo 分布式框架
  1. 接口工程:(interface)存放实体bean和业务接口

  2. 服务提供者: (provider) 业务接口的实现类并将服务暴露且注册到注册中心,调用数据持久层
    -添加依赖(dubbo,注册中心,接口工程)

    <!--dubbo 集成spring-boot 起步依赖-->
    <dependency>
        <groupId>com.alibaba.spring.boot</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.0.0</version>
    </dependency>
    <!--注册中心依赖-->
    <dependency>
        <groupId>com.101tec</groupId>
        <artifactId>zkclient</artifactId>
        <version>0.10</version>
    </dependency>
    <!--接口工程-->
    <dependency>
        <groupId>com.guang.boot</groupId>
        <artifactId>dubbo-interface</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    

    -配置服务提供者核心配置文件

    #设置内嵌tomcat端口号
    server.port=8081
    #设置上下文跟
    server.servlet.context-path=/
    # 设置dubbo的配置
    spring.application.name=dubbo-provider
    
    #设置当前工程是一个 服务提供者
    spring.dubbo.server=true
    
    #设置注册中心
    spring.dubbo.registry=zookeeper:139.9.42.209:2181
    
  3. 服务消费者:(consumer) 处理浏览器客户端发送的请求,从注册中心调用服务提供者所提供的服务
    -添加依赖(dubbo ,注册中心,接口工程)
    -配置服务消费者核心配置文件

示例:

interface 模块:

public interface StudentService {
    Integer selectStudentAll();
}

provider模块:

//提供者创建实现类
@Component  //交给spring容器管理
//dubbo下的@service(interfaceClass="你要暴漏的接口")
@Service(interfaceClass = StudentService.class,version = "1.0.0",timeout = 15000)
public class StudentServiceImpl implements StudentService {
    @Override
    public Integer selectStudentAll() {
        //操作数据库
        return 2000;
    }
}

//主程序设置开启springboot和 Dubbo注解
@SpringBootApplication  //开启springboot 注解
@EnableDubboConfiguration   //开启Dubbo 注解
public class DubboProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(DubboProviderApplication.class, args);
    }

}

consumer模块:

//使用者
@RestController
public class ConsumerController {
    //同样是使用dubbo下的该注解
    @Reference(interfaceClass = StudentService.class,version = "1.0.0",check = false)
    private StudentService studentService;

    @RequestMapping("/student/count")
    public Object count() {
        Integer count = studentService.selectStudentAll();
        return "总人数为"+count;
    }
}

//主程序
@SpringBootApplication
@EnableDubboConfiguration
public class DubboConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(DubboConsumerApplication.class, args);
    }
}
9. Spring Boot 创建java项目

第一种方式:

@Service
public class StudentServiceImpl implements StudentService {
    @Override
    public String show() {
        return "Say hello";
    }
}

//主程序
@SpringBootApplication
public class SpringbootJavaApplication {

    public static void main(String[] args) {
        //springboot 启动后 返回值是ConfigurableApplicationContext,它也是一个容器
        ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringbootJavaApplication.class, args);
        //从容器中获取指定对象
        StudentService studentService = (StudentService) applicationContext.getBean("studentServiceImpl");
        //调用方法
        String show = studentService.show();
        System.out.println(show);
    }
}

第二种方式:

@SpringBootApplication
public class SpringbootJavaApplication implements CommandLineRunner {
    @Autowired
    private StudentService studentService;

    public static void main(String[] args) {
        SpringApplication.run(SpringbootJavaApplication.class,args);
    }

    //实现CommandLineRunner接口的run方法
    @Override
    public void run(String... args) throws Exception {
        String show = studentService.show();
        System.out.println(show);
    }
}
10. spring boot 关闭 && 开启 控制台LOGO

关闭:

public class SpringbootJavaApplication implements CommandLineRunner {
    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(SpringbootJavaApplication.class);
        //设置关闭控制台logo
        springApplication.setBannerMode(Banner.Mode.OFF);
        springApplication.run();
    }
}

修改控制台LOGO 样式:

http://patorjk.com/software/taag/#p=display&f=Big&t=I%20%20LOVE%20%20J%20A%20V%20A
11. 拦截器

使用步骤:

//拦截器类
public class UserInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("进入拦截器!!");
        User user = (User) request.getSession().getAttribute("user");
        System.out.println(user);
        if(null==user){
            //未登录
            response.sendRedirect(request.getContextPath()+"/user/error");
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

Controller
@RestController
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/login")
    public Object login(HttpServletRequest request) {
        //将用户的信息存到session中
        User user = new User();
        user.setId(1001);
        user.setName("张三");
        request.getSession().setAttribute("user", user);
        return "login success";
    }

    //登陆以后才可访问
    @RequestMapping("/center")
    public Object center() {
        return "see cent message";
    }

    //不登陆就可访问
    @RequestMapping("/out")
    public Object out() {
        return "see out message";
    }

    //没登陆却访问了需要登陆的路径
    @RequestMapping("/error")
    public Object error() {
        return "error";
    }
}

//配置类
@Configuration    //表示该类是一个配置类   相当于之前的配置文件
public class InterceptorConfig implements WebMvcConfigurer {
    //mvc:interceptors
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //拦截哪些
        String[] addPathPatterns ={
                "/user/**"
        };
        //排除那些
        String[] excludePathPatterns ={
                "/user/out","/user/error", "/user/login"
        };
      registry.addInterceptor(new UserInterceptor()).addPathPatterns(addPathPatterns).excludePathPatterns(excludePathPatterns);
    }
}
12.sprintboot 使用servlet

第一种方式:使用@WebServlet(urlPatterns = “/myServlet”)和@ServletComponentScan(“com.guang.boot.controller”) 注解

//servlet
@WebServlet(urlPatterns = "/myServlet")
public class SpringbootServletController extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().println("hello springboot&servlet");
        response.getWriter().flush();
        response.getWriter().close();
    }
}

//主程序
@SpringBootApplication
@ServletComponentScan("com.guang.boot.controller") //扫描@Webservlet 注解
public class SpringBootServletApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootServletApplication.class, args);
    }
}

第二种方式: 不用前两种注解,只需要@Bean

@Configuration   //这是一个配置类
public class ServletConfig {
    //@Bean 是一个方法级别的注解 相当于配置文件中的
    // <beans>
    // <bean id="" class=""></bean>
    // </beans>
    @Bean
    public ServletRegistrationBean ServletRegistrationBean() {
        ServletRegistrationBean sg =new ServletRegistrationBean(new Myservlet(),("/myServlet")); //new ...(我创建的servlet,"设置请求的路径")
        return sg;
    }
}
13.使用filter 过滤器

第一种: @WebFilter(“/myfilter”)

@WebFilter("/myfilter")
public class Myfilter extends HttpFilter {
    @Override
    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("进入filter拦截器!!");
        chain.doFilter(request,response);
    }
}

//主程序
@ServletComponentScan("com.guang.boot.filter") //扫描@WebFilter 

第二种:

//创建类继承HttpFilter
public class Myfilter extends HttpFilter {
    @Override
    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("进入filter拦截器!!");
        chain.doFilter(request,response);
    }
}
//controller
@RestController
public class FilterControoler {
    @RequestMapping("/user/detail")
    public Object detail() {
        return "/user/detail";
    }

    @RequestMapping("/center")
    public Object center() {
        return "center";
    }
}
//创建配置类
@Configuration  //配置类
public class FilterConfig {
    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
        //创建过滤器
        FilterRegistrationBean filterRegistrationBean =new FilterRegistrationBean(new Myfilter());
        //添加过滤路径
        filterRegistrationBean.addUrlPatterns("/user/*");
        return filterRegistrationBean;
    }
}
14. 设置字符编码

第一种方式:

  1. 创建servlet
@WebServlet("/encoding")
public class MyServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().println("你好世界!!");
        resp.setContentType("text/html;character=utf-8");
        resp.getWriter().flush();
        resp.getWriter().close();
    }
}


  1. 创建配置类
@Configuration
public class MyConfig {
    @Bean
    public FilterRegistrationBean characterEncodingFilterRegistrationBean(){
        //创建字符编码过滤器
        CharacterEncodingFilter characterEncodingFilter =new CharacterEncodingFilter();
        //设置强制转换
        characterEncodingFilter.setForceEncoding(true);
        //设置字符类型
        characterEncodingFilter.setEncoding("utf-8");
        //创建FilterRegistrationBean对象
        FilterRegistrationBean filter =new FilterRegistrationBean();
        filter.setFilter(characterEncodingFilter);
        filter.addUrlPatterns("/*");  
        return  filter;
    }
}
  1. 设置application.properties配置文件
#关闭springboot 的http字符编码支持
#关闭之后自己设置的才生效
server.servlet.encoding.enabled=false

第二种:

#开启springboot 的http字符编码支持
server.servlet.encoding.enabled=true
#开启强制使用指定字符编码
server.servlet.encoding.force=true
#设置格式
server.servlet.encoding.charset=utf-8
15. 打包

打war包:

<!--设置打包方式-->
<packaging>war</packaging>


<!--在bilud标签设置打war包的字符-->
<finalName>SpringBootWar</finalName>

<resources>
    <resource>
        <!--源文夹-->
        <directory>src/main/webapp</directory>
        <!--指定编译到META- INF/resources-->
        <targetPath>META-INF/resources</targetPath>
        <!--指定源文件夹中的哪个资源要编译进行-->
        <includes>
            <include>*.*</include>
        </includes>
    </resource>

    <resource>
        <!--源文夹-->
        <directory>src/main/resources</directory>
        <includes>
            <include>**/*.*</include>
        </includes>
    </resource>
</resources>

主程序:

@SpringBootApplication
//打包需继承SpringBootServletInitializer
public class BootDapakageApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(BootDapakageApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
     //参数为当前启动类
        return builder.sources(BootDapakageApplication.class);
    }
}

点击右侧maven–>Lifecycle–>选择打包的项目–>先clean–>再点击pakage–>将打包后的war包放到tomcat–>webapps目录下 -->在bin目录下启动tomcat–>在网页中输入请求路径要带上项目名

打jar包:

<!--打包后的项目名称-->
<finalName>SpringBootjar</finalName>

<resources>
    <resource>
        <!--源文夹-->
        <directory>src/main/webapp</directory>
        <!--指定编译到META- INF/resources-->
        <targetPath>META-INF/resources</targetPath>
        <!--指定源文件夹中的哪个资源要编译进行-->
        <includes>
            <include>*.*</include>
        </includes>
    </resource>

    <resource>
        <!--源文夹-->
        <directory>src/main/resources</directory>
        <includes>
            <include>**/*.*</include>
        </includes>
    </resource>
</resources>
#主配置文件
server.port=8088
server.servlet.context-path=/

spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp

点击右侧maven–>Lifecycle–>选择打包的项目–>先clean–>再点击pakage–>将打包后的jar包放到本地目录下–>打开cmd命令窗口–>输入 java -jar 打包后的项目名称 .jar -->进入浏览器访问

16. SpringBoot 集成logback日志
  1. 在resource目录下 创建logback-spring.xml文件:
</filter>
<encoder>
<Pattern>%date [%-5p] [%thread] %logger{60}
[%file : %line] %msg%n</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--<File>/home/log/stdout.log</File>-->
<File>D:/log/stdout.log</File>
<encoder>
<pattern>%date [%-5p] %thread %logger{60}
[%file : %line] %msg%n</pattern>
</encoder>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 添加.gz 历史日志会启用压缩 大大缩小日志文件所占空间 -->
<!--<fileNamePattern>/home/log/stdout.log.%d{yyyy-MM-dd}.log</fileNam
ePattern>-->
<fileNamePattern>D:/log/stdout.log.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory><!-- 保留 30 天日志 -->
</rollingPolicy>
</appender>
<logger name="com.abc.springboot.mapper" level="DEBUG" />
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
  1. 添加依赖:
<!--logback日志依赖-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
  1. 使用注解 @Slf4j
@Slf4j
//类名
//方法
log.info("学生总人数查询:");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值