spring整合jdbc

  spring中提供了一个可以操作数据库的对象(JDBCTemplate),对象封装了jdbc技术。

  1.使用spring整合jdbc需要jdbc驱动、c3p0连接池、spring-jdbc、spring-tx事务包。

  2.准备数据库

CREATE TABLE `david2018_db`.`UserInfo` (
`Id` INT NOT NULL AUTO_INCREMENT,
`UserName` VARCHAR(255) NULL,
PRIMARY KEY (`Id`));

  3.src下新建配置文件c3p0-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!--默认配置-->
<default-config>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
</default-config> <!--配置连接池mysql-->
<named-config name="mysql">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/david2018_db</property>
<property name="user">root</property>
<property name="password">1234</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
</named-config> </c3p0-config>

  4.编写测试类

    public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); ComboPooledDataSource dataSource=new ComboPooledDataSource("mysql"); //创建jdbc模板对象
JdbcTemplate jt = new JdbcTemplate();
//注入连接池
jt.setDataSource(dataSource); //添加
jt.update("insert into userinfo (userName) values ('david')"); //修改
jt.update("update userinfo set username = 'tom' where id = 1"); }

  5.与spring整合 新建UserInfo实体类,IUserInfoDao接口,UserInfoDaoImpl实现类

package com.david.bean;

public class UserInfo {
private Integer Id;
private String UserName; public Integer getId() {
return Id;
} public void setId(Integer id) {
Id = id;
} public String getUserName() {
return UserName;
} public void setUserName(String userName) {
UserName = userName;
}
}
package com.david.dao;

import com.david.bean.UserInfo;

import java.util.List;

public interface IUserInfoDao {
void save(UserInfo u);
void update(UserInfo u);
void delete(UserInfo u);
UserInfo getUserById(Integer id);
int getTotalCount();
List<UserInfo> getUserList();
}
package com.david.dao;

import com.david.bean.UserInfo;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper; import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List; public class UserInfoDaoImpl implements IUserInfoDao{
//定义一个jdbc模板等着spring注入
private JdbcTemplate jt; public JdbcTemplate getJt() {
return jt;
} public void setJt(JdbcTemplate jt) {
this.jt = jt;
}
@Override
public void save(UserInfo u) {
String sql = "insert into userinfo (username) values (?)";
jt.update(sql,u.getUserName());
} @Override
public void update(UserInfo u) {
String sql = "update userinfo set username = ? where id = ?";
jt.update(sql,u.getUserName(),u.getId());
} @Override
public void delete(UserInfo u) {
String sql = "delete from userinfo where id = ?";
jt.update(sql,u.getId());
} @Override
public UserInfo getUserById(Integer id) {
String sql = "select * from userinfo where id = ?";
return jt.queryForObject(sql, new RowMapper<UserInfo>() {
@Override
public UserInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
UserInfo u = new UserInfo();
u.setId(rs.getInt("id"));
u.setUserName(rs.getString("username"));
return u;
}
},id);
} @Override
public int getTotalCount() {
String sql = "select count(*) from userinfo";
return jt.queryForObject(sql,Integer.class);
} @Override
public List<UserInfo> getUserList() {
String sql = "select * from userinfo";
return jt.query(sql, new RowMapper<UserInfo>() {
@Override
public UserInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
UserInfo u = new UserInfo();
u.setId(rs.getInt("id"));
u.setUserName(rs.getString("username"));
return u;
}
});
}
}

  6.将Dao配置到spring容器 不需要用c3p0-config.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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!--将连接池放入spring容器 -->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/david2018_db"></property>
<property name="user" value="root"></property>
<property name="password" value="1234"></property>
</bean>
<!--将JDBCTemplate放入spring容器 -->
<bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--将UserInfoDao放入spring容器 -->
<bean name="userInfoDao" class="com.david.dao.UserInfoDaoImpl">
<property name="jt" ref="jdbcTemplate"></property>
</bean>
</beans>

  7.测试

public class Main {

    public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); UserInfoDaoImpl userInfoDao = (UserInfoDaoImpl) ac.getBean("userInfoDao"); //添加
