面向接口编程+策略模式+方法回调一起使用

面向接口编程+策略模式+方法回调

日常在写代码的过程中,这些些简单的知识点我们应该都用过,但是真正的核心逻辑有很多人也不明白,这里给大家做一下简单的总结

  1. jdbc
  2. servlet规范
  3. jdk动态代理
  4. spring
  5. mybatis中的原生 api 方法,select(),实现原理是策略模式 + 方法回调,select可以返回我们自定义的数据格式,例如json
  6. mybatis中的mpper的代理对象方式,调用getMapper()方法时
  7. springJDBC中的 queryForObject()方法使用了

在这里插入图片描述

jdbc

Sun公司提供了一个jdbc规范,其实就是一些接口,各大数据库厂商实现了这些接口,程序员只需要会使用这些接口就行,而之前没有jdbc时我们要去学习每个数据库的使用
在这里插入图片描述

servlet规范

我们写的java应用程序是遵循servlet规范的,而一些厂商的服务器也实现了servlet规范,所以我们的程序可以运行在这些服务器上

在这里插入图片描述

jdk动态代理

在Proxy类调用newProxyInstance方法时,会有三个参数,一个是类加载器,一个是接口数组,一个是实现了InvocationHandler接口类的回调,这个类中重写了invoke方法,我们在调用方法时,会调用重写后的方法

spring

我们的程序基于三层架构,为了使各层之间的耦合度降低,spring以IOC和DI的方式帮我们很好地解决了耦合问题,例如在service层中提供一个userdao接口,而在dao层中可以随意更换任意的数据库,而不影响web层和service层

mybatis中的原生 api 方法,select(),实现原理是策略模式 + 方法回调,select可以返回我们自定义的数据格式,例如json

		//将数据库中查询到的数据拼接成json字符串
		class JsonHandler implements ResultHandler<User>{
			//[{"id":1,"name":"aa","password":"aa","address":"aa"},{},{},{}]
			//{"key1":{},"key2":{}...}
			StringBuilder sb=new  StringBuilder("[");
			@Override
			public void handleResult(ResultContext<? extends User> resultContext) {
				//获取一个用户数据
				User user =resultContext.getResultObject();
				//把数据封装成json字符串
				sb.append("{");
				sb.append("\"id\"");
				sb.append(":");
				sb.append(user.getId());
				sb.append(",");
				sb.append("\"name\"");
				sb.append(":");
				sb.append("\""+user.getName()+"\"");
				sb.append(",");
				sb.append("\"password\"");
				sb.append(":");
				sb.append("\""+user.getPassword()+"\"");
				sb.append(",");
				sb.append("\"address\"");
				sb.append(":");
				sb.append("\""+user.getAddress()+"\"");
				sb.append("}");
				sb.append(",");
			}
			public String getJson(){
				String temp=sb.toString();
				String temp1=temp.substring(0, temp.length()-1)+"]";
				return temp1;
			}
			}
			@Override
			public String findAllUser5() {
				String json=null;
				SqlSession sqlSession=null;
				try{
					sqlSession=MyBatisUtil.getSession();
					JsonHandler handler=new JsonHandler();
					sqlSession.select("findAllUser_user", handler);
					json=handler.getJson();
					sqlSession.commit();
				}catch(Exception e){
					e.printStackTrace();
					sqlSession.rollback();
				}finally{
					sqlSession.close();
				}
				return json;
			}

mybatis中的mpper的代理对象方式,调用getMapper()方法时

UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
userMapper.findUserById(7);

用UserMaper接口利用jdk动态代理生成接口代理类,用代理类生成代理对象
用代理对象调用目标方法,实际上执行的是InvocationHandler中的invoke方法
在invoke方法中调用selectOne等原生api方法,来做增删改查

	手动实现getMapper()方法
		//测试类

			public void testMethod(){
				//接口类型   jdk动态代理对象=sqlSession.getMapper(接口类型.class);
				UserMapper userMapper=(UserMapper)JDKProxy.getMapper(UserMapper.class);
				User user=userMapper.findUserById(1);
				System.out.println(user);
			}

		//代理类

			/**
			 * 根据接口获取代理对象
			 * @param clazz   接口的Class类型对象  比如UserMapper.class
			 * @return
			 */
			public static Object getMapper(Class clazz){
				Object proxyObject=null;
				/**
				 * 参数一:类加载器
				 * 参数二:接口数组
				 * 参数三:InvocationHandler接口的回调
				 */
				Object targetObject=null;
				proxyObject=Proxy.newProxyInstance(
						clazz.getClassLoader(), 
						new Class[]{clazz}, 
						new MapperHandler());
				return proxyObject;
			}

	//invocationHandler接口的实现类

			public class MapperHandler implements InvocationHandler {

				public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
					Object returnValue=null;
					System.out.println("由mybatis根据若干信息选择执行对应的原生api方法");
					//mybatis根据method能得到目标方法的返回值,方法名,参数类型
					//if判断返回的数据为一个值则调用mybatis的原生selectOne方法
					//if判断返回的数据为多个数据,就看返回类型是否为List ,则调用mybatis的原生selectList方法
					//if判断返回的数据为多个数据,就看返回类型是否为Map ,则调用mybatis的原生selectMap方法
					//if判断是insert,delete,update, ,则调用mybatis的原生对应insert(),delete(),update方法'
					//假设给一个User
					User user=new User();
					user.setName("aaa");
					returnValue=user;
					return returnValue;
				}

			}

springJDBC中的 queryForObject()方法使用了

        User user=null;
		String sql="select id idd,username name,userpassword pwd,address from t_user where id=?";
		//手动处理返回结果集中的数据如何映射到实体(domain)中
		RowMapper<User> rowMapper=new RowMapper<User>(){
			@Override
			public User mapRow(ResultSet rs, int rowNum) throws SQLException {
				User user=new User();
				user.setId(rs.getInt("idd"));
				user.setName(rs.getString("name"));
				user.setPassword(rs.getString("pwd"));
				user.setAddress(rs.getString("address"));
				return user;
			}			
		};
		user =this.jdbcTemplate.queryForObject(sql, rowMapper, id);
		return user;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值