标签:
对mybatis理解的还不是特别深刻,只会简单的使用,实现这个功能跟平常使用spring+mybatis时的DAO操作有点类似,spring+mybatis具体内部实现还不清楚,后续要继续学习
代码:
1. 实体类:
1 package com.mrlu.concurrency.domain; 2 3 /** 4 * Created by stefan on 15-12-19. 5 */ 6 public class Goods { 7 private Integer id; 8 private Integer count; 9 10 public Integer getId() { 11 return id; 12 } 13 14 public void setId(Integer id) { 15 this.id = id; 16 } 17 18 public Integer getCount() { 19 return count; 20 } 21 22 public void setCount(Integer count) { 23 this.count = count; 24 } 25 26 @Override 27 public String toString() { 28 return "Goods{" + 29 "id=" + id + 30 ", count=" + count + 31 ‘}‘; 32 } 33 }
2. DAO:
1 package com.mrlu.concurrency.dao; 2 3 import com.mrlu.concurrency.domain.Goods; 4 import com.mrlu.concurrency.sqloperation.SQLSessionFactory; 5 import java.util.List; 6 7 /** 8 * Created by stefan on 15-12-19. 9 */ 10 public class GoodsDao { 11 private SQLSessionFactory sqlSessionFactory; 12 13 public void insert(Goods goods){ 14 System.out.println("insert into table goods...."); 15 String sql = "insert into goods(count) values(?)"; 16 sqlSessionFactory.insert(sql, new Object[]{goods.getCount()}); 17 } 18 19 public void update(Goods goods){ 20 System.out.println("update table goods...."); 21 String sql = "UPDATE goods SET count =? WHERE id = ?"; 22 sqlSessionFactory.update(sql, new Object[]{goods.getCount(), goods.getId()}); 23 } 24 25 public List<Goods> select(){ 26 System.out.println("select table goods...."); 27 String sql = "SELECT * FROM goods"; 28 List<Goods> resultList = sqlSessionFactory.select(sql, new Object[]{}, Goods.class); 29 System.out.println("select count: " + resultList.size()); 30 return resultList; 31 } 32 33 public SQLSessionFactory getSqlSessionFactory() { 34 return sqlSessionFactory; 35 } 36 37 public void setSqlSessionFactory(SQLSessionFactory sqlSessionFactory) { 38 this.sqlSessionFactory = sqlSessionFactory; 39 } 40 }
3. 提供代理操作方法的类,并提供创建代理类对象:
1 package com.mrlu.concurrency.daoProxy; 2 3 import org.springframework.cglib.proxy.Enhancer; 4 import org.springframework.cglib.proxy.MethodInterceptor; 5 import org.springframework.cglib.proxy.MethodProxy; 6 7 import java.lang.reflect.Field; 8 import java.lang.reflect.Method; 9 import java.sql.*; 10 import java.util.LinkedList; 11 import java.util.List; 12 13 /** 14 * Created by stefan on 15-12-21. 15 */ 16 public class SQLSessionProxy implements MethodInterceptor{ 17 private Enhancer enhancer = new Enhancer(); 18 private static List<Connection> connectionPool = new LinkedList<>(); 19 20 public Object getProxy(Class clazz){ 21 enhancer.setSuperclass(clazz); 22 enhancer.setCallback(this); 23 return enhancer.create(); 24 } 25 26 static{ 27 try { 28 Class.forName("com.mysql.jdbc.Driver"); 29 String url = "jdbc:mysql://127.0.0.1:3306/concurrency"; 30 String userName = "root"; 31 String password = "123456a"; 32 for(int i=0; i<10; i++){ 33 Connection connection = DriverManager.getConnection(url, userName, password); 34 connectionPool.add(connection); 35 } 36 }catch (Exception e){ 37 e.printStackTrace(); 38 } 39 40 } 41 42 public void init(Object o){ //注意操作的都是代理对象,不能使用this,this不代表代理对象 43 System.out.println("init......."+ o); 44 if(connectionPool.isEmpty()){ 45 return; 46 } 47 System.out.println("class: " + o); 48 System.out.println("class: " + o.getClass().getSuperclass()); 49 Field[] fields = o.getClass().getSuperclass().getDeclaredFields(); //避免private,protected修饰的属性拿不到 50 Connection connection = connectionPool.get(1); 51 connectionPool.remove(1); 52 for(Field field: fields){ 53 field.setAccessible(true); //此处设置任何属性都能拿到 54 if(field.getName().equals("connection")){ 55 try { 56 field.set(o, connection); 57 } catch (IllegalAccessException e) { 58 e.printStackTrace(); 59 } 60 break; 61 } 62 } 63 } 64 65 public void destory(Object o){ 66 System.out.println("destory......." + o); 67 Field[] fields = o.getClass().getSuperclass().getDeclaredFields(); 68 try { 69 for(Field field: fields){ 70 field.setAccessible(true); 71 if(field.getName().equals("connection")){ 72 Connection connection = (Connection) field.get(o); 73 if(connection != null){ 74 connectionPool.add(connection); 75 } 76 }else if(field.getName().equals("preparedStatement")){ 77 PreparedStatement preparedStatement = (PreparedStatement) field.get(o); 78 if(preparedStatement != null) { 79 preparedStatement.close(); 80 } 81 }else if(field.getName().equals("resultSet")){ 82 ResultSet resultSet = (ResultSet) field.get(o); 83 if(resultSet != null) { 84 resultSet.close(); 85 } 86 } 87 } 88 } catch (Exception e) { 89 e.printStackTrace(); 90 } 91 } 92 93 @Override 94 public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { 95 if(method.getName().equals("insert") || method.getName().equals("update") || method.getName().equals("select")) { //注意此处的校验是特别有必要的,为了避免陷入无限递归循环中,因为不论调用代理对象的哪个方法都会交给代理方法来处理 96 init(o); 97 if (method.getName().equals("select")) { 98 return methodProxy.invokeSuper(o, objects); //select需返回查询结果 99 } 100 methodProxy.invokeSuper(o, objects); 101 destory(o); 102 } 103 return null; 104 } 105 }
4. 封装的SQLSessionFactory
1 package com.mrlu.concurrency.sqloperation; 2 3 import java.lang.reflect.Field; 4 import java.sql.*; 5 import java.util.HashMap; 6 import java.util.LinkedList; 7 import java.util.List; 8 import java.util.Map; 9 10 /** 11 * Created by stefan on 15-12-21.
* 内部处理异常,无须抛到DAO去,DAO也不关心数据库操作异常 12 */ 13 public class SQLSessionFactory{ 14 private Connection connection = null; 15 private PreparedStatement preparedStatement = null; 16 private ResultSet resultSet = null; 17 18 public void insert(String sql, Object[] args){ 19 System.out.println("[SQLSessionFactory] insert into table goods...."); 20 try { 21 preparedStatement = connection.prepareStatement(sql); 22 for(int i=0; i < args.length;){ 23 Object object = args[i]; 24 preparedStatement.setObject(++i, object); 25 } 26 int updateCount = preparedStatement.executeUpdate(); 27 System.out.println("[SQLSessionFactory] updateCount: " + updateCount); 28 }catch (SQLException e){ 29 e.printStackTrace(); 30 } 31 } 32 33 public void update(String sql, Object[] args){ 34 try { 35 System.out.println("[SQLSessionFactory] update table goods...."); 36 preparedStatement = connection.prepareStatement(sql); 37 for(int i=0; i < args.length;){ 38 Object object = args[i]; 39 preparedStatement.setObject(++i, object); 40 } 41 int updateCount = preparedStatement.executeUpdate(); 42 System.out.println("[SQLSessionFactory] updateCount: " + updateCount); 43 }catch (SQLException e){ 44 e.printStackTrace(); 45 } 46 } 47 48 public <T> List<T> select(String sql, Object[] args, Class returnType){ 49 List<T> list = null; 50 try { 51 System.out.println("[SQLSessionFactory] select table goods...."); 52 preparedStatement = connection.prepareStatement(sql); 53 for (int i = 0; i < args.length; ) { 54 Object object = args[i]; 55 preparedStatement.setObject(++i, object); 56 } 57 resultSet = preparedStatement.executeQuery(); 58 59 List<Map<String, Object>> result = new LinkedList<>(); 60 ResultSetMetaData metaData = resultSet.getMetaData(); 61 int columnCount = metaData.getColumnCount(); 62 while (resultSet.next()) { 63 Map<String, Object> maps = new HashMap<>(); 64 for (int i = 0; i < columnCount; ) { 65 maps.put(metaData.getColumnName(++i), resultSet.getObject(i)); 66 } 67 result.add(maps); 68 } 69 System.out.println("[SQLSessionFactory] select: " + result.size()); 70 list = transferResultToObject(result, returnType); 71 }catch (SQLException e){ 72 e.printStackTrace(); 73 } 74 return list; 75 } 76 77 private <T> List<T> transferResultToObject(List<Map<String, Object>> result, Class returnType) { //此处用到了泛型(方法返回值泛型)和反射, 泛型需要注意类型擦除 78 Field[] fields = returnType.getDeclaredFields(); 79 List resultObject = new LinkedList<>(); 80 try { 81 for (Map<String, Object> map: result) { 82 Object eachResult = returnType.newInstance(); 83 for (Field field : fields) { 84 field.setAccessible(true); 85 Object object = map.get(field.getName()); 86 field.set(eachResult, object); 87 } 88 resultObject.add(eachResult); 89 } 90 }catch (Exception e){ 91 e.printStackTrace(); 92 } 93 return resultObject; 94 } 95 96 public Connection getConnection() { 97 return connection; 98 } 99 100 public void setConnection(Connection connection) { 101 this.connection = connection; 102 } 103 104 public PreparedStatement getPreparedStatement() { 105 return preparedStatement; 106 } 107 108 public void setPreparedStatement(PreparedStatement preparedStatement) { 109 this.preparedStatement = preparedStatement; 110 } 111 112 public ResultSet getResultSet() { 113 return resultSet; 114 } 115 116 public void setResultSet(ResultSet resultSet) { 117 this.resultSet = resultSet; 118 } 119 }
5. 测试:
1 package com.mrlu.concurrency; 2 3 import com.mrlu.concurrency.dao.GoodsDao; 4 import com.mrlu.concurrency.daoProxy.DaoProxy; 5 import com.mrlu.concurrency.daoProxy.SQLSessionProxy; 6 import com.mrlu.concurrency.domain.Goods; 7 import com.mrlu.concurrency.sqloperation.SQLSessionFactory; 8 9 import java.util.List; 10 11 /** 12 * Created by stefan on 15-12-17. 13 */ 14 public class Main { 15 public static void main(String[] args){ 16 SQLSessionProxy proxy = new SQLSessionProxy(); 17 SQLSessionFactory sqlSessionFactory = (SQLSessionFactory) proxy.getProxy(SQLSessionFactory.class); //创建SQLSessionFactory 18 19 GoodsDao goodsDao = new GoodsDao(); 20 goodsDao.setSqlSessionFactory(sqlSessionFactory); //注入依赖 21 22 Goods goods = new Goods(); 23 goods.setCount(30); 24 goodsDao.insert(goods); //执行数据库操作 25 26 List<Goods> list = goodsDao.select(); //拿到返回值结果,完全利用泛型的在必要的时候类型转换的特性 27 for (Goods goods1: list){ 28 System.out.println(goods1); 29 } 30 System.out.println(list); 31 } 32 }
使用cglib和JAVA反射实现AOP操作数据库增删改查的简单功能
标签:
原文地址:http://www.cnblogs.com/stefanking/p/5064846.html