1.Spring配置数据源
1.1 数据源(连接池)的作用
数据源(连接池)是提高程序性能如出现的
事先实例化数据源,初始化部分连接资源
使用连接资源时从数据源中获取
使用完毕后将连接资源归还给数据源
常见的数据源(连接池):DBCP、C3P0、BoneCP、Druid等
开发步骤
①导入数据源的坐标和数据库驱动坐标
<!-- C3P0连接池 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- Druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
②创建数据源对象
//创建数据源c3p0数据源
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//创建数据源druid数据源
DruidDataSource dataSource = new DruidDataSource();
③设置数据源的基本连接数据
//创建数据源
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//设置数据库连接参数
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUser("root");
dataSource.setPassword("root");
//创建数据源
DruidDataSource dataSource = new DruidDataSource();
//设置数据库连接参数
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUsername("root");
dataSource.setPassword("root");
④使用数据源获取连接资源和归还连接资源
//获得连接对象
Connection connection = dataSource.getConnection();
System.out.println(connection);
抽离配置文件使用jdbc.properties进行配置文件的书写
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root
加载properties进行指定数据源的设置
ResourceBundle rb = ResourceBundle.getBundle("jdbc");
rb.getString('key');
1.2 spring配置数据源的原理
将数据源对象交由spring IOC控制反转,其属性DI依赖注入(set方法注入)
spring配置数据源步骤
①导入spring与数据源相应坐标
<!--导入spring的context坐标,context依赖core、beans、expression-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<!-- C3P0连接池 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- Druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
②配置spring配置文件
<!-- c3p0数据源bean配置 -->
<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- druid数据源bean配置 -->
<bean id="DuridDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
③applicationContext加载spring配置文件获取指定bean
c3p0与Druid都是DataSource接口的实现类可以使用接口对象进行保存,减少代码冗余
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
DataSource dataSource = (DataSource) ac.getBean("c3p0DataSource");
Connection connection = dataSource.getConnection();
System.out.println(connection);
④抽离数据源配置在spring中同一配置
spring可以配置多个不同的bean,多个不同bean可能使用相同的属性数据
1)在配置文件中添加命名空间与约束路径
添加之后就可以使用相应的标签获取properties噢诶之文件并在当前配置中使用
命名空间:xmlns:context="http://www.springframework.org/schema/context"
约束路径:http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
<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">
2)书写相应标签加载指定properties配置文件
在加载当前配置文件时去指定位置加载properties配置文件
<context:property-placeholder location="classpath:jdbc.properties"/>
3)使用properties配置文件key获取对应数据
<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>
4)测试代码
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
DataSource dataSource = (DataSource) ac.getBean("DruidDataSource");
Connection connection = dataSource.getConnection();
System.out.println(connection);
2. Spring注解开发
2.1 Spring原始注解
Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率。
Spring原始注解主要是替代的配置
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的销毁方法
注解开发步骤
①在spring配置文件中开启注解扫描
配置扫描指定位置(包)中的设置注解的类进行控制反转
<context:component-scan base-package="com.yunhe"></context:component-scan>
只会加载指定包下以及子包下所有bean
②使用相应注解进行标注
1)bean标识注解
用来标识bean使其可以被扫描到并交由spring进行控制反转(实例化)
@Component 使用在类上用于实例化Bean
@Controller 使用在web层类上用于实例化Bean
@Service 使用在service层类上用于实例化Bean
@Repository 使用在dao层类上用于实例化Bean
进行标注时可以设置对应的唯一标识,也可以不设置,默认使用类名首字母小写进行定义
使用@Compont或@Repository标识UserDaoImpl需要Spring进行实例化。
@Repository("userDao")
public class UserDaoImpl implements UserDao {
@Override
public int insert() {
System.out.println("添加user");
return 1;
}
}
2)属性注入注解
用来注入属性的注解(为实例的对象赋值)
@Autowired 使用在字段上用于根据类型依赖注入
@Qualifier 结合@Autowired一起使用用于根据名称进行依赖注入
@Resource 相当于@Autowired+@Qualifier,按照名称进行注入
@Value 注入普通属性
类属性注入
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
@Qualifier("userDao")
// @Resource(name = "userDao")
UserDao userDao;
@Override
public int save() {
userDao.insert();
return 1;
}
}
基本属性注入
注解自动注入无需set方法
@Component
public class User {
@Value("张三")
private String name;
}
3)生命周期注解
@PostConstruct 使用在方法上标注该方法是Bean的初始化方法
@PreDestroy 使用在方法上标注该方法是Bean的销毁方法
@PostConstruct
public void init(){
System.out.println("初始化");
}
@PreDestroy
public void destroy(){
System.out.println("销毁");
}
测试代码
AbstractApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
User user = (com.yunhe.pojo.User) ac.getBean("user");
System.out.println(user);
ac.close();
2.2 Spring新注解
使用已有注解不能完全替代xml配置文件,还需要使用注解替代的配置如下:
非自定义的Bean的配置:
加载properties文件的配置:context:property-placeholder
组件扫描的配置:context:component-scan
引入其他文件:
注解 说明
@Configuration 用于指定当前类是一个 Spring 配置类,当创建容器时会从该类上加载注解
@ComponentScan 用于指定 Spring 在初始化容器时要扫描的包。 作用和在 Spring 的 xml 配置文件中的 <context:component-scan base-package=“com.yh”/>一样
@Bean 使用在方法上,标注将该方法的返回值存储到 Spring 容器中
@PropertySource 用于加载.properties 文件中的配置
@Import 用于导入其他配置类
spring注解类配置
@Configuration 用于指定当前类是一个 Spring 配置类,当创建容器时会从该类上加载注解
@ComponentScan 用于指定 Spring 在初始化容器时要扫描的包。 作用和在 Spring 的 xml 配置文件中的 <context:component-scan base-package=“com.yh”/>一样
@Import 用于导入其他配置类
①创建注解类
@Configuration
//用于指定当前类是一个 Spring 配置类,当创建容器时会从该类上加载注解
@ComponentScan("com.yunhe")
//用于指定 Spring 在初始化容器时要扫描的包。
// 作用和在 Spring 的 xml 配置文件中的<context:component-scan base-package=“com.yunhe”/>一样
@Import(com.yunhe.test.DataSourceConfiguration.class)
//用于导入其他配置类
public class SpringConfig {
@Bean(name = "random")
//将方法返回值对象交由spring管理
public Random getRandom(){
return new Random();
}
}
②创建其他的注解类(非必要)
可以直接书写在配置注解类中,但为了格式整理一般不同的类使用不同的配置书写
//数据源配置类
@PropertySource("jdbc.properties")
//用于加载.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;
@Bean(name="dataSource")
// 使用在方法上,标注将该方法的返回值存储到 Spring 容器中
public DataSource getDataSource() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
return dataSource;
}
}
③书写测试类
使用加载注解配置类的形式读取
AbstractApplicationContext ac=new AnnotationConfigApplicationContext(SpringConfig.class);
DataSource dataSource = (DataSource) ac.getBean("dataSource");
Connection connection = dataSource.getConnection();
System.out.println(connection);
// Random random = (Random) ac.getBean("random");
// System.out.println( random.nextInt(100));
junit单元测试@Test注解简单使用
①导入junit测试坐标
在创建maven项目时一般会自动导入单元测试junit的坐标,但是maven是进程测试时使用,所以需要将作用域删除
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
②创建测试类
注意不要使用Test作为测试类类名
③书写测试方法
测试方法书写格式:无参数无返回值
//使用注解配置类加载datascore
@Test
public void DataSourceTest() throws SQLException {
AbstractApplicationContext ac=new AnnotationConfigApplicationContext(SpringConfig.class);
DataSource dataSource = (DataSource) ac.getBean("dataSource");
Connection connection = dataSource.getConnection();
System.out.println(connection);
}
//使用注解配置类加载random
@Test
public void randomTest() throws SQLException {
AbstractApplicationContext ac=new AnnotationConfigApplicationContext(SpringConfig.class);
Random random = (Random) ac.getBean("randomsa");
System.out.println( random.nextInt(100));
}
如果只想运行单个方法只需要在相应方法处运行
如果想运行当前测试类中所有测试方法只需要在类名进行运行
在控制台对相应的方法执行结果拥有独立的显示
//在每个test方法运行之前执行
@Before
public void before(){
System.out.println("之前.......");
}
//在每个test方法运行之后执行
@After
public void after(){
System.out.println("之后.......");
}
//在第一个test方法执行前执行且只执行一次
@BeforeClass
public static void before1() {
System.out.println("before1之前.......");
}
//在第最后一个test方法执行后执行且只执行一次
@AfterClass
public static void after1(){
System.out.println("after1之后.......");
}
//注释测试方法 被注释test方法不能执行
@Ignore
public void before(){
System.out.println("之前.......");
}
//在每个test方法运行之后执行
@After
public void after(){
System.out.println("之后.......");
}
//在第一个test方法执行前执行且只执行一次
@BeforeClass
public static void before1() {
System.out.println("before1之前.......");
}
//在第最后一个test方法执行后执行且只执行一次
@AfterClass
public static void after1(){
System.out.println("after1之后.......");
}
//注释测试方法 被注释test方法不能执行
@Ignore