base黑马,视频链接:https://www.bilibili.com/video/BV1WZ4y1P7Bp?t=94.4
此系列文章可以当做视频的配套笔记,也可以当做自学SSM框架的教程。
Spring配置数据源-数据源的作用
Spring配置数据源-数据源开发步骤
Spring配置数据源-数据源的开发步骤和手动创建C3P0数据源
1、导入相应的坐标
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.10</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
2、创建测试类进行测试:
package com.lyh.test;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import java.sql.Connection;
public class DataSourceTest {
//测试手动创建c3p0数据源
@Test
public void test1() throws Exception {
//创建c3p0的对象
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//设置基本的连接参数
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ssm1");
dataSource.setUser("root");
dataSource.setPassword("1234");
//获取资源
Connection connection = dataSource.getConnection();
System.out.println(connection); //打印一下证明不是空的
//关闭 表面上是关闭,实际上是归还
connection.close();
}
}
3、结果
Spring配置数据源-手动创建Druid数据源
1、导入相关的坐标,上面的例子中已经导入了
2、创建测试类进行测试
//测试手动创建Druid数据源
@Test
public void test2() throws Exception {
//创建Druid的对象
DruidDataSource dataSource = new DruidDataSource();
//设置基本的连接参数
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/ssm1");
dataSource.setUsername("root");
dataSource.setPassword("1234");
//获取资源
DruidPooledConnection connection = dataSource.getConnection();
System.out.println(connection);
//关闭 表面上是关闭,实际上是归还
connection.close();
}
3、结果
Spring配置数据源-抽取jdbc.properties文件
为了降低耦合度,创建配置文件 xx.properties,xx.xml文件也是可以的,但是xml文件的解析是比较费劲的。
在resources文件下面建立一个jdbc.properties文件(名字叫什么都行,a.properties、b.properties、c.properties)
这样是为了让具体的字符串设置与数据源解耦合。
jdbc.properties 文件中的内容
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm1
jdbc.username=root
jdbc.password=1234
编写测试,在创建对象的时候读取properties配置文件
//测试手动创建c3p0数据源(加载properties配置文件)
@Test
public void test3() throws Exception {
//读取配置文件 用ResourceBundle 来 读取配置文件 ResourceBundle 是 java提供的工具
//getBundle()需要的参数是 baseName 是基本名称,简称基名
//getBundle()里面的参数 是 相对于 类加载路径的地址
//在开发环境下就是相对于resources下面的路径
//resources下面的内容 都在 类加载路径下
//getBundle()需要的参数 不需要扩展名 因为 是 专门对 properties进行读取的
//所以写jdbc就可以
ResourceBundle resourceBundle = ResourceBundle.getBundle("jdbc");
//进行赋值
String driver = resourceBundle.getString("jdbc.driver");
String url = resourceBundle.getString("jdbc.url");
String username= resourceBundle.getString("jdbc.username");
String password = resourceBundle.getString("jdbc.password");
//创建数据源对象
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
//设置连接参数
comboPooledDataSource.setDriverClass(driver);
comboPooledDataSource.setJdbcUrl(url);
comboPooledDataSource.setUser(username);
comboPooledDataSource.setPassword(password);
//获取资源
Connection connection = comboPooledDataSource.getConnection();
System.out.println(connection);
//关闭资源,资源归还到数据源中
connection.close();
}
结果:
抽取配置文件的目的是方便解耦,因为代码后期会进行编译,编译之后在打完的包中,看到的就是字节码文件,字节码文件是看不懂的,但是配置文件开发阶段长什么样子,最终还是长的什么样子。方便修改。
Spring配置数据源-Spring产生数据源对象
C3P0 或者 Druid 不是自己定义的,因为这个是导入第三方.jar包,像这种第三方的bean也是可以让Spring进行配置的。
Spring 是通过无参构造 帮忙创建对象,最简单的注入有set方法注入和有参构造注入。
//创建c3p0的对象
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//设置基本的连接参数
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ssm1");
dataSource.setUser("root");
dataSource.setPassword("1234");
上面的代码,正好满足通过Spring创建bean(对象)的条件
可以将DataSource的创建权交给Spring容器去完成
搭建Spring的环境
导入坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
创建配置文件 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 id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ssm1"/>
<property name="user" value="root"/>
<property name="password" value="1234"/>
</bean>
</beans>
测试代码:
//测试Spring容器产生数据源对象
@Test
public void test4() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext1.xml");
DataSource dataSource = applicationContext.getBean("dataSource",DataSource.class);
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
结果:
Spring配置数据源-Spring加载properties文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 加载外部的 properties文件-->
<!-- 引入context,目前而言通过context下面的标签加载-->
<!-- 要加载的文件 properties 在resources目录下 在类加载路径下 所以用 classpath-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 现在已经把 properties文件 加载到spring容器内部了-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 这里用的是 spel、spring表达式 -->
<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>
</beans>
测试代码
//Spring加载properties文件
@Test
public void test4() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext1.xml");
DataSource dataSource = applicationContext.getBean("dataSource",DataSource.class);
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
结果:
Spring注解开发-原始注解介绍
Spring注解开发-完善测试环境
创建Dao层的接口
package com.lyh.dao;
public interface UserDao {
public void save();
}
创建Dao层的实现
package com.lyh.dao.impl;
import com.lyh.dao.UserDao;
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("save方法执行了。。。");
}
}
创建Service层的接口
package com.lyh.service;
public interface UserService {
public void save();
}
创建Service层的实现
package com.lyh.service.impl;
import com.lyh.dao.UserDao;
import com.lyh.service.UserService;
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
创建Spring的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 加载外部的 properties文件-->
<!-- 引入context,目前而言通过context下面的标签加载-->
<!-- 要加载的文件 properties 在resources目录下 在类加载路径下 所以用 classpath-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 现在已经把 properties文件 加载到spring容器内部了-->
<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>
<bean id="userDao" class="com.lyh.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.lyh.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
</beans>
创建UserController类
package com.lyh.web;
import com.lyh.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserController {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext1.xml");
UserService userService = app.getBean("userService",UserService.class);
userService.save();
}
}
结果:
Spring注解开发-原始注解入门操作
Dao层里面的注解
package com.lyh.dao.impl;
import com.lyh.dao.UserDao;
import org.springframework.stereotype.Component;
//<bean id="userDao" class="com.lyh.dao.impl.UserDaoImpl"/>
@Component("userDao")
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("save方法执行了。。。");
}
}
Service层里面的注解
package com.lyh.service.impl;
import com.lyh.dao.UserDao;
import com.lyh.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
//<bean id="userService" class="com.lyh.service.impl.UserServiceImpl">
@Component("userService")
public class UserServiceImpl implements UserService {
// <property name="userDao" ref="userDao"/>
@Autowired//自动注入
@Qualifier("userDao")
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
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/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 加载外部的 properties文件-->
<!-- 引context目前而言通过context下面的标签加载-->
<!-- 要加载的文件 properties 在resources目录下 在类加载路径下 所以用 classpath-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 现在已经把 properties文件 加载到spring容器内部了-->
<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>
<!-- 虽然把注解配到这里了得告诉Spring-->
<!-- 组件扫描的作用是告诉Spring,
在那个包下面的bean需要Spring进行扫描
从而扫到对应的注解帮忙创建对象-->
<!-- 所以得配置组件扫描-->
<context:component-scan base-package="com.lyh"/>
<!-- 扫描基础包 及其子包-->
</beans>
测试代码
package com.lyh.web;
import com.lyh.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserController {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = app.getBean("userService",UserService.class);
userService.save();
}
}
效果:
Spring注解开发-原始注解详解1
UserDaoImpl中注解的解释
package com.lyh.dao.impl;
import com.lyh.dao.UserDao;
import org.springframework.stereotype.Repository;
//<bean id="userDao" class="com.lyh.dao.impl.UserDaoImpl"/>
//@Component("userDao")
@Repository("userDao") //使用语意更加明确的 @Repository 注解 和 @Component作用一样 只是增加了语意
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("save方法执行了。。。");
}
}
UserServiceImpl中注解的解释
package com.lyh.service.impl;
import com.lyh.dao.UserDao;
import com.lyh.service.UserService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
//<bean id="userService" class="com.lyh.service.impl.UserServiceImpl">
//@Component("userService")
@Service("userService")
public class UserServiceImpl implements UserService {
// <property name="userDao" ref="userDao"/>
//自动注入
// 如果只是单独写上 @Autowired注解的话
// 是按照数据类型从Spring容器中进行匹配的
//当Spring扫描到这个注解之后 会 尝试着从 Spring容器中找一个UserDao类型的bean 直接注入
//@Autowired
//@Qualifier("userDao") //是按照 id值从容器中进行匹配 但是 此处@Qualifier要结合@Autowired一起使用
@Resource(name="userDao") //网上有人说这个是jdk9的新特性 就是换到jdk8可以 但是 jdk11就不行
//@Resource 就相当于 @Qualifier + @Autowired
private UserDao userDao;
//如果使用的是xml配置的方式 set方法是要写的
//如果使用的是注解的方式 set方法可以省略不写
// public void setUserDao(UserDao userDao) {
// this.userDao = userDao;
// }
@Override
public void save() {
userDao.save();
}
}
Spring注解开发-原始注解详解2
普通数据类型的注入:
@Value("itcast")
private String driver;
在applicationContext.xml配置文件中
<context:property-placeholder location="classpath:jdbc.properties"/>
加载外部的properties文件到Spring容器中,把properties的键值对放到了Spring容器中了
//spel表达式 直接到Spring容器中找对应的key,key如果匹配成功,就把key的值赋值给driver
@Value("${jdbc.driver}")
private String driver;
效果:
@Scope注解
@Scope("prototype") //多例
//@Scope("singleton") //单例
public class UserServiceImpl implements UserService {
}
创建 初始化方法 和 销毁方法 以及注解
@PostConstruct //初始化注解 构造之后
public void init(){
System.out.println("Service对象的初始化方法。。。");
}
@PreDestroy //销毁方法 销毁之前
public void destroy(){
System.out.println("Service对象的销毁方法。。。");
}
测试
package com.lyh.web;
import com.lyh.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserController {
public static void main(String[] args) {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = app.getBean("userService",UserService.class);
userService.save();
app.close();
}
}
效果:
Spring注解开发-新注解介绍
原始注解对于非自定义的bean就束手无策了。
Spring注解开发-新注解详解
用核心配置类去替代.xml文件
核心配置类:SpringConfiguration
package com.lyh.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
//标志该类是Spring的核心配置类
@Configuration
//<context:component-scan base-package="com.lyh"/> 组件扫描
@ComponentScan("com.lyh")
//<import resource=""/>
@Import({DataSourceConfiguration.class}) //加载分配置类
//@Import({DataSourceConfiguration.class,XXX.class,XXX.class}) 可以是一个数组
public class SpringConfiguration {
}
DataSourceConfiguration配置类:
package com.lyh.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
//<context:property-placeholder location="classpath:jdbc.properties"/>
@PropertySource("classpath:jdbc.properties")
public class DataSourceConfiguration {
@Value("{jdbc.driver}")
private String driver;
@Value("{jdbc.url}")
private String url;
@Value("{jdbc.username}")
private String username;
@Value("{jdbc.password}")
private String password;
//Spring把这个方法的返回值给放到容器当中
@Bean("dataSource") //Spring会将当前方法的返回值以指定名称存储到Spring容器当中
public DataSource getDataSource() throws PropertyVetoException {
//创建c3p0的对象
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//设置基本的连接参数
dataSource.setDriverClass(driver);//这里是API这里就是字符串
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
return dataSource;
}
}
测试代码:
package com.lyh.web;
import com.lyh.config.SpringConfiguration;
import com.lyh.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserController {
public static void main(String[] args) {
//ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class);
UserService userService = app.getBean("userService",UserService.class);
userService.save();
}
}
效果:
Spring集成Junit-集成简介和开发步骤
Spring-test 包是用于Spring集成Junit包
@Runwith:原先进行测试的时候,是通过Junit进行测试的,而现在的测试是找Spring,Spring再帮我们去找Junit。
Spring集成Junit-代码实现
导入相关坐标
<!-- Junit的坐标-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--Spring集成Junit的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
测试代码:
在这个文件夹下面才会生效,否则会报错
package com.lyh.web;
import com.lyh.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.sql.DataSource;
import java.sql.SQLException;
//指定谁帮我去执行这个测试
@RunWith(SpringJUnit4ClassRunner.class) //使用Spring提供的内核去跑
@ContextConfiguration("classpath:applicationContext.xml") //指定配置文件的位置
public class SpringJunitTest {
//要测试谁 把谁进行注入就行
@Autowired //直接进行注入就行,如果能注入成功就能测试它
private UserService userService;
@Autowired
private DataSource dataSource;
@Test
public void test1() throws SQLException {
userService.save();
System.out.println(dataSource.getConnection());
}
}
效果:
package com.lyh.web;
import com.lyh.config.SpringConfiguration;
import com.lyh.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.sql.DataSource;
import java.sql.SQLException;
//指定谁帮我去执行这个测试
@RunWith(SpringJUnit4ClassRunner.class) //使用Spring提供的内核去跑
//@ContextConfiguration(value="classpath:applicationContext.xml") //指定配置文件的位置
//使用全注解的方式
//这个代表,现在要的不是配置文件。现在要的是一个配置类,把这个配置类的字节码告诉我
@ContextConfiguration(classes={SpringConfiguration.class})//classes是一个数组方式
public class SpringJunitTest {
//要测试谁 把谁进行注入就行
@Autowired //直接进行注入就行,如果能注入成功就能测试它
private UserService userService;
@Test
public void test1() throws SQLException {
userService.save();
//System.out.println(dataSource.getConnection());
}
}