01.Spring之Bean
# 01.IOC和DI
# 1、代码耦合事例
- 在BookServicelmpl內部之间new了BookDaolmpl对象
- 试想一下,如果有一个新的BookDaolmpl2代替了BookDaolmpl
- 那我们的代码中就需要将new BookDaolmpll改成BookDaolmpl2,重新编译、打包、部署、运行一系列操作
- 造成这个问题的原因就是BookServicelmpl和BookDaolmpl 强耦合到一起了
# 2、核心概念
1)IOC(Inversion of Control)控制反转
- 使用对象时,由
主动new产生对象转换为由外部提供对象
,此思想称为控制反转
- 通俗的讲就是“将new对象的权利交给Spring,我们从Spring中获取对象使用即可”
- 使用对象时,由
2)IOC容器
Spring提供了一个容器
,称为IOC容器
,管理对象生命周期和依赖关系的容器- IOC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为
Bean
3)DI(Dependency Injection)依赖注入
- 在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
- 依赖注入是实现IOC的一种方法,就是由IOC容器在运行期间,动态地将某个依赖关系注入到对象内部
通俗的讲:将IOC容器中的dao对象赋值给BookServicelmpl中的BookDao就是依赖注入
# 3、DI案例
# 0、说明
说明
- 1.管理什么?(Service与Dao)
- 2.如何将被管理的对象告知IOC容器?(配置文件)
- 3.被管理的对象交给IOC容器,如何获取到IoC容器?(接口)
- 4.IOC容器得到后,如何从容器中获取bean?(接口方法)
设置绑定关系
spring_01
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ │ └── org
│ │ │ └── example
│ │ │ ├── App.java
│ │ │ ├── App2.java
│ │ │ ├── dao
│ │ │ │ ├── BookDao.java
│ │ │ │ └── impl
│ │ │ │ └── BookDaoImpl.java
│ │ │ └── service
│ │ │ ├── BookService.java
│ │ │ └── impl
│ │ │ └── BookServiceImpl.java
│ │ └── resources
│ │ └── applicationContext.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 1、pom.xml
<dependencies>
<!--导入spring的坐标spring-context,对应版本是5.2.10.RELEASE-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 2、dao
example/dao/BookDao.java
接口
public interface BookDao {
public void save();
}
1
2
3
2
3
example/dao/impl/BookDaoImpl.java
类
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
}
1
2
3
4
5
2
3
4
5
# 3、service
example/service/BookService.java
接口
public interface BookService {
public void save();
}
1
2
3
2
3
example/service/impl/BookServiceImpl.java
类
public class BookServiceImpl implements BookService {
// private BookDao bookDao = new BookDaoImpl();
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
// 提供依赖对象对应的setter方法
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 4、org/example/App2.java
public class App2 {
public static void main(String[] args) {
// 获取IoC容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
// 获取bean(根据bean配置id获取)
// BookDao bookDao = (BookDao) ctx.getBean("bookDao");
// bookDao.save();
BookService bookService = (BookService) ctx.getBean("bookService");
bookService.save();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 5、resources/applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
bean标签:表示配置bean
id属性:表示给bean起名字
class属性:表示给bean定义类型
-->
<bean id="bookDao1" class="org.example.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="org.example.service.impl.BookServiceImpl">
<!--配置server与dao的关系
property标签:表示配置当前bean的属性
name属性:表示配置哪一个具体的属性
ref属性:表示参照哪一个bean
-->
<property name="bookDao" ref="bookDao1"/>
</bean>
</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 02.Bean
# 1、Bean概述
- JavaBean是一个符合特定规则的Java类,它通过方法提供了一个默认的无参构造函数,可以通过get和set方法对其中的属性进行访问
- Spring Bean是Spring框架中的基本组成单位,Spring容器会负责Spring Bean的创建和管理
- Spring Bean是由Spring IOC容器实例化的一个对象
- 这个对象就通过配置文件或者注解生成一个或多个实例,这些实例就可以在应用程序中使用
# 2、Component注解
# 0、说明
@Controller
,@Service
,@Repository
和@Component
都是Spring中的注解,它们用于定义Bean以及Bean的类型- 它们都会把类标记为Spring的组件,Spring会自动扫描并创建这些类的实例,并把它们放入Spring的ApplicationContext中
- 1)
@Component
- 这是一个通用性的注解,可以标记任何类作为Spring组件
- 当Spring进行扫描的时候,会自动识别这个注解,并创建其类的实例
- 2)
@Controller
- 这个注解主要用在MVC架构的控制层
- 被
@Controller
标记的类会被识别为Spring MVC Controller对象,可以响应用户的请求
- 3)
@Service
- 这个注解用于标记业务逻辑层的组件,用于处理业务逻辑,事务控制等
- Spring在扫描到
@Service
注解的类时,会创建其实例并将其视为业务逻辑层的组件
- 4)
@Repository
- 这个注解用于标记数据访问层的组件,它通常用在实现数据访问的类上,例如DAO对象
- Spring在扫描到
@Repository
注解的类时,会创建其实例并将其视为数据访问对象 - 此外,
@Repository
还有一个额外的特性,就是它能够将底层数据访问异常转换为Spring的DataAccessException
# 1、Controller
@Controller
:这个注解通常用于标记控制层的组件,也就是直接接收用户请求并控制应用流程的组件@Controller
通常用于配合@RequestMapping
等注解用于处理HTTP请求- 使用场景:处理和接收用户请求,如返回一个视图或者处理用户提交的数据等
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/users")
public String listUsers(Model model) {
model.addAttribute("users", userService.getAllUsers());
return "users";
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 2、Service
@Service
:这个注解通常用于标记业务层的组件,也就是处理具体业务逻辑的组件@Service
在业务逻辑复杂,需要分层处理的时候使用- 使用场景:封装和处理业务逻辑,如用户注册、登录、商品购买等业务逻辑
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> getAllUsers() {
return userRepository.findAll();
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 3、Repository
@Repository
:这个注解通常用于标记数据访问层的组件,也就是直接与数据库交互的组件@Repository
在数据访问逻辑处理时使用- 使用场景:封装数据访问逻辑,如数据库的增删改查等操作
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
1
2
3
2
3
# 3、Autowired自动装配
@Autowired
是Spring框架的一个注解,它主要用于自动装配Spring Bean作用:
@Autowired
可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作- 通过
@Autowired
的使用来消除get
和set
方法。在Spring容器中,@Autowired
注解默认按类型装配。
使用场景:
- 在Spring中,我们通常会把一些服务类定义为Bean,然后在需要使用这些服务的地方通过
@Autowired
来自动装配
- 在Spring中,我们通常会把一些服务类定义为Bean,然后在需要使用这些服务的地方通过
# 1、类成员变量标注
UserRepository
是一个Spring Data JPA的Repository,Spring会自动创建它的实例- 在
UserService
中,我们需要使用UserRepository
,所以我们在userRepository
字段上加上@Autowired
注解 - 这样Spring就会自动将
UserRepository
的实例注入到UserService
中
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public User findUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 2、方法进行标注
- 在
setUserRepository
方法上加上@Autowired
注解 - 这样Spring就会自动调用这个方法,将
UserRepository
的实例注入到UserService
中
@Service
public class UserService {
private UserRepository userRepository;
@Autowired
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User findUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 3、构造函数标注
UserService
的构造函数上加上@Autowired
注解- 这样Spring在创建
UserService
的实例的时候,就会自动将UserRepository
的实例注入到UserService
中
@Service
public class UserService {
private UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User findUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 4、第三方bean依赖注入
1)单独定义配置类
public class JdbcConfig {
//@Bean:表示当前方法的返回值是一个bean对象,添加到IOC容器中
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
ds.setUsername("root");
ds.setPassword("root");
return ds;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
2)将独立的配置类加入核心配置
// 方式1:@Import注解导入式
@Configuration
@ComponentScan("com.itheima")
//@Import:导入配置信息
@Import({JdbcConfig.class})
public class SpringConfig {
}
1
2
3
4
5
6
7
2
3
4
5
6
7
// 方式2:@ComponentScan扫描式
@Configuration
@ComponentScan({"com.itheima.config","com.itheima.service","com.itheima.dao"})
//只要com.itheima.config包扫到了就行,三个包可以合并写成com.itheima
public class SpringConfig {
}
1
2
3
4
5
6
2
3
4
5
6
# 03.Bean案例
# 0、说明
spring_02
├── pom.xml // 项目的依赖、构建规则配置
├── src // 源代码目录,所有的源代码、配置文件、资源文件都放在这个目录下
│ ├── main // 主程序源代码目录,包含java源代码和资源文件
│ │ ├── java // java源代码目录,所有的java源代码都放在这里
│ │ │ ├── App.java // 两个java程序入口文件,通常包含主程序入口,即main方法
│ │ │ ├── App2.java
│ │ │ └── com
│ │ │ └── example // 包目录,通常按照公司的域名反转作为包名的前缀
│ │ │ ├── config // 配置类的包
│ │ │ │ ├── JdbcConfig.java
│ │ │ │ ├── MybatisConfig.java
│ │ │ │ └── SpringConfig.java
│ │ │ ├── dao // 数据访问对象(DAO)的包,用于操作数据库
│ │ │ │ └── AccountDao.java
│ │ │ ├── domain // 领域模型的包
│ │ │ │ └── Account.java // Account.java,用于表示账户这个领域对象
│ │ │ └── service // 服务层的包
│ │ │ ├── AccountService.java // 接口
│ │ │ └── impl
│ │ │ └── AccountServiceImpl.java
│ │ └── resources // 资源文件目录
│ │ ├── SqlMapConfig.xml // MyBatis的SQL映射配置文件
│ │ └── jdbc.properties // JDBC的数据库连接配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 1、初始化数据库
create database if not exists spring_db character set utf8;
use spring_db;
create table if not exists tbl_account(
id int primary key auto_increment,
name varchar(20),
money double
);
insert into tbl_account values(null,'Tom',1000);
insert into tbl_account values(null,'Jerry',1000);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 2、dao
// src/main/java/com/example/dao/AccountDao.java
import com.example.domain.Account;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
public interface AccountDao {
@Insert("insert into tbl_account(name,money)values(#{name},#{money})")
void save(Account account);
@Delete("delete from tbl_account where id = #{id} ")
void delete(Integer id);
@Update("update tbl_account set name = #{name} , money = #{money} where id = #{id} ")
void update(Account account);
@Select("select * from tbl_account")
List<Account> findAll();
@Select("select * from tbl_account where id = #{id} ")
Account findById(Integer id);
}
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
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
# 3、domain
// src/main/java/com/example/domain/Account.java
import java.io.Serializable;
public class Account implements Serializable {
private Integer id;
private String name;
private Double money;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\'' +
", money=" + money +
'}';
}
}
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
39
40
41
42
43
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
39
40
41
42
43
# 4、service
- java/com/example/service/AccountService.java 接口
import com.example.domain.Account;
import java.util.List;
public interface AccountService {
void save(Account account);
void delete(Integer id);
void update(Account account);
List<Account> findAll();
Account findById(Integer id);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- src/main/java/com/example/service/impl/AccountServiceImpl.java 类
import com.example.dao.AccountDao;
import com.example.domain.Account;
import com.example.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
public void save(Account account) {
accountDao.save(account);
}
public void update(Account account){
accountDao.update(account);
}
public void delete(Integer id) {
accountDao.delete(id);
}
public Account findById(Integer id) {
return accountDao.findById(id);
}
public List<Account> findAll() {
return accountDao.findAll();
}
}
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
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
# 5、Spring和Mybatis配置
# 0、jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_db?useSSL=false
jdbc.username=root
jdbc.password=123456
1
2
3
4
2
3
4
# 1、XML的配置方式:法1
properties: 加载属性文件,Mybatis会把属性文件加载到Mybatis配置中
typeAliases: 类型别名,可以为Java类型设置一个短的名字,方便在Mybatis映射文件中使用
environments: 环境配置,可以为不同的环境(如开发、测试、生产)配置不同的数据库连接和事务管理器
mappers: 映射器配置,Mybatis会自动扫描指定包下的所有映射器接口和映射文件
1)SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="jdbc.properties"/>
<typeAliases>
<package name="com.example.domain"/>
</typeAliases>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="com.example.dao"/>
</mappers>
</configuration>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2)App.java
import com.example.dao.AccountDao;
import com.example.domain.Account;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class App {
public static void main(String[] args) throws IOException {
// 1. 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 2. 加载SqlMapConfig.xml配置文件
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 3. 创建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
// 4. 获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 5. 执行SqlSession对象执行查询,获取结果User
AccountDao accountDao = sqlSession.getMapper(AccountDao.class);
Account ac = accountDao.findById(1);
System.out.println("app");
System.out.println(ac);
// 6. 释放资源
sqlSession.close();
}
}
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
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
# 2、Java配置方式:法2
1)config/SpringConfig.java
@Configuration
- 声明当前类是一个配置类,该类应包含在Spring应用上下文中如何初始化和装配Bean的细节
@ComponentScan("com.example")
置Spring在初始化时自动扫描的包路径,"com.example"表示会扫描这个包及其子包下的所有类,并根据类中的注解自动创建和注册Bean
@PropertySource("classpath:jdbc.properties")
- 用于导入其他的配置类,JdbcConfig.class和MybatisConfig.class表示需要导入的配置类
- 通过这种方式,可以把配置分散在不同的配置类中,然后通过@Import注解将它们组合在一起,这样可以使配置更加模块化
@Import({JdbcConfig.class,MybatisConfig.class})
- 声明一个公共类SpringConfig,这个类就是Spring的Java配置类,用于配置Spring上下文
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.example") //指定自动扫描的包路径
@PropertySource("classpath:jdbc.properties") //指定属性文件路径
@Import({JdbcConfig.class,MybatisConfig.class}) //用于导入其他的配置类
//这个类就是Spring的Java配置类,用于配置Spring上下文
public class SpringConfig {
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
2)config/MybatisConfig.java
- 该方法被
@Bean注解
,所以Spring会调用这个方法并把返回的对象注册到Spring容器中
- 方法的
参数是DataSource对象
,Spring会自动把配置好的DataSource Bean注入进来
- 该方法被
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,SqlSessionFactoryBean,用于产生SqlSessionFactory对象
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
//设置别名包,MyBatis会把这个包下的所有类自动注册为别名
ssfb.setTypeAliasesPackage("com.example.domain");
ssfb.setDataSource(dataSource);
//设置数据源,MyBatis会使用这个数据源进行数据库操作
return ssfb;
}
//定义bean,返回MapperScannerConfigurer对象
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
//设置基础包,MyBatis会把这个包下的所有接口自动注册为Mapper接口
msc.setBasePackage("com.example.dao");
return msc;
}
}
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
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
3)config/JdbcConfig.java
import com.alibaba.druid.pool.DruidDataSource;
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(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
}
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
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
4)App2.java
import com.example.config.SpringConfig;
import com.example.domain.Account;
import com.example.service.AccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class App2 {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
AccountService accountService = ctx.getBean(AccountService.class);
Account ac = accountService.findById(1);
System.out.println("app2");
System.out.println(ac);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 3、两种方法比较
- 1)使用SqlSessionFactoryBean封装SqlSessionFactory需要的环境信息
- 2)使用MapperScannerConfigurer加载Dao接口,创建代理对象保存到IOC容器中
上次更新: 2024/5/31 11:18:42