发表于: 2018-04-01 23:52:04

1 627


今天完成的事情:

任务1.17

完成了上次留下的任务,把JDBC连接数据库的增删改查写了一遍,把JdbcTemplate连接数据库的增删改查写了一遍,把mybatis连接数据库的增删改查写了一遍。

使用mybatis时为什么不用写实现类,因为mybatis使用了Java的动态代理在运行期创建代理实现类。其实如果直接使用sqlSession根据xml的id查询,接口都不用写,接口也只是对xml配置的一个映射,使用接口的优点是不用在Java代码里以字符串方式引用xml的id了,安全性提高,毕竟手写容易出错,而且可以使用IDE的代码补全功能查看方法了。

明天计划的事情:

任务1.18-1.21,Junit测试以前用过,应该不会费太多时间,spring又是一个大块,打算先不深入研究,复习个大概,先任务优先。                         

遇到的问题:

1、spring配置文件引入包含数据库连接信息的properties文件时,因为还没复习spring,就想当然的使用了import命令,结果显然无法解析。

  1. 需要使用<context:property-placeholder location="db.properties" />组件来引用。或者还有配置相关bean的方法。
  2. 2、spring配置数据库信息中的用户名和密码使用${}方式获取properties文件的值总是报错,我的密码是空的,然后不使用${}获取密码了,用户名也报错,控制台输出信息显示用户名是乱码。开始我以为是编码问题,但properties里也没有中文,而且改了编码也不行,再说jdbc和url都能正常获取。后来发现properties中的属性都换成jdbc.username这种格式就正常了。看来它获取的是另一个username变量值?又查了查才知道,原来它默认获取的是本计算机的用户名。而我的计算机用户名是中文的,乱码了才没想到这个。而我计算机的密码它也获取不到。想要获取properties文件中的username和password,需要设置system-properties-mode属性,如下:   
  3. <context:property-placeholder location="db.properties" system-properties-mode="FALLBACK"/>
  4. 或者把变量名设置成不冲突的。
  5. 收获:
  6. 一、关于JDBC:
  7. 任务里虽然没有用JDBC,但JdbcTemplate以及mybatis等连接数据库的工具都是对JDBC的封装,所以总结了一下。
  8. JDBC连接数据库的步骤(以mysql为例):
  9. 1、加入JDBC驱动jar包
  10. 2、注册驱动:Class.forName(com.mysql.jdbc.Driver);
  11. 3、获取连接:Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbname", "root", "password");
  12. 4、执行查询:
  13.   Statement statement = connection.createStatement();
      String sql = "select * from student";
      ResultSet resultSet = statement.executeQuery(sql);
  14. 5、处理结果:
  15.   while(resultSet.next()){
        int id = resultSet.getInt("id");
        String name = resultSet.getString("name")
        System.out.println("ID:" + id + " Name:" + name);
      }
  16. 6、关闭资源:
  17.   resultSet.close(); 
      statement.close(); 
      connection.close();
  18. 如果没使用连接池的话,只关闭connection就可以了。另外这里面主要用到的接口都在rt.jar的ava.sql包里。
  19. 写了写JDBC,再去用其它的框架如JdbcTemplate等,就能感觉到它们的好处了,上面的代码大部分可以省了。对比如下:
  20. 二、关于JdbcTemplate
  21. JdbcTemplate的使用也很简单,主要是要配置好。三种配置方式:
  22. 1.在DAO实现类中注入一个外部DataSource引用(spring的XML文件配置),然后自己实例化JdbcTemplate,如:
  23. private static JdbcTemplate jdbcTemplate;
  24. public void setDataSource(DataSource dataSource) {
      this.jdbcTemplate = new JdbcTemplate(dataSource)
  25. }
  26. 2.在Spring的IoC容器中配置一个JdbcTemplate的bean,将DataSource注入进来,然后再把JdbcTemplate注入到自定义DAO中。
  27. 就是把JdbcTemplate的创建工具交给spring框架了,和其它xml文件里配置的bean一样。
  28. 3.继承JdbcDaoSupport类,注入DataSource。(JdbcDaoSupport类中有DataSource和JdbcTemplate属性)
  29. JdbcTemplate的使用之前也总结过API了,或者用到时查API就可以。
  30. 三、关于mybatis
  31. 这两天看的最多的还是mybatis,MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的JDBC。
  32. 另外提一下ORM,百度:
  33. 对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的--“虚拟对象数据库”。
  34. 面向对象是从软件工程基本原则(如耦合、聚合、封装)的基础上发展起来的,而关系数据库则是从数学理论发展而来的,两套理论存在显著的区别。为了解决这个不匹配的现象,对象关系映射技术应运而生。
  35. hibernate是ORM框架,mybatis算不上完全的ORM框架,mybaits可以把数据库的表数据直接映射到Java对象里,但是却不能通过Java对象直接操作数据库表,还是要手写sql语句。
  36. 所以有人说mybatis是半自动ORM框架,有人说不是ORM,只是用xml标记然后用java查找占位符,说白了就是给你在java和sql之间提供更灵活的映射方案。
  37. 自己的感觉,这些框架的出现和发展,不管是ORM等持久层框架,还是spring,struts,springmvc等别的框架,都是由需求推动的。这些需求包括面向对象的思想、减少开发代码量、业务层数据层等各层的解耦合、提升性能、安全性等等。
  38. 使用这些框架有很多优点,如程序员不需要去关注太多底层的或者与业务无关的内容,从而专注在业务逻辑代码上。但优点也是缺点,比如本来一句SQL能搞定的事,用了mybatis或者hibernate之类的,还要花大量时间学习框架的内容,说是为了简化,有时却变得更麻烦了。
  39. 而且框架对逻辑进行了各种封装,出了问题就懵了,你还要花时间深入研究框架,看源码?不知道多少新框架又出来了,没等你学熟练这框架也许就淘汰了。
  40. 也许从公司的角度看,使用框架能减少很多成本,毕竟现在这么多培训出来的,谁都会几个热门框架,处理简单的业务也足够用了,而且大多数人对技术并不是真的热爱,会使几个框架能干活就得了,也不用考虑太多。但如果是对技术有追求的初级程序员,该深入学什么不该学什么,还是应该好好思考下的,毕竟现在技术更迭这么快,要有长远的眼光和知识架构的方向。
  41. 当然用不用框架,分不分层什么的之类的问题,也不是你来决定的,现阶段还是好好学习,不用思考太多。等工作个几年经验丰富了,自然会有更深的理解。其实是看完mybatis手册后觉得,很多东西似乎还是弄得挺复杂的,貌似hibernate更复杂,感觉持久层框架以后还会有很多改善吧。就像现在别的什么层不是又出了个springboot什么的,据说用起来很简单。总之一切都在发展之中。
  42. mybaits也要配置,有一个主要的配置文件,元素如下:
  43. properties是引入属性文件,也可以自己定义属性。environments是配置数据源(和事务)的,类型别名什么的用一次就明白了。其它的属性可以先不用深入了解,最关键的是mappers映射器。mapper映射器是写sql语句的xml文件,这里只是要把所有mapper.xml引入进来。
  44. mapper映射器中定义了sql语句,并能把查询结果映射到java的实体类中,这个是mybatis比较核心的功能。映射器xml文件的元素如下:
  45. 看起来挺简单的,不过每个元素标签下都会有许多的子标签可选。最重要最强大的是resultMap元素,它定义了如何把数据库查询的结果集映射到Java对象里。
  46. 当然很多简单的情况,根本不需要定义resultMap,像返回结果是一个Student类这种,mybatis会在幕后自动创建一个resultMap帮你映射。但是比较复杂的情况就需要了,像有表关联的,一对多、多对一、多对多什么的,对于这种情况,mybatis的resultMap里主要使用了collection和association元素来解决,看起来很复杂,其实熟悉一下逻辑还是挺简单的。不过表关联的内容官方文档写的感觉不如其它教程简单。关联查询暂时还没有用到,就不深入讨论了。
  47. 官方文档中文版:http://www.mybatis.org/mybatis-3/zh/index.html
  48. 其它教程:https://www.yiibai.com/mybatis/
  49. mybatis在获取了sqlSession后,有两种执行sql的方法,一种是直接使用sqlSession的API:
  50. Student s = sqlSession.selectOne("jnshu.mapper.StudentMapper.selectById", 1); //直接根据xml映射器中定义的id去查找sql然后执行
  51. 另一种是编写一个与xml映射器对应的Java接口,然后调用接口的方法:
  52. StudentMapper sm = session.getMapper(StudentMapper.class);
  53. Student s = sm.selectById(1);
  54. 接口中的方法名对应xml中的id,参数类型对应xml中的paramType,返回类型对应xml中的resultType或者resultMap。
  55. mybatis会根据接口的方法来找到xml映射器中定义的sql来执行,比第一种方法多了一个中间步骤。
  56. 第一种方法,由于是直接根据映射器id查sql执行,所以映射器xml中的namespace属性没有特别要求,只要唯一就好。但是第二种方法,由于是通过接口的方法来执行sql,所以namespace必须和接口全路径相同,不然无法通过方法名找到对应的映射器和语句。
  57. 当然这种绑定其实在程序运行时就已经做好了。mybatis会解析xml文件,检查namespace指定的接口类是否存在,存在的话,该接口和命名空间就会绑定。然后在方法调用的时候才能动态代理生成接口的实现类。如果namespace没有和接口绑定,则调用的时候无法生成接口的实现类。
  58. 所以用第二种方式的话namespace一定要指定对应接口的路径就好了。
  59. 最后再总结一下mybatis传入参数的问题吧。
  60. parameterType 将会传入这条语句的参数类的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset。
  61. 所以大多时候parameterType参数都是可以省略的。如果是单一的参数,获取方法有:
  62. 基本数据类型:#{参数} 获取参数中的值

  63. 复杂数据类型:#{属性名}  ,map中则是#{key}

  64. 举例:

  65. 这两个中的parameterType参数都是可以不写的,也能成功执行。

  66. 如果是多个参数,那parameterType想写也没法写了,可以有几种方法传参:

  67. 1、用#{index}序号的方式接收参数:

  68. 2、用注解的方式指定参数的名字:

  69. 3、把参数封装成map或者list等,不再细说。

  70. 任务1.17算结束了,弄了好几天,花时间最长的主要是系统的浏览了一下mybatis手册,另外鼓捣了一下编码的问题。明天开始1.18任务。



返回列表 返回列表
评论

    分享到