4.Spring JDBC

一.JDBC

1.环境准备:
1. mysql-connector-java-5.1.x.jar:MySQL驱动包
2. druid-1.x.jar:德鲁伊连接池
3. spring-jdbc-4.2.4.RELEASE.jar:支持JDBC
4. spring-tx-4.2.4.RELEASE.jar: 支持事务

DDL

CREATE TABLE `t_emp` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `sal` decimal(10,0) DEFAULT NULL,
  `hireDate` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

db.properties

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///struts2
jdbc.username=root
jdbc.password=admin

domain

Employee

@Setter@Getter@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
	private Long id;
	private String name;
	private BigDecimal sal;
	private Date hireDate;
}

dao接口IEmployeeDAO

public interface IEmployeeDAO {
	void save(Employee e);
	void update(Employee e);
	void delete(Long id);
	Employee get(Long id);
	List<Employee> queryList();

}

dao实现类
EmployeeDAOImpl

public class EmployeeDAOImpl implements IEmployeeDAO{
	
	private JdbcTemplate jdbcTemplate;
	//属性dataSource
	public void setDataSource(DataSource ds) {
		jdbcTemplate = new JdbcTemplate(ds);
	}
	
	public void save(Employee e) {
		String sql = "insert t_emp values(null,?,?,?)";
		Object[] params = {e.getName(),e.getSal(),e.getHireDate()};
		jdbcTemplate.update(sql,params);
	}

	public void update(Employee e) {
		String sql = "update t_emp set name=?,sal=?, hireDate=? where id=?";
		Object[] params = {e.getName(),e.getSal(),e.getHireDate(),e.getId()};
		jdbcTemplate.update(sql,params);
	}

	public void delete(Long id) {
		String sql = "delete from t_emp where id=?";
		jdbcTemplate.update(sql,id);
	}

	public Employee get(Long id) {
		String sql = "select * from t_emp where id=?";
		List<Employee> list= jdbcTemplate.query(sql, new RowMapper<Employee>() {
			public Employee mapRow(ResultSet rs, int rewNum) throws SQLException {
				Employee emp = new Employee();
				emp.setId(rs.getLong("id"));
				emp.setName(rs.getString("name"));
				emp.setSal(rs.getBigDecimal("sal"));
				emp.setHireDate(rs.getDate("hireDate"));
				return emp;
			}
			
		},id);
		return list.size() > 0 ? list.get(0) : null;
	}

	public List<Employee> queryList() {
		String sql = "select * from t_emp";
		List<Employee> list = jdbcTemplate.query(sql, new RowMapper<Employee>(){
			public Employee mapRow(ResultSet rs, int rewNum) throws SQLException {
				Employee emp = new Employee();
				emp.setId(rs.getLong("id"));
				emp.setName(rs.getString("name"));
				emp.setSal(rs.getBigDecimal("sal"));
				emp.setHireDate(rs.getDate("hireDate"));
				return emp;
			}
			
		});
		return list.size() > 0 ? list : null;
	}

}

配置App-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
	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.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">
       
    <context:property-placeholder location="classpath:db.properties" 
       system-properties-mode="NEVER"/>
	
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
		init-method="init" destroy-method="close">
		<property name="driverClassName" value="${jdbc.driverClassName}"/>
		<property name="url" value="${jdbc.url}"/>
		<property name="username" value="${jdbc.username}"/>
		<property name="password" value="${jdbc.password}"/>
	</bean>
	
	<bean id="employeeDAOImpl" class="cn.dusk._01_jdbc.dao.impl.EmployeeDAOImpl">
		<property name="dataSource" ref="dataSource"/>
	</bean>
</beans>

测试类App

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class App {
	@Autowired
	IEmployeeDAO dao;
	@Test
	public void testSave() throws Exception {
		Employee e = new Employee(null,"真.红眼黑空",new BigDecimal("9000"),new Date());
		dao.save(e);
	}
	@Test
	public void testUpdate() throws Exception {
		Employee e = new Employee(1L,"假.红眼黑空",new BigDecimal("8000"),new Date());
		dao.update(e);
	}
	@Test
	public void testDelete() throws Exception {
		dao.delete(3L);
	}
	@Test
	public void testGet() throws Exception {
		Employee employee = dao.get(2L);
		System.out.println(employee);
	}
	@Test
	public void testList() throws Exception {
		List<Employee> queryList = dao.queryList();
		for (Employee employee : queryList) {
			System.out.println(employee);
		}
	}
}

二.事务

  1. Spring的事务管理主要包括3个接口:
    1. TransactionDefinition:封装事务的隔离级别和超时时间,是否为只读事务和事务的隔离级别和传播规则等事务属性,可通过XML配置具体信息。
    2. PlatformTransactionManager:根据TransactionDefinition提供的事务属性配置信息,创建事务。
    3. TransactionStatus:封装了事务的具体运行状态。比如,是否是新开启事务,是否已经提交事务,设置当前事务为rollback-only等。
  2. Spring支持编程式事务管理和声明式事务管理。
    1. 编程式事务管理:事务和业务代码耦合度太高。
    2. 声明式事务管理:侵入性小,把事务从业务代码中抽离出来,提供维护性。

Spring的事务管理:

  1. PlatformTransactionManager:接口统一抽象处理事务操作相关的方法;
    1. TransactionStatus getTransaction(TransactionDefinition definition):
      根据事务定义信息从事务环境中返回一个已存在的事务,或者创建一个新的事务,并用TransactionStatus描述该事务的状态。
    2. void commit(TransactionStatus status):
      根据事务的状态提交事务,如果事务状态已经标识为rollback-only,该方法执行回滚事务的操作。
    3. void rollback(TransactionStatus status):
      将事务回滚,当commit方法抛出异常时,rollback会被隐式调用
  2. 在使用spring管理事务的时候,首先得告诉spring使用哪一个事务管理器; 看图
  3. 常用的事务管理器:
    DataSourceTransactionManager:使用JDBC,MyBatis的事务管理器:依赖DataSource对象;
    HibernateTransactionManager: 使用Hibernate的事务管理器:依赖SessionFactory对象;

