学习目标:
学习并且完善上一篇文章中的二分查找法的lower方法
学习声明式事务的七种传播方式,并且学习基于注解配置声明式事务。
学习内容:
public class BinarySearch { private BinarySearch(){} //非递归实现二分查找法 public static <E extends Comparable<E>> int search(E[] data, E target) { int l = 0, r = data.length - 1; //在data[l,r]的范围中查找target while (l<=r){ int mid=l+(r-l)/2; if(data[mid].compareTo(target)==0) return mid; if(data[mid].compareTo(target)<0) l=mid+1; else r=mid-1; } return -1; } //递归实现二分查找法 public static <E extends Comparable<E>> int searchR(E[] data, E target) { return searchR(data, 0, data.length - 1, target); } private static <E extends Comparable<E>> int searchR(E[] data, int l, int r, E target) { if(l>r)return -1; int mid=l+(r-l)/2; if(data[mid].compareTo(target)==0) return mid; if(data[mid].compareTo(target)<0) return searchR(data, mid + 1, r, target); return searchR(data, l, mid - 1, target); } //>target的最小值索引 public static <E extends Comparable<E>> int upper(E[] data,E target){ int l=0,r=data.length; //在data[l,r]中寻找解 while (l<r){ int mid=l+(r-l)/2; if(data[mid].compareTo(target)<=0){ l=mid+1; }else{ r=mid; } } return l; } //>target,返回最小值索引 //==target,返回最大索引 public static <E extends Comparable<E>> int ceil(E[] data,E target){ int u = upper(data, target); if(u-1>=0&&data[u-1].compareTo(target)==0) return u - 1; return u; } //>target,返回最小值索引 //==target,返回最小索引 public static <E extends Comparable<E>> int lower_ceil(E[] data,E target){ int u = upper(data, target); while (u-1>=0&&data[u-1].compareTo(target)==0){ u-=1; } return u; } //<target的最大值索引 public static <E extends Comparable<E>> int lower(E[] data,E target){ int l=-1,r= data.length-1; // 在data[l,r]中寻找解 while (l<r){ // System.out.println(l+""+r); int mid=l+(r-l+1)/2; if(data[mid].compareTo(target)<0) l=mid; else r=mid-1; } return l; } public static void main(String[] args) { Integer[] arr = {1, 1, 3, 3, 5, 5}; for(int i=0;i<=6;i++){ System.out.print(BinarySearch.lower(arr, i) + " "); } System.out.println(); } }
学习了声明式事务的七种传播方式,并对三种最常使用的方式进行了实际的使用,了解了各种方式的不同,同时完成了基于注解配置声明式事务的过程。
applicationContext.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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <context:component-scan base-package="com.imooc"/> <!-- 数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/imooc?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true"/> <property name="username" value="root"/> <property name="password" value="xxxxxx"/> </bean> <!-- JdbcTemplate--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 启用注解形式声明事务--> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>
EmployeeDao:
package com.imooc.spring.jdbc.dao; import com.imooc.spring.jdbc.entity.Employee; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import javax.annotation.Resource; import java.util.List; import java.util.Map; @Repository public class EmployeeDao { @Resource private JdbcTemplate jdbcTemplate; public Employee findById(Integer eno){ String sql = "select * from employee where eno = ?"; //查询单条数据 Employee employee = jdbcTemplate.queryForObject(sql, new Object[]{eno}, new BeanPropertyRowMapper<Employee>(Employee.class)); return employee; } public List<Employee> findByDname(String dname){ String sql = "select * from employee where dname = ?"; //查询复合数据 List<Employee> list = jdbcTemplate.query(sql, new Object[]{dname}, new BeanPropertyRowMapper<Employee>(Employee.class)); return list; } public List<Map<String, Object>> findMapByDname(String dname){ String sql = "select eno as empno , salary as s from employee where dname = ?"; //将查询结果作为Map进行封装 List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql, new Object[]{dname}); return maps; } public void insert(Employee employee){ String sql = "insert into employee(eno,ename,salary,dname,hiredate) values(?,?,?,?,?)"; //利用update方法实现数据写入操作 jdbcTemplate.update(sql,new Object[]{ employee.getEno() , employee.getEname(),employee.getSalary(),employee.getDname() , employee.getHiredate() }); } public int update(Employee employee){ String sql = "UPDATE employee SET ename = ?, salary = ?, dname = ?, hiredate = ? WHERE eno = ?"; int count = jdbcTemplate.update(sql, new Object[]{employee.getEname(), employee.getSalary(), employee.getDname(), employee.getHiredate(), employee.getEno()}); return count; } public int delete(Integer eno){ String sql = "delete from employee where eno = ?"; return jdbcTemplate.update(sql, new Object[]{eno}); } public JdbcTemplate getJdbcTemplate() { return jdbcTemplate; } public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } }
Employee:
package com.imooc.spring.jdbc.entity; import java.util.Date; public class Employee { private Integer eno; private String ename; private Float salary; private String dname; private Date hiredate; public Integer getEno() { return eno; } public void setEno(Integer eno) { this.eno = eno; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public Float getSalary() { return salary; } public void setSalary(Float salary) { this.salary = salary; } public String getDname() { return dname; } public void setDname(String dname) { this.dname = dname; } public Date getHiredate() { return hiredate; } public void setHiredate(Date hiredate) { this.hiredate = hiredate; } @Override public String toString() { return "Employee{" + "eno=" + eno + ", ename='" + ename + '\'' + ", salary=" + salary + ", dname='" + dname + '\'' + ", hiredate=" + hiredate + '}'; } }
BatchService:
package com.imooc.spring.jdbc.service; import com.imooc.spring.jdbc.dao.EmployeeDao; import com.imooc.spring.jdbc.entity.Employee; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.Date; @Service @Transactional(propagation = Propagation.NOT_SUPPORTED,readOnly = true) public class BatchService { @Resource private EmployeeDao employeeDao; @Transactional(propagation = Propagation.REQUIRES_NEW) public void importJob1(){ for (int i = 1; i <= 10; i++) { Employee employee = new Employee(); employee.setEno(8000 + i); employee.setEname("研发部员工" + i); employee.setSalary(4000f); employee.setDname("研发部"); employee.setHiredate(new Date()); employeeDao.insert(employee); } } @Transactional(propagation = Propagation.REQUIRES_NEW) public void importJob2(){ for (int i = 1; i <= 10; i++) { Employee employee = new Employee(); employee.setEno(9000 + i); employee.setEname("市场部员工" + i); employee.setSalary(4500f); employee.setDname("市场部"); employee.setHiredate(new Date()); employeeDao.insert(employee); } } public EmployeeDao getEmployeeDao() { return employeeDao; } public void setEmployeeDao(EmployeeDao employeeDao) { this.employeeDao = employeeDao; } }
EmployeeService:
package com.imooc.spring.jdbc.service; import com.imooc.spring.jdbc.dao.EmployeeDao; import com.imooc.spring.jdbc.entity.Employee; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.Date; @Service //声明式事务核心配置 //放在类上,将声明式事务配置应用于当前类所有方法,默认事务传播为REQUIRED @Transactional(propagation = Propagation.REQUIRED) public class EmployeeService { @Resource private EmployeeDao employeeDao; @Resource private BatchService batchService; @Transactional(propagation = Propagation.NOT_SUPPORTED,readOnly = true) public Employee findById(Integer eno){ return employeeDao.findById(eno); } public void batchImport() { for (int i = 1; i <= 10; i++) { if(i==3){ throw new RuntimeException("意料之外的异常"); } Employee employee = new Employee(); employee.setEno(8000 + i); employee.setEname("员工" + i); employee.setSalary(4000f); employee.setDname("市场部"); employee.setHiredate(new Date()); employeeDao.insert(employee); } } public void startImportJob(){ batchService.importJob1(); if(1==1){ throw new RuntimeException("意料之外的异常"); } batchService.importJob2(); System.out.println("批量导入成功"); } public EmployeeDao getEmployeeDao() { return employeeDao; } public void setEmployeeDao(EmployeeDao employeeDao) { this.employeeDao = employeeDao; } public BatchService getBatchService() { return batchService; } public void setBatchService(BatchService batchService) { this.batchService = batchService; } }
测试类
JdbcTemplateTestor:
import com.imooc.spring.jdbc.dao.EmployeeDao; import com.imooc.spring.jdbc.entity.Employee; import com.imooc.spring.jdbc.service.EmployeeService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.annotation.Resource; import java.util.Date; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:applicationContext.xml"}) public class JdbcTemplateTestor { @Resource private EmployeeDao employeeDao; @Resource private EmployeeService employeeService; @Test public void testFindById(){ Employee employee = employeeDao.findById(3308); System.out.println(employee); } @Test public void testFindByDname(){ System.out.println(employeeDao.findByDname("市场部")); } @Test public void testFindMapByDname(){ System.out.println(employeeDao.findMapByDname("研发部")); } @Test public void testInsert(){ Employee employee = new Employee(); employee.setEno(8888); employee.setEname("赵六"); employee.setSalary(6666f); employee.setDname("研发部"); employee.setHiredate(new Date()); employeeDao.insert(employee); } @Test public void testUpdate(){ Employee employee = employeeDao.findById(8888); employee.setSalary(employee.getSalary() + 1000); int count = employeeDao.update(employee); System.out.println("本次更新" + count + "条数据"); } @Test public void testDelete(){ int count = employeeDao.delete(8888); System.out.println("本次删除" + count + "条数据"); } @Test public void testBatchImport(){ employeeService.batchImport(); System.out.println("批量导入成功"); } @Test public void testStartImportJob(){ employeeService.startImportJob(); } }
学习时间:
08:30-09:20 11:20-13:00
学习产出:
掌握了二分查找法lower的陷阱。
了解了声明式事务的传播方式,并且学习了基于注解配置声明式事务,比XML的方式简单了许多。