1. 概念相关
框架的学习思路
- 了解框架的作用
- 会用框架
- 有哪些配置(重点、难点)
- 少量API
- 懂:学习其中原理
- 咬牙坚持配的多了;自然就会了,记不住(live template)(笔记)
学习安排
SSM
- S - Spring - 每一层
- S - SpringMVC - WEB
- M - Mybatis - DAO
Spring
- IoC AOP 两大核心思想
- 2天 IoC
- 2天AOP
- 源码分析
SpringMVC
- 3天
- 融合了所有web核心的技术点
Spring概念
- Spring之父 Rod Johnson
- EJB
Enterprise Java Bean
,sun公司提出来的大型web项目的架构 - Expert One-on-One J2EE Design and Development 2002年 手把手教你怎么使用EJB开发大型web项目
- Expert one-on-one J2EE Development without EJB 2004 手把手教你怎么不使用EJB开发大型web项目 (Spring的原型)
- 官网:https://spring.io/projects
- 课堂版本5.x
- EJB
Spring架构
Spring优势
-
方便解耦,简化开发
-
方便集成各种优秀框架(不排斥、慢慢整合)
-
AOP(面向切面编程)编程的支持
-
声明式事务的支持
-
Java源码是经典学习范例
-
方便程序的测试(Spring整合junit)
Spring两大核心思想
- IoC:Inverse of Control 控制反转
- AOP:Aspect Oriented Programming 面向切面编程
IoC
-
内聚耦合
内聚:
耦合:
-
Spring演化过程
基于接口编程:service和dao之间高度耦合
基于工厂:解除service和dao之间的耦合,但是带来的工厂和dao的耦合
工厂+配置文件:解除了耦合,留下配置文件和dao/工厂耦合,这种耦合是我们期望的一种耦合方式
-
IoC 控制反转
把对象的创建权从程序员自己new反转到了Spring容器创建并提供
2. Spring入门案例
2.1 配置依赖坐标
<dependencies><!--配置Spring的依赖坐标会根据依赖传传递自动导入其依赖的其他坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.9.RELEASE</version></dependency>
</dependencies>
2.2 编写service/dao实现类和接口,service实现类中main方法测试
2.3 新建Spring的配置文件并配置
resources 右键 选择 new--》xml configration file --》Spring config(前提是Spring的依赖已经成功导入)
配置文件名称任意,习惯写法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装配进Spring容器id 唯一标识,任意起名,但是尽量使用提示的名字class 全限定类名(用于反射创建对象)--><bean class="com.itheima.dao.impl.UserDaoImpl" id="userDao"/>
</beans>
2.4 创建Spring容器对象并获取bean对象
public class UserServiceImpl {
public static void main(String[] args) {
// 创建容器对象,并加载配置文件ApplicationContext app = new ClassPathXmlApplicationContext("classpath:beans.xml");// 从容器对象中获取bean对象UserDao userDao = (UserDao) app.getBean("userDao");// 使用获取的bean对象List<User> allUser = userDao.getAllUser();}
}
3. Spring配置-Bean标签
3.1 id&class属性
id:唯一标识,同一个Spring容器中不允许重复
class:全限定类名,用于反射创建对象
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装配进Spring容器id 唯一标识,任意起名,但是尽量使用提示的名字class 全限定类名(用于反射创建对象)--><bean class="com.itheima.dao.impl.UserDaoImpl" id="userDao"/>
</beans>
测试代码
public class UserServiceImpl {
public static void main(String[] args) {
// 创建容器对象,并加载配置文件ApplicationContext app = new ClassPathXmlApplicationContext("classpath:beans.xml");// 从容器对象中获取bean对象UserDao userDao = (UserDao) app.getBean("userDao");// 使用获取的bean对象List<User> allUser = userDao.getAllUser();}
}
3.2 name属性(了解)
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装配进Spring容器bean可以定义多个名称,使用name属性完成,中间使用,分割--><bean id="userService" name="userService1,userService2" class="com.itheima.service.impl.UserServiceImpl"/>
</beans>
测试代码
public class UserServiceImpl {
public static void main(String[] args) {
// 创建容器对象,并加载配置文件ApplicationContext app = new ClassPathXmlApplicationContext("classpath:beans.xml");// 从容器对象中获取bean对象UserDao userDao = (UserDao) app.getBean("userDao");// 使用获取的bean对象List<User> allUser = userDao.getAllUser();}
}
3.3 scope(重要但不需要配置)
控制Spring容器中的bean时单例还是多例的,默认单例,也是推荐的配置。
XML配置beans-scope.xml
<bean class="com.itheima.domain.User" id="user2" scope="singleton"/>
<bean class="com.itheima.domain.User" id="user1" scope="prototype"/>
类的单例和Spring中Bean的单例的区别
项目 | 类的单例 | Spring中Bean的单例 |
---|---|---|
概念 | 同一个软件项目中,某个类的实例有且只能有一个 | 整个Spring容器中,某个Bean的实例有且只能有一个 |
范围 | 整个项目 | 项目中的Spring容器 |
注意点 | 一个类最多只能有一个实例 | 一个Bean标签最多只能有一个实例。 但是多个Bean标签可以配置相同的class属性值,所以Spring中单例Bean对应的一个类可以有多个实例 |
<bean id="userService3" scope="singleton" class="com.itheima.service.impl.UserServiceImpl"/>
<bean id="userService33" scope="singleton" class="com.itheima.service.impl.UserServiceImpl"/>
测试代码
// 需求1:测试单例和多例的Bean分别在什么时候创建,请在beans_scope.xml配置并完成测试
// Spring会在创建Spring容器的时候创建所有单例的Bean
@Test
public void test01() {
app = new ClassPathXmlApplicationContext("beans-scope.xml");User user1 = (User) app.getBean("user1");User user3 = (User) app.getBean("user1");User user2 = (User) app.getBean("user2");System.out.println(user1 == user3);System.out.println(user1 == user2);Object book = app.getBean("book");Object book2 = app.getBean("book");System.out.println("book = " + book);System.out.println("book2 = " + book2);}
结论:
Spring容器在创建的时候,只会初始化并装配所有单例Bean。
3.4 lazy-init
思想重要,配置不重要
结论:Spring容器在创建的时候,只会初始化并装配所有非懒加载的单例Bean。
XML配置beans-lazy.xml
<bean class="com.itheima.domain.User" id="user" scope="singleton" lazy-init="true"/>
测试代码
// 需求2:单例Bean能不能在我们获取使用的时候再创建?如果可以请在beans_lazy.xml文件中配置并完成测试
// Spring会在初始化Spring容器的时候创建所有非懒加载的单例Bean
@Test
public void test02() {
app = new ClassPathXmlApplicationContext("beans-lazy.xml");User user = (User) app.getBean("user");User user1 = (User) app.getBean("user");
}
3.5 depends-on(了解)
XML配置beans-order.xml
<!-- 把 user book car 装配进Spring容器1. 默认情况下,Bean标签的配置顺序就是实例化顺序2. 通过配置depends-on属性,调整顺序;会先实例化属性中的bean,再实例化当前bean注意:这里仅仅是调整了bean的实例化顺序,无他。--><bean class="com.itheima.domain.Car" id="car" depends-on="user,book"/><bean class="com.itheima.domain.Book" id="book"/><bean class="com.itheima.domain.User" id="user"/>
测试代码
// 需求3:请按照User、Book、Car的顺序实例化三个Bean,请在beans-order.xml中配置并完成测试
@Test
public void test03() {
app = new ClassPathXmlApplicationContext("beans-order.xml");
}
其他代码
public class User {
public User(){
System.out.println("User创建成功……");}
}
public class Book {
public Book() {
System.out.println("Book创建成功……");}
}
public class Car {
public Car() {
System.out.println("汽车创建成功……");}
}
3.6 init-method&destroy-mehtod(理解)
配置bean对象初始化的方法和销毁的方法
注意:
-
提前准备好两个方法,方法名任意 xxx yyy
<bean id="userDao" class="com.itheima.dao.UserDao" init-method="xxx" destroy-method="yyy">
-
属性值不用带小括号
-
多例bean的生命周期不归Spring容器管理
3.7 对象的创建方式
Java中
public void test01(){
// 1. 直接new 创建对象User user = new User();System.out.println("user = " + user);// 2. 通过工厂实例获取一个car对象CarFactory carFactory = new CarFactory();Car car = carFactory.getCar();System.out.println("car = " + car);Car car1 = carFactory.getCar();System.out.println("car1 = " + car1);// 3. 通过工厂静态方法获取一个car对象Car car2 = StaticCarFactory.getCar();System.out.println("car2 = " + car2);Car car3 = CarFactoryStatic.getCar();System.out.println("car3 = " + car3);
}
Spring中
无参构造
User user = new User();
对应Spring中配置
<bean id="user" class="com.itheima.daomian.User">
工厂实例
CarFactory carFactory = new CarFactory();
Car car = carFactory.getCar();
对应Spring中配置
<!-- 把CarFactory装配进Spring容器,创建CarFactory对象 -->
<bean id="carFactory" class = "com.itheima.facotry.CarFactory"/>
<!-- 通过CarFactory对象,获取car对象 -->
<bean id="car" factory-bean="carFactory" factory-method="getCar">
工厂静态
Car car = StaticCarFactory.getCar();
对应Spring中配置
<!-- 通过CarFactory的静态发昂发,获取car对象 -->
<bean id="car" class = "com.itheima.facotry.StaticCarFactory" factory-method="getCar">
3.8 factory-bean& factory-method
用于指定工厂bean(容器中已经存在的一个bean)或者工厂中的创建对象的方法
3.9 工厂方式创建对象使用场景:
当某些对象的创建过程非常复杂(耗时、内存、性能)的时候,优先使用工厂的方式。
3.10 IoC思想总结
IOC
控制反转
控制:对象的创建权
反转:反转的就是对象的创建权
把对象的创建权
从程序员自己new的方式,反转成了spring读取配置文件并创建的方式。
我们如果需要使用,直接找Spring容器获取即可。
4. 依赖注入
4.1 概念
依赖:在A类中用到了B类,就说A依赖B;
依赖注入:Spring会把B类对象自动注入到A类中B类型的属性上,这就是依赖注入。Dependency Injection,DI。
// 伪代码演示
class A{
// 自动为B类型的b变量初始化的过程,称为依赖注入B b = null;
}
依赖注入可以理解成IoC
的一种应用场景,反转的是对象间依赖关系维护权
。
4.2 IoC和DI的关系(面试题)
IoC是一种思想(规范),可以把对象的创建权、对象间依赖关系的维护权等从程序员手中,反转到了Spring容器中;
DI依赖注入,只是IoC在某个方面的一个具体实现,在 依赖关系维护 方面的一个实现。
4.3 注入方式
本质上就是为某个类的成员变量赋值的方式:setter/有参构造
/*1. 直接为成员变量赋值,(成员变量一般都是private,不能被直接访问)----不推荐2. 提供有参构造方法,通过构造方法在创建对象的同时为成员变量赋值3. 提供setter,通过setter为成员变量赋值 */
4.4 Setter方式注入
-
保证两个bean都已经装配到Spring容器
<bean id="userDao" class="com.itheima.dao.impl.UserDao"/> <bean id="userService" class="com.itheima.dao.impl.UserServiceImpl"/>
-
在UserServiceImpl类中添加UserDao的属性并提供setter
class UserServiceImpl{ private UserDao xxx;// 属性指的是通过getter/setter方法名截取得到的,与成员变量名无关// 这个案例中,成员变量名就叫做userDao,和xxx、yyy无关public void setUserDao(UserDao yyyy){ this.xxx = yyyy;}// 非Spring容器中存在的bean---普通类型private Integer num;public void setNum(int num1){ this.num = num1;} }
-
通过
<property>
子标签完成注入<bean id="userDao" class="com.itheima.dao.impl.UserDao"/> <bean id="userService" class="com.itheima.dao.impl.UserServiceImpl"><!-- name属性名,通过getter/getter截得ref 当前Spring容器中已经存在的bean的id值--><property name="userDao" ref=“userDao”/><!-- 注入普通类型(基本类型<包括其包装类> + String) 不是ref,而是使用value;都要有有settter--><property name="num" value=“666”/> </bean>
?
4.5 p标签注入(本质是property)(了解)
需要导入p命名空间,写完p: + Alter&Enter
<bean class="com.itheima.service.impl.UserServiceImpl" id="userService"p:userDao-ref="userDao" p:num="666">
</bean>
对应Java代码
public class UserServiceImpl implements UserService {
UserDao xxx;public void setUserDao(UserDao yyyy) {
this.xxx = yyyy;}private Integer num;public void setNum(Integer num) {
this.num = num;}
}
4.6 构造方法注入(了解)
public class UserServiceImpl implements UserService {
private UserDao userDao;private int num;private String version;public UserServiceImpl(UserDao userDao, int num, String version){
this.userDao = userDao;this.num = num;this.version = version;}
}
如果要使用构造器注入,建议使用name+ref/value,index/type不要用
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl"><!--;使用构造方法进行注入,需要保障注入的属性与bean中定义的属性一致一致指顺序一致或类型一致或使用index解决该问题 --><!-- 推荐使用name + ref/value方式,见名知意好维护 --><constructor-arg name="userDao" ref="userDao"/><constructor-arg name="num" value="666666"/><constructor-arg name="version" value="itcast"/>
</bean>
<!-- 下面的配置会默认找无参构造创建对象,如果没有无参构造,会报错 -->
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
4.7 C标签注入(本质是构造器注入)(了解)
需要导入c命名空间,写完c: + Alter&Enter
<bean class="com.itheima.service.impl.UserServiceImpl" id="userService" c:num="777"c:xxx-ref="userDao"/>
4.8 集合注入(了解)
<bean class="com.itheima.domain.Book" id="book1"><property name="bookName" value="Java编程思想"/>
</bean><bean class="com.itheima.domain.Book" id="book2"><property name="bookName" value="新Java编程思想"/>
</bean><bean id="birth" class="java.util.Date"/><bean id="bmw" class="com.itheima.domain.Car"><property name="band" value="BMW"/>
</bean><!--单例集合 list set array配置通用 ,建议使用list双列集合 map properties配置通用 ,建议使用Map --><bean class="com.itheima.domain.User" id="user" ><property name="username" value="张三"/><property name="age" value="28"/><!--<property name="birthday" ref="birth"/>--><property name="birthday" ><bean class="java.util.Date" /></property><property name="car" ref="bmw"/><!-- 书单 --><property name="bookList"><list><ref bean="book1"></ref><bean class="com.itheima.domain.Book" ><property name="bookName" value="Java从入门到精通"/></bean><bean class="com.itheima.domain.Book"p:bookName="Effective Java"/><bean class="com.itheima.domain.Book" p:bookName="深入理解Java虚拟机"/><bean class="com.itheima.domain.Book" p:bookName="颈椎病诊疗与自我康复"/></list></property><!-- 昵称 --><property name="nikeNameSet"><list><value>程序员</value><value>Programmer</value><value>软件工程师</value><value>码农</value><value>IT民工</value><value>修电脑的</value></list></property><!-- 书单2--><property name="shelfMap"><props><prop key="111">2222</prop></props></property><!--书单3--><property name="bookProp"><map><entry key="技术" value="程序员的自我修养"/><entry key="生活" value="认识身体"/><entry key="思维" value="刻意练习"/><entry key="理财" value="从零开始学炒股"/><entry key="思维" value="刻意练习"/><entry key="娱乐" value="别做正常的傻瓜"/></map></property>
</bean>
4.9 SpEL
Spring Expression Language
简单,但是功能强大
<?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:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.itheima.domain.Car" id="car" p:color="红"><property name="band" value="BMW"></property></bean><bean class="com.itheima.domain.User" id="user1" p:age="18"></bean><!--[SpEL] Spring Expression LanguageSpring中的支持运行时查询和操作对象图的强大的表达式语言,语法类似于el。与EL类似,但是用法不同EL 是从域中取值 ${}SpEL 是从Spring容器中取值 #{}SpEl可以用在1. 配置文件中2. @Value("#{}")//3. 用在代码中(需要解析器)在SpEL可以操作内容字面值常量、引用其他bean、引用其他bean的某个属性值、调用非静态方法#{对象.非静态方法(参数列表)}调用静态方法#{T(全类名).静态方法(参数列表)}使用运算符-->
<!--<bean class="java.util.Date" id="date"/> --><bean class="com.itheima.domain.User" id="user"><property name="age" value="#{18-1}"/><property name="car" value="#{car}"/><property name="birthday" value="#{new java.util.Date()}"/><property name="userId" value="#{T(java.util.UUID).randomUUID().toString()}"/></bean>
</beans>
5. 引入properties文件
5.1 创建properties文件 jdbc.properties
# 不要使用username,否则会错误的获取到当前系统的用户名。建议使用jdbc.username
jdbc.username=root
pwd=123321
5.2 beans.xml
文件引入 jdbc.properties
文件
<!-- 在类路径下加载指定名称的properties配置文件 -->
<context:property-placeholder location="classpath:data.properties"/>
<!-- 在类路径下加载所有的properties配置文件 -->
<context:property-placeholder location="classpath:*.properties"/>
<!-- 在类路径+jar包中(整个项目下)加载所有的properties配置文件统配会造成效率降低,速度变慢-->
<context:property-placeholder location="classpath*:*.properties"/><!--${} 所有的框架都支持这个种写法,从当前容器对象中根据key获取值#{} SpELl********Spring容器会把当前系统的内置变量整合进自己的容器 username=当前系统的用户名${username} 会获取当前系统的用户名-->
<bean class="com.itheima.dao.impl.UserDaoImpl" id="userDao"><property name="userName" value="${jdbc.username}"/><property name="password" value="${pwd}"/>
</bean>
5.3 代码测试
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
UserDao userDao = (UserDao) ctx.getBean("userDao");
userDao.save();
6. 引入xml格式的Spring配置文件
配置文件拆分
- 按照模块拆分 : user / book / xxx
- 按照层级拆分:web / service /dao
xx**plicationContext.xml
<!--所有的配置都写在一个配置文件中,会造成该文件很臃肿,不易管理。所以可以把配置文件拆分,然后再主的配置文件中引入其他分的Spring配置文件分层配置daoserviceweb分模块配置userbookorder在主的配置文件中通过import标签的resource属性,引入其他的分配置文件或者在创建Spring容器对象的时候,一次性指定多个配置文件(此时没有主配置文件的概念)-->
<!-- <import resource="classpath:applicationContext-user.xml"/><import resource="classpath:applicationContext-book.xml"/><import resource="classpath:applicationContext-book2.xml"/>--><bean class="com.itheima.dao.impl.UserDaoImpl" id="userDao"><property name="userName" value="${jdbc.username}"/><property name="password" value="${pwd}"/></bean>
applicationContext-user.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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"><property name="userName" value="${jdbc.username}"/><property name="password" value="${pwd}"/></bean><bean id="userService" class="com.itheima.service.impl.UserServiceImpl"><property name="userDao" ref="userDao"/></bean>
</beans>
测试类
public class UserApp {
public static void main(String[] args) {
//ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-user.xml","applicationContext.xml");UserService userService = (UserService) ctx.getBean("userService");userService.save();}
}
注意:
- 一个Spring核心配置文件中不能出现两个相同id的bean
- 多个Spring核心配置文件,如果出现了相同id的bean,后面的会覆盖前面的
7. ApplicationContext体系
/* ├─ BeanFactory├─xxxx ..... ├─ ApplicationContext│ ├── yyy.....│ │ ├── ClassPathXmlApplicationContext 类路径│ │ ├── FileSystemXmlApplicationContext 文件系统└─ zzzz....├── AnnotationConfigApplicationContext 注解 */
BeanFactory & ApplicationContext区别
- 懒加载
8. Spring整合Mybatis
8.1 导入依赖坐标
pom.xml
<!-- 配置私服 --><!-- 配置各个依赖 -->
<dependencies><!-- spring --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.9.RELEASE</version></dependency><!-- spring-jdbc --><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.1.9.RELEASE</version></dependency><!-- mybatis整合Spring的依赖 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.0</version></dependency><!-- mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.3</version></dependency><!-- mysql 数据库驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><!-- druid数据源 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.16</version><scope>provided</scope></dependency><!-- junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies>
8.2 Spring配置文件
- 导入外部的properties文件
- 装配DruidDataSource
- 装配AccountDao(不需要我们自己搞)、AccountService接口的实现类
- 整合Mybatis核心配置文件
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"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd"><!--加载perperties配置文件的信息--><context:property-placeholder location="classpath:jdbc.properties"/><!--装配DruidDataSource进Spring容器--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!--accountDao不需要我们自己创建并装配进Spring容器使用Mybatis,他会根据接口和映射配置文件,动态生成接口的代理对象并装配进Spring容器;这个代理对象就是我们要使用的accountDao对象--><!--配置service作为spring的bean,注入daoref 引用的是mybatis动态生成的accountDao代理对象,该对象的id默认为接口名--><bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"/></bean><!--SqlSessionFactoryBean:创建SqlSession的工厂的Beanspring整合mybatis后,可以使用该bean创建SqlSession,并最终获取到代理对象accountDao该bean对象 依赖数据源 所以注入druidDataSource之前在mybatis核心配置文件中的大部分内容,都是通过set方法注入的方式配置在该Bean中id可以省略不写,Spring会根据bean的类型自动查找到该Bean--><bean class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/><property name="typeAliasesPackage" value="com.itheima.domain"/></bean><!--MapperScannerConfigurer:映射的扫描配置,从哪个位置加载映射配置文件,并且装配到Spring容器中id可以省略不写,Spring会根据bean的类型自动查找到该Bean。--><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.itheima.dao"/></bean>
</beans>
8.3 数据库连接参数配置
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_db
jdbc.username=root
jdbc.password=itheima
8.4 POJO
Account.java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Account /* implements Serializable */ {
private Integer id;private String name;private Double money;
}
8.5 dao层接口和配置文件
AccountDao.java
public interface AccountDao {
void save(Account account);void delete(Integer id);void update(Account account);List<Account> findAll();Account findById(Integer id);
}
AccountDao.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.dao.AccountDao"><!--配置根据id查询--><select id="findById" resultType="account" parameterType="int">select * from account where id = #{id}</select><!--配置查询所有--><select id="findAll" resultType="account">select * from account</select><!--配置保存--><insert id="save" parameterType="account">insert into account(name,money)values(#{name},#{money})</insert><!--配置删除--><delete id="delete" parameterType="int">delete from account where id = #{id}</delete><!--配置更新--><update id="update" parameterType="account">update account set name=#{name},money=#{money} where id=#{id}</update>
</mapper>
8.6 service层接口&实现类
AccountService.java
public interface AccountService {
void save(Account account);void delete(Integer id);void update(Account account);List<Account> findAll();Account findById(Integer id);
}
AccountServiceImpl.java
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao;// 提供setter,方便注入public void setAccountDao(AccountDao accountDao) {
this.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();}
}
8.7 测试类
App.java
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");AccountService accountService = (AccountService) ctx.getBean("accountService");Account ac = accountService.findById(2);System.out.println(ac);// Account account = new Account();
// account.setName("Tom");
// account.setMoney(123456.78);
//
// accountService.save(account);
9. getBean相关API
-
Object getBean(“beanName”)
根据beanName(beanId)从spring容器中获取对象;只有存在对应的beanId,就可以获取成功;但是返回值为Object类型,需要强制类型转换
-
T getBean(Class<T> requiredType )
根据class对象类型,从Spring容器中获取对象,不需要强制转换;但是,如果存在多个相同类型的对象,会报错:
NoUniqueBeanDefinitionException: No qualifying bean of type 'com.itheima.service.AccountService' available: expected single matching bean but found 2: accountService1,accountService2
-
T getBean(String beanName, Class<T> requiredType )
根据class对象类型 + beanId,从Spring容器中获取对象,不需要强制转换;但是,如果存在多个相同类型的对象,按照类型匹配之后,在根据beanId进行匹配,找到即返回。
10. 相关概念梳理
10.1 类&Bean(spring中的bean)
Java中最小的单位:类
Spring中最小的单位:Bean
10.2 JavaBean & POJO
都是用于封装并且传递数据的,VO、TO、DO……
JavaBean
- sun公司提出规范,为了规范数据传输的载体
- 类必须有一个无参构造
- 成员变量必须有getter/setter
- 可以序列化的,必须实现seriazable
- 有关图形化(GUI)内容,必须符合swing相关规范
POJO(普通的java类,Plain Ordinary Java Object)
- 阿里巴巴编码规约中表示,有成员变量及相关getter/setter/toString方法的类称之为POJO
args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(“applicationContext.xml”);
AccountService accountService = (AccountService) ctx.getBean(“accountService”);
Account ac = accountService.findById(2);
System.out.println(ac);
// Account account = new Account();
// account.setName(“Tom”);
// account.setMoney(123456.78);
//
// accountService.save(account);
## 9. getBean相关API- Object getBean("beanName")根据beanName(beanId)从spring容器中获取对象;只有存在对应的beanId,就可以获取成功;但是返回值为Object类型,需要强制类型转换- T getBean(Class\<T\> requiredType )根据class对象类型,从Spring容器中获取对象,不需要强制转换;但是,如果存在多个相同类型的对象,会报错:```shellNoUniqueBeanDefinitionException: No qualifying bean of type 'com.itheima.service.AccountService' available: expected single matching bean but found 2: accountService1,accountService2
-
T getBean(String beanName, Class<T> requiredType )
根据class对象类型 + beanId,从Spring容器中获取对象,不需要强制转换;但是,如果存在多个相同类型的对象,按照类型匹配之后,在根据beanId进行匹配,找到即返回。
10. 相关概念梳理
10.1 类&Bean(spring中的bean)
Java中最小的单位:类
Spring中最小的单位:Bean
10.2 JavaBean & POJO
都是用于封装并且传递数据的,VO、TO、DO……
JavaBean
- sun公司提出规范,为了规范数据传输的载体
- 类必须有一个无参构造
- 成员变量必须有getter/setter
- 可以序列化的,必须实现seriazable
- 有关图形化(GUI)内容,必须符合swing相关规范
POJO(普通的java类,Plain Ordinary Java Object)
- 阿里巴巴编码规约中表示,有成员变量及相关getter/setter/toString方法的类称之为POJO