UserInfo u = new UserInfo();
u.setUserName("salinna");
userInfoDao.save(u); //修改
UserInfo u1 = new UserInfo();
u1.setId(1);
u1.setUserName("black");
userInfoDao.update(u1); //删除
UserInfo u2 = new UserInfo();
u2.setId(2);
userInfoDao.delete(u2); //查询数量
int totalCount = userInfoDao.getTotalCount();
System.out.println(totalCount); //查询单个user
UserInfo u3 = userInfoDao.getUserById(1);
System.out.println(u3); //查询user列表
List<UserInfo> userList = userInfoDao.getUserList();
for(UserInfo u4 : userList){
System.out.println(u4);
} }
}

spring中aop事务

  spring中封装了事务管理代码:事务操作(打开事务、提交事务、回滚事务),因为在不同平台操作事务的代码各不相同,所以spring提供了一个接口PlatformTransactionManger该接口实现类有DataSourceTransactionManager,HibernateTransactionManager等。

  spring管理事务的属性

    1.事务的隔离性:1248选择哪个隔离级别级别

    2.是否只读:如果打开 本次操作不允许修改数据库中的数据

    3.事务传播行为:解决业务方法之间调用,事务应该如何处理

      3.1:TransactionDefinition.PROPAGATION_REQUIRED 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。

      3.2:TransactionDefinition.PROPAGATION_REQUIRES_NEW 创建一个新的事务,如果当前存在事务,则把当前事务挂起。

      3.3:TransactionDefinition.PROPAGATION_SUPPORTS 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。

      3.4:TransactionDefinition.PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果当前存在事务,则把当前事务挂起。

      3.5:TransactionDefinition.PROPAGATION_NEVER 以非事务方式运行,如果当前存在事务,则抛出异常。

      3.6:TransactionDefinition.PROPAGATION_MANDATORY 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

      3.7:TransactionDefinition.PROPAGATION_NESTED 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。

    

创建数据表

CREATE TABLE `david2018_db`.`Account` (
`Id` INT NOT NULL AUTO_INCREMENT,
`UserName` VARCHAR(45) NULL,
`Money` DOUBLE NULL,
PRIMARY KEY (`Id`));

测试数据

insert into account (username,money) values ('david',1000);
insert into account (username,money) values ('jack',1000);

创建接口、实现类

package com.david.dao;

public interface IAccountDao {
void addMoney(Integer id,Double money); void decreaseModeny(Integer id,Double money);
}
package com.david.dao;

import org.springframework.jdbc.core.support.JdbcDaoSupport;

//继承JdbcDaoSupport 这个类就可以直接使用jdbctemplate对象了 不用定义属性 然后去注入了
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {
@Override
public void addMoney(Integer id, Double money) {
getJdbcTemplate().update("update account set money = money + ? where id = ?",money,id);
} @Override
public void decreaseModeny(Integer id, Double money) {
getJdbcTemplate().update("update account set money = money - ? where id = ?",money,id);
}
}

编写服务类

package com.david.service;

public interface IAccountService {
void transfer(Integer from,Integer to,Double money);
}
package com.david.service;

import com.david.dao.IAccountDao;

public class AccountServiceImpl implements IAccountService {

    private IAccountDao ad;

    @Override
public void transfer(Integer from, Integer to, Double money) {
//减钱
ad.decreaseModeny(from, money);
//加钱
ad.addMoney(to, money);
} public IAccountDao getAd() {
return ad;
} public void setAd(IAccountDao ad) {
this.ad = ad;
}
}

编写配置文件注入

<?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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/david2018_db"></property>
<property name="user" value="root"></property>
<property name="password" value="1234"></property>
</bean> <bean name="accountDao" class="com.david.dao.AccountDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean> <bean name="accountService" class="com.david.service.AccountServiceImpl">
<property name="ad" ref="accountDao"></property>
</bean> </beans>

编写测试代码

public class Main {

    public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); AccountServiceImpl accountService = (AccountServiceImpl) ac.getBean("accountService"); accountService.transfer(1,2,100D); }
}

现在是没有事务的,如果在减少钱后 发生异常 此时 钱没了, 对方还没收到.

    public void transfer(Integer from, Integer to, Double money) {
//减钱
ad.decreaseModeny(from, money); int i = 1 / 0;
//加钱
ad.addMoney(to, money);
}

spring三种加入事务的方式:

  1.编码式(了解):

    <!--事务核心管理器,封装了所有事务操作。依赖连接池 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 编码式需要模板对象,依赖事务核心管理器 -->
<bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"></property>
</bean> </beans>

  在AccountService中定义一个transactionTemplate属性并生成get set方法

public class AccountServiceImpl implements IAccountService {

    private IAccountDao ad;
private TransactionTemplate tt;
...

