JAVA互联网架构学习之Spring其二数据库连接池及注解配置bean等

来源:互联网 发布:文明6 for mac 下载 编辑:程序博客网 时间:2024/06/07 19:01
1.数据库连接池:
数据库连接池
> 数据库连接池就是存放数据库连接(Connection)的集合
> 我们获取一个数据库连接是一个相对很麻烦的过程,
如果我们获取一个数据库连接,使用一次以后就给它关闭了
下一次再去使用的时候就要重新创建一个新的数据库连接。
> 所以我们提出了一个数据库连接池的概念,数据库连接池放的都是数据库连接(Connection)
我们在去使用数据库连接时候,不用再去重新创建数据库连接,而是直接从池中获取,
使用完的数据库连接,也不是直接销毁,而是要放回到连接池。
> 数据库连接池的常见的属性:

初始连接数量:数据连接池创建以后,保存数据库连接的数量

最小空闲连接数:数据库连接池最少得未使用的数据库连接的数量

最大空闲连接数:数据库连接池最大闲置连接数,当闲置连接数满了以后,将不会有其他连接进入池

每次增加连接数:当数据库连接都被占用以后,一次性增加的数据库连接的个数

最大连接数:数据库连接池的最大容量,当最大连接数饱和了,则不再创建新的数据库连接

最大等待时间:当数据库连接池饱和以后,等待获取数据库连接的时间

> 常见的数据库连接池
- 所有的数据库连接池都需要实现DataSource,当使用数据库连接池是,我们便不再需要使用DriverManger获取数据库连接
而是使用DataSource。
- Connection getConnection()
- 从数据库连接池中获取数据库连接对象


1.DBCP
- DBCP是Apache出品的一款数据库连接
- DBCP依赖于commons-pool
- 使用DBCP需要导入两个jar包:
commons-dbcp-1.4.jar
commons-pool-1.5.5.jar
- 当我们通过数据库连接池获取数据库连接以后,我们所获取到数据库连接已经不是我们熟悉的那个Connection
数据库连接池对Connection对象进行了包装,它修改Connection的close()方法,
再去调用close()数据库连接将不会真的关闭,而是要放回到数据库连接池中,供其他线程使用。
- 核心类:
BasicDataSourceFactory

2.C3P0(重点)
- C3P0使用的是XML作为配置文件
- 使用c3p0需要导入一个jar包:
c3p0-0.9.1.2.jarhttps://pan.baidu.com/s/1eRJpZfO
- 导入c3p0的配置文件:
1.配置文件的名字:c3p0-cofig.xml
2.配置文件要求放到类路径下(src)
- 核心类:
ComboPooledDataSource
- 注意:
DataSource就相当于池子,我们的数据库连接都是从DataSource中获取的,
如果程序中有多个DataSource的实例,那么我们说你还不如不用数据库连接池。

所以我们的DataSource在项目中应该只有一个实例。

数据库连接池的使用:

1.引用外部属性文件

jdbc.properties

jdbc.user=root
jdbc.passowrd=123456
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.driver=com.mysql.jdbc.Driver

建议使用xxx.***的形式

2.

<!-- 指定properties属性文件的位置 --><context:property-placeholder location="classpath:jdbc.properties"/>

3.

<!-- 从properties属性文件中引入属性值 --><!-- 此处的${}不是EL表达式 --><bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="user" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property><property name="jdbcUrl" value="${jdbc.url}"></property><property name="driverClass" value="${jdbc.driver}"></property></bean>

4.若要在其他切面使用properties,先导入AOP包并加上注释,将其加入到IOC池中

在目标属性上加@Value注解
@Value("${jdbc.user}")
private String username;
使用

此时就可获取到目标属性

*此处Value的${}中的名字写错不会报错,只会显示null值

5.测试数据库连接池的连接

DataSource bean = IOC.getBean(DataSource.class); //注意导入的是javax.sql.DataSource包;导入的可为父类对象类型Connection connection = bean.getConnection();String sql="select * from book";PreparedStatement ps = connection.prepareStatement(sql);ResultSet rs = ps.executeQuery();while(rs.next()) {String name = rs.getString("name");String writer = rs.getString("writer");String category = rs.getString("category");System.out.println(name+":"+writer+"——"+category);}


2.基于XML的属性装配

1.手动装配

<!-- 属性的装配:手动装配 --><bean id="userService" class="com.neuedu.spring.bean.UserService"></bean><bean  id="userAction" class="com.neuedu.spring.bean.UserAction"><property name="userService" ref="userService"></property></bean>


