美文网首页
[Spring] 配置数据源(连接池)&注解&集成Junit

[Spring] 配置数据源(连接池)&注解&集成Junit

作者: abboo | 来源:发表于2020-10-18 14:02 被阅读0次

    1.1 数据源作用

    数据源(连接池)是提高程序性能如出现的
    事先实例化数据源,初始化部分连接资源
    使用连接资源时从数据源中获取
    使用完毕后将连接资源归还给数据源

    常见的数据源(连接池):DBCP、C3P0、BoneCP、Druid等

    1.2 数据源的开发步骤

    1. 导入数据源的坐标和数据库驱动坐标
    2. 创建数据源对象
    3. 设置数据源的基本连接数据
    4. 使用数据源获取连接资源和归还连接资源

    1、导入c3p0和druid和mysql的坐标

          <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.26</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.1</version>
            </dependency>
    

    2、有三种方法创建数据源:

    1. 手动创建
    2. 配置文件法
    3. Spring框架创建
    1. 手动创建
        @Test
        //测试手动创建c3p0数据源
        public void test1() throws PropertyVetoException, SQLException {
            ComboPooledDataSource dataSource = new ComboPooledDataSource();
            dataSource.setDriverClass("com.mysql.jdbc.Driver");
            dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
            dataSource.setUser("root");
            dataSource.setPassword("root");
            Connection connection = dataSource.getConnection();
            System.out.println(connection);
            connection.close();
        }
    
        @Test
        //测试手动创建Druid数据源
        public void test2() throws PropertyVetoException, SQLException {
            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);
            connection.close();
        }
    

    注意c3p0和druid的set方法后跟的字符串写法不一样,和以后的配置就不一样

    2.配置文件法

    resource下创建jdbc.properties

    jdbc.driver = com.mysql.jdbc.Driver
    jdbc.url = jdbc:mysql://localhost:3306/test
    jdbc.username=root
    jdbc.password=root
    

    读取jdbc.properties配置文件创建连接池

        @Test
        //测试手动创建c3p0数据源(加载properties配置文件)
        public void test3() throws PropertyVetoException, SQLException {
            // 读取配置文件
            ResourceBundle rb = ResourceBundle.getBundle("jdbc");
            String driver = rb.getString("jdbc.driver");
            String url = rb.getString("jdbc.url");
            String username = rb.getString("jdbc.username");
            String password = rb.getString("jdbc.password");
            ComboPooledDataSource datasource = new ComboPooledDataSource();
            datasource.setDriverClass(driver);
            datasource.setJdbcUrl(url);
            datasource.setUser(username);
            datasource.setPassword(password);
    
            datasource.getConnection();
            System.out.println(datasource);
        }
    

    druid同理

    3、 Spring配置数据源

    可以将DataSource的创建权交由Spring容器去完成
    DataSource有无参构造方法,而Spring默认就是通过无参构造方法实例化对象的
    DataSource要想使用需要通过set方法设置数据库连接信息,而Spring可以通过set方法进行字符串注入
    resources下创建applicationContext.xml文件

          <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" >
                <property name="DriverClassName" value="com.mysql.jdbc.Driver"></property>
                <property name="url" value="jdbc:mysql://localhost:3306/test"></property>
                <property name="username" value="root"></property>
                <property name="password" value="root"></property>
            </bean>
    
     @Test
        //测试Spring容器产生数据源对象
        public void test4() throws PropertyVetoException, SQLException {
            ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
            DataSource dataSource = app.getBean(DataSource.class);
            Connection connection = dataSource.getConnection();
            System.out.println(connection);
            connection.close();
        }
    

    还可以在xml中加载配置文件
    applicationContext.xml加载jdbc.properties配置文件获得连接信息。

    首先,需要引入context命名空间和约束路径:
    命名空间:xmlns:context="http://www.springframework.org/schema/context"
    约束路径:http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd
    Spring容器加载properties文件

    <context:property-placeholder location="xx.properties"/>�
    <property name="" value="${key}"/>
    
    <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">
        <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="DriverClassName" value="${jdbc.driver}"></property>
            <property name="url" value="${jdbc.url}"></property>
            <property name="username" value="${jdbc.username}"></property>
            <property name="password" value="${jdbc.password}"></property>
        </bean>
    </beans>
    

    2. Spring注解开发

    2.1 注解入门

    Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率。


    注意:
    使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,作用是指定哪个包及其子包下的Bean需要进行扫描以便识别使用注解配置的类、字段和方法。

    <!--注解的组件扫描-->�
        <context:component-scan base-package="cn.edu.ustc"/>
    

    使用xml配置时,我们要写很多配置信息


    <bean id="userDao" class="cn.edu.ustc.dao.impl.UserDaoImpl"></bean>
    <bean id="userService" class="cn.edu.ustc.service.impl.UserServiceImpl">
            <property name="userDao" ref="userDao"></property>
    </bean>
    
        @Test
        public void userController() {
            ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserService userService = app.getBean(UserService.class);
            userService.save();
    
        }
    

    使用注解时

    //UserDaoImpl.java
    // <bean id="userDao" class="cn.edu.ustc.dao.impl.UserDaoImpl"></bean>
    @Component("userDao")
    public class UserDaoImpl implements UserDao {
        @Override
        public void save() {
            System.out.println("save running");
        }
    }
    
    //UserServiceImpl.java
    //<bean id="userService" class="cn.edu.ustc.service.impl.UserServiceImpl"/>
    @Component("userService")
    public class UserServiceImpl implements UserService {
        //<property name="userDao" ref="userDao"></property>
        @Autowired
        @Qualifier("userDao")
        private UserDao userDao;
        public void setUserDao(UserDao userDao){
            this.userDao = userDao;
        }
    
        @Override
        public void save() {
            userDao.save();
        }
    }
    

    最后在appliicationContext.xml加入(那两个bean标签删除掉)

        <!--配置组件扫描-->
        <context:component-scan base-package="cn.edu.ustc"/>
    

    2.2 原始注解

    Spring原始注解主要是代替<Bean>配置
    再回到那个图



    可以看到
    Controller 作用于web层
    Service 作用于service层
    Repository 作用于Dao层
    与我们的项目结构一一对应,使用方式和Component是一样的,只是可读性强一点

    值得注意的是,使用xml配置时setUserDao() 是一定要的,但使用注解配置这个可以删掉

    @Service("userService")
    public class UserServiceImpl implements UserService {
        //<property name="userDao" ref="userDao"></property>
        @Autowired
        @Qualifier("userDao")
        private UserDao userDao;
    //    public void setUserDao(UserDao userDao){
    //        this.userDao = userDao;
    //    }
        @Override
        public void save() {
            userDao.save();
        }
    }
    

    甚至删除 @Qualifier("userDao")这一行也可以运行
    @Autowired按照数据类型从Spring容器中进行匹配,如果有多个bean就不行了
    @Qualifier("XXX")是按照id值从容器中进行匹配的,但是要使用@Autowired+@Qulifier的方法两者一起结合使用
    @Resource(name="userDao")是上面的结合,等于@Autowired+@Qulifier

    总结
    使用@Compont或@Service标识UserServiceImpl需要Spring进行实例化
    使用@Autowired或者@Autowired+@Qulifier或者@Resource进行userDao的注入

    使用@Value进行字符串的注入

    @Service("userService")
    public class UserServiceImpl implements UserService {
        @Value("aaabbb")
        private String val;
    
        @Resource(name="userDao")
        private UserDao userDao;
    
        @Override
        public void save() {
            System.out.println(val);
            userDao.save();
        }
    }
    

    结果

    aaabbb
    save running

    这样好像没什么价值,但是如果和properties结合呢

     @Value("${jdbc.driver}")
        private String driver;
    

    结果

    com.mysql.jdbc.Driver
    save running

    • 使用@Scope标注Bean的范围
    @Scope("singleton")
    
    • 使用@PostConstruct标注初始化方法,使用@PreDestroy标注销毁方法
       @PostConstruct
        public void init() {
            System.out.println("初始化方法....");
        }
    
        @PostConstruct
        public void destroy() {
            System.out.println("销毁方法.....");
        }
    

    2.3 Spring新注解

    使用上面的注解还不能全部替代xml配置文件,还需要使用注解替代的配置如下:

    非自定义的Bean的配置:<bean>
    加载properties文件的配置:<context:property-placeholder>
    组件扫描的配置:<context:component-scan>
    引入其他文件:<import>

    1. config
      @Configuration
      @ComponentScan
      @Import

    新建一个config包,里面new一个SpringConfig.java和一个DataSourceConfig.java
    DataSourceConfig.java

    //<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    @PropertySource("classpath:jdbc.properties")
    public class DataSourceConfig {
        @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("dataSource")//Spring会将当前方法的返回值以指定名称存储到Spring容器中
        public DataSource getDataSource() throws SQLException {
            DruidDataSource dataSource = new DruidDataSource();
            dataSource.setDriverClassName(driver);
            dataSource.setUrl(url);
            dataSource.setUsername(username);
            dataSource.setPassword(password);
            Connection connection = dataSource.getConnection();
            System.out.println(connection);
            connection.close();
            return dataSource;
        }
    }
    

    SpringConfig.java

    //标志该类是Spring的核心配置类
    @Configuration
    //<context:component-scan base-package="cn.edu.ustc"/>
    //<import resourve="">
    @Import({DataSourceConfig.class})
    @ComponentScan("cn.edu.ustc")
    public class SpringConfig {
    }
    

    测试一下

        @Test
        public void userControllerAnno() {
            ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfig.class);
            UserService userService = app.getBean(UserService.class);
            userService.save();
    
        }
    

    结果

    初始化方法....
    销毁方法.....
    com.mysql.jdbc.JDBC4Connection@443118b0
    com.mysql.jdbc.Driver
    save running

    3. 整合Junit

    3.1 原始Junit存在的问题

    在测试类中,每个测试方法都有以下两行代码:

    //ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
    ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfig.class);
    UserService userService = app.getBean(UserService.class);
    

    这两行代码的作用是获取容器,如果不写的话,直接会提示空指针异常。所以又不能轻易删掉。

    3.2 解决方法

    • 让SpringJunit负责创建Spring容器,但是需要将配置文件的名称告诉它
    • 将需要进行测试Bean直接在测试类中进行注入

    Spring继承Junit步骤

    1. 导入spring集成Junit的坐标
    2. 使用@Runwith注解替换原来的运行期
    3. 使用@ContextConfiguration指定配置文件或配置类
    4. 使用@Autowired注入需要测试的对象
    5. 创建测试方法进行测试

    3.2.1

    导入spring-test

           <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>5.2.9.RELEASE</version>
                <scope>test</scope>
            </dependency>
    

    3.2.2

    test下新建一个SprinigJunitTest 测试类

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class SprinigJunitTest {
    
        @Resource(name = "userService")
        private UserService userService;
    
        @Autowired
        private DataSource dataSource;
    
        @Test
        public void test1() throws SQLException {
            userService.save();
            System.out.println(dataSource.getConnection());
        }
    }
    
    

    结果

    初始化方法....
    销毁方法.....
    com.mysql.jdbc.Driver
    save running
    十月 18, 2020 1:59:16 下午 com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl info
    信息: {dataSource-1} inited
    com.mysql.jdbc.JDBC4Connection@1af2d44a

    如果使用全注解方式呢

    @RunWith(SpringJUnit4ClassRunner.class)
    //@ContextConfiguration("classpath:applicationContext.xml")
    @ContextConfiguration(classes = {SpringConfig.class})
    public class SprinigJunitTest {
        
        @Resource(name = "userService")
        private UserService userService;
    
        @Autowired
        private DataSource dataSource;
    
        @Test
        public void test1() throws SQLException {
            userService.save();
            System.out.println(dataSource.getConnection());
        }
    }
    
    

    相关文章

      网友评论

          本文标题:[Spring] 配置数据源(连接池)&注解&集成Junit

          本文链接:https://www.haomeiwen.com/subject/wqxfmktx.html