为了账号安全,请及时绑定邮箱和手机立即绑定

通过自动回复机器人学Mybatis---加强版

难度中级
时长 2小时43分
学习人数
综合评分9.77
214人评价 查看评价
9.9 内容实用
9.7 简洁易懂
9.7 逻辑清晰
  • 我,豁出去了
    查看全部
    1 采集 收起 来源:店小二的自白

    2015-05-28

  • 动态代理,没有实现类的方法也能执行
    查看全部
  • 接口式编程(针对调用配置文件sql语句这行代码,有四处值得分析的地方)

    1、namespace :方法里的namespace需要和mapper标签的namespace一致,由于两边是手写的,可能存在不一致的风险,而且也不能保证多个sql配置文件,namespace不冲突。

     2、与sql关联的id :方法里的id和标签的id也是手写的,也存在不一致的风险。

     3、传入的参数 :例如selectList传入的参数类型是Object,所以传入的参数不管是何种类型,它不会报错,但是如果传入的类型和parameterType类型不匹配,sql语句中引用的参数就会出错。

     4、返回值:例如selectList方法,Mybatis提供了一种约束,只要是List即可,无论集合中存储何种类型,但是这样不意味执行就是对的,因为真正存入的是resultMap约束的,编译时不会报错,执行时可能就会报错。

    SqlSession方法的mapper的namespace、与sql关联的id、传入的参数、返回值。

    接口式编程:就是为了避免上述风险,而人为做的强制性规范和约束,Mybatis提供的这种方式,就称作接口式编程(相当于sql的配置文件有一个java接口作为代言人,这样SqlSession对象直接调用接口里的方法即可。但是该接口有一些前提:

    1、namespace的统一:该接口的包名+接口名就是namespace名。

    2、sql标签id的统一:代言人代言一条sql语句提供给外面,代言哪条sql语句,就提供和该sql的id相同名称方法。该接口可以代言sql配置文件的sql语句,通过提供方法,方法名为id名。

    3、方法参数的统一:接口方法参数类型为parameterType类型。

    4、方法返回值的统一:接口方法返回值类型为resultMap类型。

    注意:如上该接口就可以代言sql语句了。该接口不用人为手动编写实现类,通过Mybatis获取该接口,就可以调用,Mybatis已经实现了该接口(它就会知道该方法是调用配置文件中的哪条sql语句)。因为当前该接口没有实现类,这里通过SqlSession对象的getMapper(接口的类类型)就可以获得该接口实现类的代理对象,这样就可以直接调用接口里的方法,而不用传入namespace+id,而是按照接口的约束进行调用)。

    这样就避免了上述的问题:namespace不可能相同,因为不可能有多个相同名全路径的接口,调用方法时也不需要传入namespace。同一个接口里也不肯有多个相同名称的方法。传入的参数已经被限制,如果不符合编译会报错。返回的接口也被限定,如果不符合编译也会报错。

    接口式编程的作用:
    1、规范访问配置文件

    2、当mybatis和spring整合后,配置的数据源将交给Spring管理,也就意味着认为手写的提供SqlSession会消失,Spring将提供SqlSesssion,传入的参数应该交给Service处理好再传入进来。通过SqlSession调用接口式编程的这些代码统统都由Spring来实现。这个Dao层将会消失,该接口将会变成真正的Dao层,这时Dao层将只剩下接口文件和配置文件。

    https://img4.sycdn.imooc.com/5d391bc00001803c08140440.jpg

    https://img2.sycdn.imooc.com/5d391bc20001ef2210950322.jpg

    https://img2.sycdn.imooc.com/5d391c1a0001437809360282.jpg
    当Mybatis与Spring结合时,这些Spring提供了便捷,这里只做一些了解即可,整合之后整个Dao层只剩接口文件和配置文件。


    查看全部
    1 采集 收起 来源:接口式编程

    2019-08-06

  • 查看一个接口的所有实现类:选中接口名,Ctrl+T 或者选中该接口名,按F4,即 Open Type Hierarchy IMessage imessage=sqlSession.getMapper(IMessage.class);//获取到的就是代理实例 messageList =imessage.queryMessageList(parameter);//代理实例执行接口方法时,就会触发调用处理程序,也就是第三个参数对象的invoke()方法,MapperProxy是实现了InvocationHandler接口的 MapperProxyFactory.newInstance(MapperProxy<T> mapperProxy){ --return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader()//通过接口获取类加载器,new Class[]{mapperInterface}//代理类实现的接口数组,mapperProxy//调用代理实例的处理程序) --} 解决了三个问题: 1、为什么只定义了一个接口,没有实现类的情况下,接口方法可以被调用,因为动态代理。 2、为什么sqlSession.getMapper(.class)可以根据传入的参数,返回一个对应的类型,因为泛型。 3、Mybatis加载文件时,利用namespace加载了一个class,然后把这个class与代码中传入接口的class进行匹配,方法执行所需要的信息就是来自于已经匹配成功的配置文件中,当结果与配置文件对应上后,调用接口的方法执行sql语句。

    查看全部
  • Mybatis在案例中呈现出的特点: 1.SQL语句与代码分离 优点:便于管理和维护 缺点:不便于调试,需要借助日志工具获得信息 2.用标签控制动态SQL的拼接 优点:用标签代替编写逻辑代码 缺点:拼接复杂SQL语句时,没有代码灵活,比较复杂 3. 结果集与Java对象的自动映射 优点:保证名称相同即可自动映射 缺点:对开发人员所写的SQL依赖性很强 4. 编写原生SQL 优点:接近JDBC,很灵活 劣势:对SQL语句依赖程序很高;半自动;数据库移植不方便
    查看全部
  • 面向接口编程---源码详细步骤 加载配置信息... 通过配置信息加载一个代理工厂Map: 这个Map存放的是接口Class与对应的代理工厂 通过接口的Class从代理工厂取出对应的代理工厂 通过代理工厂实例化一个代理类 用这个代理类将代理实例返回出去 通过接口与method获取对应的配置文件信息: 接口名.方法名==namspace.id 通过配置文件中的信息获取SQL语句类型 根据SQL语句类型调用sqlSession对应的增删改查方法 当SQL语句类型是查询时: 根据返回值类型是List,Map,Object 分别调用selectList,selectMap,selectObject方法
    查看全部
  • 查看一个接口的所有实现类:选中接口名,Ctrl+T 或者选中该接口名,按F4,即 Open Type Hierarchy IMessage imessage=sqlSession.getMapper(IMessage.class);//获取到的就是代理实例 messageList =imessage.queryMessageList(parameter);//代理实例执行接口方法时,就会触发调用处理程序,也就是第三个参数对象的invoke()方法,MapperProxy是实现了InvocationHandler接口的 MapperProxyFactory.newInstance(MapperProxy<T> mapperProxy){ --return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader()//通过接口获取类加载器,new Class[]{mapperInterface}//代理类实现的接口数组,mapperProxy//调用代理实例的处理程序) --} 解决了三个问题: 1、为什么只定义了一个接口,没有实现类的情况下,接口方法可以被调用,因为动态代理。 2、为什么sqlSession.getMapper(.class)可以根据传入的参数,返回一个对应的类型,因为泛型。 3、Mybatis加载文件时,利用namespace加载了一个class,然后把这个class与代码中传入接口的class进行匹配,方法执行所需要的信息就是来自于已经匹配成功的配置文件中,当结果与配置文件对应上后,调用接口的方法执行sql语句。
    查看全部
  • 大概流程
    查看全部
  • 实现拦截器需要实现三个方法:①intercept(Invocation invacation) ② plugin(Object target)方法参数就是被拦截的对象target,返回的就是满足条件的代理类,Plugin.wrap(target,this):this也就是自定义拦截器实例,通过获取注解得到要拦截的类型,比较target的类型与this获取的要拦截的类型是不是一致,如果满足条件就获取代理对象,并执行intercept方法,没有获取代理对象的将直接返回,不会经过intercept方法。 mybatis获取statement其实是在statementHandler中,这是一个处理接口,有个prepare方法,返回Statement,这个方法是在BaseStatementHandler中实现的,statement是在instantiateStatement这个方法中获取的,这个方法是一个抽象方法,看它的PrepareStatementHandler实现,在这里边看到了connection.prepareStatement(sql,PreparedStatement.),也就是和JDBC类似的代码了,这就是分页拦截器要拦截的位置了。如何实现拦截呢?mybatis提供了相应的注解:@Intercept({@Signnature(type=StatementHandler.class),method=“prepare”,args={Connection.class}}) ①type指向要连接的接口class,这里指向StatementHandler.class, ②Method指向要拦截的方法,这里是prepare ③args[]拦截的方法的参数类型,这里是Connection.class 这样就准确描述了要拦截StatementHandler接口下的prepare方法。目标确定,接下来就可以做手脚了,在PrepareStatementHandler拿到sql语句之前将这个sql语句改装成我们的分页sql,然后在塞回去,让程序继续执行,这样就成功了。
    查看全部
  • 前端校验等于没有校验,为了保证安全,最好后端做校验。
    查看全部
  • @Page部分源码 /** * 分页对应的实体类 * */ public class Page { private int totalNumber;//总条数 private int currentPage;//当前第几页 private int totalPage;//总页数 private int pageNumber=5;//每页显示条数 private int dbIndex;//数据库中Limit的参数,从第几条开始取 private int dbNumber;//数据库中Limit的参数,一共取多少条 /** * 根据当前对象中属性值计算并设置相关属性值 */ public void count(){ //计算总页数 int totalPageTemp=this.totalNumber / this.pageNumber; int plus=(this.totalNumber % this.pageNumber) == 0 ? 0 : 1; totalPageTemp=totalPageTemp+plus; if(totalPageTemp<=0){ totalPageTemp=1; } this.totalPage=totalPageTemp; //设置当前页数 //总页数小于当前页数,将当前页数设为总页数 if(this.totalPage<this.currentPage){ this.currentPage=this.totalPage; } //当前页数小于1时,设当前页数为1 if(this.currentPage<1){ this.currentPage=1; } //设置limit参数 this.dbIndex=(this.currentPage-1)*this.pageNumber; this.dbNumber=this.pageNumber; } //其他getter和setter方法,在此忽略 public void setTotalNumber(int totalNumber) { this.totalNumber = totalNumber; this.count(); } }
    查看全部
  • 接口代言配置文件里的SQL语句步骤: 0.创建一个接口 1.首先统一命名空间【这里的命名空间地址是接口所在的位置作为xml文件的namespace】 2.想要为哪条SQL语句代言,就在接口中定义和id相对应(同名)的方法 3.SQL语句的返回值类型就是接口的返回值类型 通过mybaits获取接口 同时接口不能实例化! 通过sqlSession获取接口 Message message = new Message(); IMessage imessage = sqlSession.getMapper(IMessage.class); List<message> messageList = imessage.queryMessageList(message);
    查看全部
    1 采集 收起 来源:接口式编程

    2018-03-22

  • 本章的最终源码是利用拦截器实现分页。对于分页的简单实现,需要修改QueryService.java类中代码。增加语句"page.count();"获取limit两个参数dbIndex,dbNumber。否则页面加载不了数据,代码调试时会发现limit的两个参数为0。
    查看全部
  • 将配置文件中的<congfiguration>节点传递给XMLConfigBuilder的parseConfiguration(XNode)方法来解析,截图是parseConfiguration解析mybatis配置文件的全过程,阅读源码的方式递归阅读。
    查看全部
  • 实现拦截器需要实现三个方法:①intercept(Invocation invacation) ② plugin(Object target)方法参数就是被拦截的对象target,返回的就是满足条件的代理类,Plugin.wrap(target,this):this也就是自定义拦截器实例,通过获取注解得到要拦截的类型,比较target的类型与this获取的要拦截的类型是不是一致,如果满足条件就获取代理对象,并执行intercept方法,没有获取代理对象的将直接返回,不会经过intercept方法。
    查看全部

举报

0/150
提交
取消
课程须知
本课程的前导课程为《通过自动回复机器人学 Mybatis ---基础版》, 课程中案例的关联性极强,所以学习本课程唯一的条件就是学习过《通过自动回复机器人学 Mybatis ---基础版》
老师告诉你能学到什么?
1、 Mybatis 的接口式编程 2、实现分页查询 3、通过拦截器实现分页共通来了解 Mybatis 的拦截器 4、通过如何用数组做参数来了解 Mybatis 对类型的处理 5、 Mybatis 如何实现 jdbc 的 addBatch ,即批量插入

微信扫码,参与3人拼团

意见反馈 帮助中心 APP下载
官方微信
友情提示:

您好,此课程属于迁移课程,您已购买该课程,无需重复购买,感谢您对慕课网的支持!