2.自动装配

(1).按类型装配

<!-- 1.按类型装配:byType --><!-- 首先检测当前bean中需要装配的属性的类型 --><!-- 然后在IOC容器中查找匹配这个类型的bean --><!-- 如果类型匹配的bean是唯一的,那么就将这个匹配的bean注入到userAction中 --><!-- 通过type自动装配,只能存在一个该类型的bean,id和属性名可以不同 --><bean id="userService" class="com.neuedu.entity.userService"></bean><bean id="userAction" autowire="byType" class="com.neuedu.entity.userAction"></bean>

(2).按bean的id值装配

<!-- 通过name自动装配,id和属性名必须相同 --><bean id="userService" class="com.neuedu.entity.userService"></bean><bean id="userAction" autowire="byName" class="com.neuedu.entity.userAction"></bean>


3.使用注解配置bean

1.声明bean的注解
@Component 将当前类声明为IOC容器中的一个普通的组件
@Controller 将当前类声明为IOC容器中的一个控制器组件
@Service 将当前类声明为IOC容器中的业务逻辑层组件
@Repository 将当前类声明为IOC容器中的一个持久化层组件
   Spring根据上述注解其实并不能分辨当前类是否真的是一个控制器或Dao,即使标记的类和注解不对应也没有语法错误。但在实际工作中,肯定要将专门的注解标记在对   应的类上面。

2.使用基于注解的bean的配置,需要额外导入一个jar包:spring-aop-4.0.0.RELEASE.jar


3.需要设置自动扫描的包

    <context:component-scan base-package="com.neuedu"></context:component-scan>
[1]base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包及其子包中的所有类。
[2]当需要扫描多个包时可以使用逗号分隔,
[3]如果仅希望扫描特定的类而非基包下的所有类,可使用resource-pattern属性过滤特定的类,示例:
<context:component-scan base-package="com.neuedu.component" resource-pattern="autowire/*.class"/>
[4]包含与排除
●<context:include-filter>子节点表示要包含的目标类
注意:通常需要与use-default-filters属性配合使用才能够达到“仅包含某些组件”这样的效果。
即:通过将use-default-filters属性设置为false,禁用默认过滤器,然后扫描的就只是include-filter中的规则
指定的组件了。
●<context:exclude-filter>子节点表示要排除在外的目标类
●component-scan下可以拥有若干个include-filter和exclude-filter子节


使用context:include-filter指定扫描包时要包含的类

<!-- 扫描不包含的注解 -->   <!-- annotation表示注解的全类名 --><context:component-scan base-package="com.neuedu"><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan>

使用context:exclude-filter指定扫描包时不包含的类

<!-- 扫描包含的注解      use-default-filters不使用默认过滤器  --><context:component-scan base-package="com.neuedu" use-default-filters="false"><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan>


扫描类名

<!-- aspectj表示类名的全类名 --><context:component-scan base-package="com.neuedu"><context:exclude-filter type="aspectj" expression="com.neuedu.entity.userController"/></context:component-scan>




使用注解后,默认按照类名首字母小写作为id的值,也可以使用value属性指定id,value属性名也可以省略注解

4.在切面中可使用注解进行自动装配

@Autowired注解[好处就是:连get、set方法都不用写!]
[1]首先检测标记了@Autowired注解的属性的类型
[2]根据类型进行装配
[3]如果指定类型的bean不止一个,那么根据需要被装配的属性的属性名做id的值,查找bean
[4]如果根据id值还是没有找到bean,可以使用@Qualifier注解手动指定要装配的bean的id.

例:

在Controller中调用Service时

@Autowiredprivate userService userService;
此时Service层的注解了@Service的userService就被装配了,在函数中可直接使用userService下的方法

假如userService类只有一个,那么不论这里写的对象名是否为userService,@Autowired都会自动装配the userService

例如

@Autowiredprivate userService service;
此时service一样可用


假如userService类不只一个,例如创建一个MyService extend userService

此时

@Autowiredprivate userService service;
就不可使用了,因为@Autowired找不到那个唯一的userService,有两个userService都被注入到了IOC容器中,而写的名字为service

此时可使用默认属性名来获取,例如

@Autowiredprivate userService userService;

@Autowiredprivate userService myService;

又或者使用@Qualifier手动进行注解

例如在myService类前注解@Service(value="test")

就可使用test来获取

@Autowired@Qualifier("test")private userService service;


 




原创粉丝点击