  在spring容器中 注入transactionTemplate

    <bean name="accountService" class="com.david.service.AccountServiceImpl">
<property name="ad" ref="accountDao"></property>
<property name="tt" ref="transactionTemplate"></property>
</bean>

  编写事务代码-无需手写打开事务 提交事务

public class AccountServiceImpl implements IAccountService {

    private IAccountDao ad;
private TransactionTemplate tt; @Override
public void transfer(Integer from, Integer to, Double money) { tt.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) { //减钱
ad.decreaseModeny(from, money); int i = 1 / 0;
//加钱
ad.addMoney(to, money); }
}); }
...

  2.xml配置(aop):

导入aop包和依赖包,导入aop命名空间,配置通知,织入

<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/david2018_db"></property>
<property name="user" value="root"></property>
<property name="password" value="1234"></property>
</bean> <bean name="accountDao" class="com.david.dao.AccountDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean> <bean name="accountService" class="com.david.service.AccountServiceImpl">
<property name="ad" ref="accountDao"></property>
</bean> <!--事务核心管理器,封装了所有事务操作。依赖连接池 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!--配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--方法名 隔离级别 传播行为 是否只读-->
<!--配置指定方法: -->
<tx:method name="transfer" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
<!--配置多个方法:通配符匹配 以什么开头的所有方法 -->
<tx:method name="save*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
<tx:method name="persist*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
<tx:method name="update*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
<tx:method name="modify*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
<tx:method name="delete*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
<tx:method name="remove*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
<tx:method name="get*" isolation="DEFAULT" propagation="REQUIRED" read-only="true"/>
</tx:attributes>
</tx:advice> <!--配置织入 -->
<aop:config>
<!--切入点 -->
<aop:pointcut id="txPc" expression="execution(* com.david.service.AccountServiceImpl.*(..))"></aop:pointcut>
<!--配置切面-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"></aop:advisor>
</aop:config> </beans>

  3.注解配置(aop):

使用注解也是要导包,命名空间,然后开启注解

<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/david2018_db"></property>
<property name="user" value="root"></property>
<property name="password" value="1234"></property>
</bean> <bean name="accountDao" class="com.david.dao.AccountDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean> <bean name="accountService" class="com.david.service.AccountServiceImpl">
<property name="ad" ref="accountDao"></property>
</bean> <!--事务核心管理器,封装了所有事务操作。依赖连接池 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!--开启注解事务 -->
<tx:annotation-driven></tx:annotation-driven> </beans>

然后再service实现类使用Transactional注解

    @Override
@Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED,readOnly = false)
public void transfer(Integer from, Integer to, Double money) {
//减钱
ad.decreaseModeny(from, money); //加钱
ad.addMoney(to, money);
}

也可以将注解加到类上 ,表示类中所有方法都开启事务。 优先级:方法上有先找方法的,方法没有才找类上的。

最新文章

  1. Spring 01基础
  2. java:关于继承变量的值问题
  3. 强加密RNGCryptoServiceProvider
  4. grads 绘制仿matlab色标效果
  5. apt-get下载的文件
  6. POJ 1548 Robots (Dilworth)
  7. lintcode:打劫房屋
  8. Struts2之异常处理
  9. ORACLE多表查询优化
  10. Android Learning:多线程与异步消息处理机制
  11. Asp.net 主题
  12. CSV 客座文章系列: Pruffi 通过 Windows Azure 挖掘社交媒体的强大招聘潜能
  13. Windows phone 8.1 MessageBox 变了哦!
  14. c#读取html
  15. aync await 进一步探索
  16. accp8.0转换教材第1章多线程理解与练习
  17. RabbitMQ windows安装(一 )
  18. 如何用ABP框架快速完成项目(14) - 结尾? 当然不是, 这只是开始!
  19. 第一课了解SQL
  20. 使用github的srs代码,搭建 RTMP_Server

热门文章

  1. SVN的一些操作
  2. Ansible 利用playbook批量部署mariadb
  3. 【上海站】EOLINKER 用户培训之旅,等你来共建API新连接
  4. kernel-常见参数或宏
  5. 2.1 Java开发工具包
  6. mybatis源码阅读-执行器StatementHandle和ParameterHandler(五)
  7. Android欢迎页面以及引导页面
  8. hdu 1220组合数学
  9. OpenCV使用GPU
  10. ORACLE11G 将dataguard的rman备份恢复到測试环境的单机oracle中的具体过程