2d Spring-JC.txt
UP 返回
1.简介
jdbcTemplate类似人DBUtils,用于操作Jdbc的工具类,它需要依赖于连接池DataSource(数据源)(直接使用jdbc是不用连接池的)
JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API
ODBC(Open Database Connectivity,ODBC)开放数据库连接,是微软公司开提供了一组对数据库访问的标准API(应用程序编程接口)(SQLServer)
DBCP(DataBase Connection Pool)数据库连接池,是java数据库连接池的一种,由Apache开发
C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。
c3p0与dbcp区别
dbcp没有自动回收空闲连接的功能,c3p0有自动回收空闲连接功能
2.导入jar包
com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar c3p0连接池
com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar dbcp连接池(下面那个也要添加)
com.springsource.org.apache.commons.pool-1.5.3.jar
mysql-connector-java-5.0.8-bin.jar MySQL驱动(位置:F:\BaiduNetdiskDownload\2019年4月黑马程序员教程\01-黑马IDEA版本Java基础+就业课程\4.框架\Java开发工具\jar包\dbcp连接池)
spring-jdbc-4.2.0.RELEASE.jar spring jdbc
spring-tx-4.2.0.RELEASE.jar 事务管理
3.简单使用的代码
3.1 不使用配置文件
■测试类
public class JdbcTest {
@Test
public void testJdbc() throws Exception{
//1.创建数据源
BasicDataSource dataSource=new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///test");//表示本地数据库
dataSource.setUsername("root");
dataSource.setPassword("123654");
//2.创建jdbcTemplate
JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
jdbcTemplate.update("update custom set username=? where id=?","zz",1);
}
}
3.2 使用配置文件
■表结构类
public class Custom {
private Integer id;
private String username;
private String password;
}
■Dao层
@Repository
public class CustomDao {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void add(Custom custom){
jdbcTemplate.update("insert custom (username,password) values (?,?)",custom.getUsername(),custom.getPassword());
}
}
■测试类
public class JdbcTest {
@Test
public void testJdbc() throws Exception{
ApplicationContext context=new ClassPathXmlApplicationContext("jdbctest.xml");
CustomDao customDao=(CustomDao) context.getBean("customDao");
Custom custom=new Custom();
custom.setUsername("哈哈");
custom.setPassword("123456");
customDao.add(custom);
}
}
★配置文件jdbctest.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"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--配置DBCP DataSource-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///test"></property>
<property name="username" value="root"></property>
<property name="password" value="123654"></property>
</bean>
<!--配置jdbcTemp对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置dao-->
<bean id="customDao" class="com.cn.dao.CustomDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property> ▶注意在配置自己的类中的属性时,只有属性存在set方法,IDE才会在写的时候给与提示(所以上面customDao类中故意加了一个setJdbcTemplate的方法)
</bean>
</beans>
如果要使用c3p0数据源,只需改为:(注意两种数据源中的属性名略有不同)
<!--配置c3p0数据源-->
<bean id="dataSource1" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///test"></property>
<property name="user" value="root"></property>
<property name="password" value="123654"></property>
</bean>
3.3 代码优化
spring提供了一个JdbcDaoSupport类自带模板,可以通过继承他省去自己定义JdbcTemplate的必要
关于数据库的配置信息,可以将其放入单独的文件
相应代码更改如下(未列入的代码说明不变):
■Dao层
@Repository
//▶继承了JdbcDaoSupport,自带模板
public class CustomDao extends JdbcDaoSupport{
public void add(Custom custom){
getJdbcTemplate().update("insert custom (username,password) values (?,?)",custom.getUsername(),custom.getPassword());
}
}
★配置文件jdbctest.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"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--读取properties数据 ▶不可少(classpath表示类路径,即src文件下)-->
<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
<!--配置DBCP DataSource-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${driverClassName}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
</bean>
<!--配置dao ▶可以少配置模板属性-->
<bean id="customDao" class="com.cn.dao.CustomDao">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
★配置文件db.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///test
username=root
password=123654
█踩坑:以上修改数据库信息到properties中后,数据库连接会报错,Cannot create PoolableConnectionFactory (Access denied for user 'shuil'@'localhost' (using password: YES)),但是直接在xml中赋值时没问题的,原因暂不明
★后来验证发现是用户名读取错误,配置文件使用username会被spring解析成计算机的名字,所以要换个名称:jdbc.username=root,相应修改xml,问题解决
4.mysql的事务保存
4.1 简单的一个事务(以下ABCD是一个事务,一旦出错则所有的操作都会回滚)
Connection conn = null;
try{
//1 获得连接
conn = ...;
//2 开启事务
conn.setAutoCommit(false);
A
B
C
D
//3 提交事务
conn.commit();
} catche(){
//4 回滚事务
conn.rollback();
}
4.2 建立一个事务的保存点(比如AB事务是必须提交的,而CD则是可选,应该采取以下代码)
Connection conn = null;
Savepoint savepoint = null; //保存点,记录操作的当前位置,之后可以回滚到指定的位置。(可以回滚一部分)
try{
//1 获得连接
conn = ...;
//2 开启事务
conn.setAutoCommit(false);
A
B
savepoint = conn.setSavepoint(); ●
C
D
//3 提交事务
conn.commit();
} catche(){
if(savepoint != null){ //CD异常 ●
// 回滚到CD之前
conn.rollback(savepoint);
// 提交AB
conn.commit();
} else{ //AB异常 ●
// 回滚AB
conn.rollback();
}
}
DOWN 返回