三.声明式事务管理-基于配置xml

DDL

CREATE TABLE `account` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `balance` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

资源文件

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///struts2
jdbc.username=root
jdbc.password=admin

dao接口

public interface IAccoutDAO {
	void transOUt(Long outId,Integer money);
	void transIn(Long inId,Integer money);
}

dao实现类

public class AccoutDAOImpl extends JdbcDaoSupport implements IAccoutDAO{
	
	public void transOUt(Long outId, Integer money) {
		String sql = "update account set balance = balance - ? where id=?";
		getJdbcTemplate().update(sql,money,outId);
	}

	public void transIn(Long inId, Integer money) {
		String sql = "update account set balance = balance + ? where id=?";
		getJdbcTemplate().update(sql,money,inId);
	}

}

service接口

public interface IAccountService {
	void trans(Long outId,Long inId,Integer money);
}

service实现类

public class AccountServiceImpl implements IAccountService{
	@Setter 
	private IAccoutDAO dao;
	public void trans(Long outId, Long inId, Integer money) {
		dao.transOUt(outId, money);
		System.out.println(1/0);
		dao.transIn(inId, money);
	}

}

App-context.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:tx="http://www.springframework.org/schema/tx" 
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:context="http://www.springframework.org/schema/context"
	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/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">
       
    <!-- 引入属性文件啊 -->   
    <context:property-placeholder location="classpath:db.properties" 
       system-properties-mode="NEVER"/>
    
	<!-- 配置连接池 -->
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
		init-method="init" destroy-method="close">
		<property name="driverClassName" value="${jdbc.driverClassName}"/>
		<property name="url" value="${jdbc.url}"/>
		<property name="username" value="${jdbc.username}"/>
		<property name="password" value="${jdbc.password}"/>
	</bean>
	
	<!-- 配置dao -->  
	<bean id="accoutDAOImpl" class="cn.dusk._02_routine.dao.impl.AccoutDAOImpl">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	
	<!-- 配置service -->
	<bean id="cccountServiceImpl" class="cn.dusk._02_routine.service.impl.AccountServiceImpl">
		<property name="dao" ref="accoutDAOImpl"/>
	</bean>
	
	<!--what 配置事务管理器 -->
	<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	<!-- when:配置事务的环绕增强 -->
	<tx:advice id="txAdvice" transaction-manager="txManager">
		<tx:attributes>
			<tx:method name="trans"/>
		</tx:attributes>
	</tx:advice>
	<!-- where:配置在哪里做增强 -->
	<aop:config>
		<aop:pointcut expression="execution(* cn.dusk._02_routine.service.*Service.*(..))" id="point"/>
		<aop:advisor advice-ref="txAdvice" pointcut="point"/>
	</aop:config>
</beans>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class App {
	@Autowired
	private IAccountService service;
	
	@Test
	public void testOut() throws Exception {
		service.trans(2L, 1L, 1000);
	}

}

四.总结

一:spring基础
  1. bean管理原理
    1. 反射(创建对象[IoC]) + 内省(属性赋值[DI])
  2. xml配置
    见详细配置表: 注意属性必须提供set方法
  3. 获取bean方式
    容器对象.getBean(beanName)
    容器对象.getBean(beanType)
    容器对象.getBean(beanName, beanType)
  4. bean的作用域
    singleton(单例) prototype(多例)
二:IoC
  1. xml方式:
<bean id=".." class="...">
  1. 注解:
    1)

    <context:component-scan base-package=""/>
    
    @Service用于标注业务层组件
    @Controller用于标注控制层组件(如struts中的action)
    @Repository用于标注数据访问组件,即DAO组件
    @Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注
    
三:DI注入

给容器创建好的对象设置属性值

  1. 使用xml配置(见详细配置表)
    1. Setter注入
    2. 构造器注入
  2. 注解
    1. context:annotation-config/
    2. @Autowired: 先按类型, 再按名字
    3. @Resource: 先按名字,再按类型
四:AOP
  1. 动态代理:不改变源代码情况下动态添加功能
    1. JDK:通过接口实现
    2. CGLIB:通过类继承方式实现
      2.AOP 3要素
      英语:I had dinner at home last night
    3. what: 要添加什么额外功能(增强)
    4. where: 在哪个位置作增强(哪个包,哪个类,哪个方法 )
    5. when: 在什么时机执行(执行前?后?异常?..)
五:事务

xml方式:

<bean id="事务管理器实例名称" class="事务管理器类全名">
	<property name="数据源属性名" ref="要引用的数据源实例名称"/>
  </bean>

  <!-- 配置一个事务通知  -->
  <tx:advice id="事务通知名称" transaction-manager="事务管理器实例名称">
	<tx:attributes>
		<!-- 方法以get/select/query开头,不使用事务 -->
		<tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/>
		<tx:method name="select*" read-only="true" propagation="NOT_SUPPORTED"/>
		<tx:method name="query*" read-only="true" propagation="NOT_SUPPORTED"/>
		<!-- 其他方法以默认事务进行 -->
		<tx:method name="*"/>
	</tx:attributes>
  </tx:advice>
  <!-- 使用AOP技术实现事务管理 -->	
  <aop:config>
	<aop:pointcut id="事务切入点名称" expression="事务切入点正则表达式" />
	<aop:advisor advice-ref="事务通知名称" pointcut-ref="事务切入点名称"/>
  </aop:config>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值