SSM 学习第二天

纯注解开发

首先在需要注入 IOC 容器的类上加入 @Component 注解, 这样就向 IOC 容器中注入了一个 Bean 了.

@Component 注解有三个衍生注解

  • @Repository
  • @Service
  • @Controller
    用于标识不同层, 快捷开发

IOC 容器默认是单例的, 可以通过 @Scope 注解, 有 prototype(多例), singleton(单例) 两个参数.
然后需要创建一个 Spring 的配置类

1
2
3
4
5
6
7
8
9
package org.ljguo.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("org.ljguo")
public class BeanConfig {
}
  • @Configuration 注解使得其成为一个注解类
  • @ComponentScan("org.ljguo") 进行包扫描, 扫描刚刚的 @Component 注解

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package org.ljguo.test;

import org.ljguo.config.BeanConfig;
import org.ljguo.dao.UserDao;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class UserTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(BeanConfig.class);
UserDao userDao = ac.getBean(UserDao.class);
// ac.close();
System.out.println(userDao);
}
}
  • 需要使用 AnnotationConfigApplicationContext 类加载配置类, 可以加载多个配置类, 以逗号给出即可.

生命周期

包括 init destroy
定义两个方法,

1
2
3
4
5
6
7
8
9
@PostConstruct
public void init() {
System.out.println("init...");
}

@PreDestroy
public void destroy() {
System.out.println("destroy...");
}

两个注解, @PostConstruct 用于注解 init 方法, 表示在构造器之后执行, @PreDestroy 注解用于 destroy 方法, 表示在销毁之前执行, 但是需要手动关闭 IOC 容器对象.

依赖注入

自动装配

1
2
@Autowired
private User user;

值注入

1
2
@Value("100")
private int num;

也可以从 properties 文件中获得数据, 首先在 Spring 配置文件中引入 properties 文件,

1
@PropertySource("classpath:jdbc.properties")
1
2
3
4
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ljguo
jdbc.username=root
jdbc.password=20001020

然后使用,

1
2
@Value("${jdbc.url}")
private String str;

管理第三方 Bean

建议新建一个配置类, 例如名为 JdbcConfig.class,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package org.ljguo.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.ljguo.dao.impl.UserDaoImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;

public class JdbcConfig {
@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
public DataSource dataSource(UserDaoImpl userDao) {
userDao.show();
DruidDataSource dc = new DruidDataSource();
dc.setDriverClassName(driver);
dc.setUrl(url);
dc.setUsername(username);
dc.setPassword(password);
return dc;
}
}
  • @Value 注解用于注入一些普通类型的值, 注入的是 properties 文件中的数据, 记得需要载入该配置文件
  • @Bean 用于注入一个第三方 Bean
  • 方法名就是要注入 Bean 的 id 值
  • 若要注入引用类型, 需要将类型写在方法的形参里面, 如上的 UserDaoImpl (自动装配)

在主配置文件中, 使用 @Import 注解导入该配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
package org.ljguo.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;

@Configuration
@Import(JdbcConfig.class)
@ComponentScan("org.ljguo")
@PropertySource("classpath:jdbc.properties")
public class BeanConfig {
}

Spring 整合 Mybatis

目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.
├── pom.xml
└── src
├── main
│   ├── java
│   │   └── com
│   │   └── ljguo
│   │   ├── AppTest.java
│   │   ├── config
│   │   │   ├── JdbcConfig.java
│   │   │   ├── MybatisConfig.java
│   │   │   └── SpringConfig.java
│   │   ├── mapper
│   │   │   └── UserMapper.java
│   │   ├── pojo
│   │   │   └── User.java
│   │   └── service
│   │   └── UserService.java
│   └── resources
│   ├── com
│   │   └── ljguo
│   │   └── mapper
│   │   └── UserMapper.xml
│   ├── jdbc.properties

15 directories, 13 files

源码位置 spring-mybatis

导入依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 <!-- mysql 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.31</version>
</dependency>

<!-- 数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>

<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<!-- spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<!-- spring 整合 mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>

配置文件

  • SpringConfig

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    package com.ljguo.config;

    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Import;
    import org.springframework.context.annotation.PropertySource;

    @Configuration
    @ComponentScan("com.ljguo")
    @PropertySource("classpath:jdbc.properties")
    @Import({JdbcConfig.class,MybatisConfig.class})
    public class SpringConfig {

    }
  • JdbcConfig

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    import org.springframework.context.annotation.Bean;

    import javax.sql.DataSource;

    public class JdbcConfig {
    @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
    public DataSource dataSource() {
    DruidDataSource ds = new DruidDataSource();
    ds.setDriverClassName(driver);
    ds.setUrl(url);
    ds.setUsername(username);
    ds.setPassword(password);
    return ds;
    }
    }
  • MybatisConfig

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    package com.ljguo.config;

    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.mapper.MapperScannerConfigurer;
    import org.springframework.context.annotation.Bean;

    import javax.sql.DataSource;

    public class MybatisConfig {

    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
    SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
    ssfb.setTypeAliasesPackage("com.ljguo.pojo");
    ssfb.setDataSource(dataSource);
    return ssfb;
    }

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
    MapperScannerConfigurer msc = new MapperScannerConfigurer();
    msc.setBasePackage("com.ljguo.mapper");
    return msc;
    }
    }
  1. 注入两个对象, SqlSessionFactoryBeanMapperScannerConfigurer
  2. 设置 pojo 和 mapper 包路径进行映射
  • UserMapper

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package com.ljguo.mapper;

    import com.ljguo.pojo.User;
    import org.springframework.stereotype.Component;

    import java.util.List;

    @Component
    public interface UserMapper {
    List<User> selectAll();

    void add(User user);
    }
  • UserMapper.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.ljguo.mapper.UserMapper">
    <resultMap id="userResultMap" type="user">
    <result column="user_id" property="userId"/>
    </resultMap>
    <select id="selectAll" resultType="com.ljguo.pojo.User" resultMap="userResultMap">
    select *
    from tb_user;
    </select>

    <insert id="add" >
    insert into tb_user (username, password, permission)
    values (
    #{username}, #{password}, #{permission}
    );
    </insert>
    </mapper>
  • User 实体类比较简单

  • UserService

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    package com.ljguo.service;

    import com.ljguo.mapper.UserMapper;
    import com.ljguo.pojo.User;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import java.util.List;

    @Service
    public class UserService {

    @Autowired
    private UserMapper userMapper;

    public List<User> selectAll() {
    return userMapper.selectAll();
    }
    }
  1. 自动装配一个 UserMapper 对象来调用对应的方法
  • AppTest
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    package com.ljguo;

    import com.ljguo.config.SpringConfig;
    import com.ljguo.mapper.UserMapper;
    import com.ljguo.service.UserService;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;

    public class AppTest {
    public static void main(String[] args) {
    ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
    UserService userService = ac.getBean(UserService.class);
    System.out.println(userService.selectAll());
    }
    }
  1. 载入 SpringConfig 配置文件来初始化 IOC 容器
  2. 拿到 UserService 对象, 执行方法