发表于: 2018-02-07 18:46:31
3 715
今日完成的事:
mybatis排错和dao功能初步实现。
关于昨天的错误,今天还是长时间卡在上面,我想可能不是没有创建sqlsession实例的原因,因为程序卡在了
SqlSessionFactoryBuilder().build(inputStream);
这个方法上。既然不能成功创建sqlsessionfactor实例,那就更不能创建sqlsession实例了。
我花了大量的时间,反复检查代码,都没有发现问题到底出在哪里,由于上面说error may exist in mapper configuration,可是我怎么也找不出mapper映射文件到底哪里出错了。
直到我无意间看到了properties标签的设置规范,我才知道原来问题根本不是mapper映射文件出问题了,而是properties的resource资源出了问题,结果发现原来是外部文件定义的属性导入不到datasource标签中,原因是外部文件不应使用xml。不像mapper映射,它就是一个普通的文本文件,也不需要另外定义propertie标签。
mybatis的dao实现,使用hashmap保存表名和表值。但是这样会产生强制类型转换。
mybatis终于也可以使用了,而且我发现是一次编译到处使用,但是目前没有看到比jdbc优越的地方。
关于其他插入语句,例如insert语句。由于一般需要一次输入很多数据,所以参数的类型都是一个java类,这个类可以使用所谓的JavaBean和所谓的POJO,这方面我还没看,但是创建一个类还是不难的。
创建一个Student类,除了一些基本的成员变量外,其余的全部都是get和set方法。
疑问:我一直有点奇怪,为什么不用构造函数?
用于插入的映射代码。
疑问解决:我并不知道其他人是否有什么好办法使用可变参数长度的构造函数来初始化student实例,即使那需要写13个重载的构造函数。
但是使用一连串的set方法,我就可以做到定制插入的数据,因为一般来说,很可能插入一条不完整的数据。像这样:
插入完成,使用command line一查
插入成功。
注意有的时候插入不成功mybatis是不会报错的。
好吧我承认是我没找到设置可变参数构造函数的办法,另外由于java不允许默认参数,所以你必须写13个方法才行。
收获:
(重要)花时间细心检查那些低级错误(例如是不是忘了逗号,分号,或者代码格式不对!)。否则你可能会在莫名其妙的异常上卡上很久。
关于mybatis的记录知识:
关于复杂结果集映射:
如其名,简单的select比如在一个表中查询某行,只需要简单的结果集映射就行,但是如果你面对的是各种关联表例如要在表B中查询和表A,C,D,E有关的值。那么结果集映射就会变得复杂。
复杂结果集映射有以下标签用于构造一个映射:
constructor:这个标签用于当实例化一个结果类时,把结果注入类的构造方法中。
使用result作为一个字段把数据注入到类的属性中。
association:可以包含多个result查询结果,算是复杂结果集映射,例如一次查询中与一个表有关的数据。association中可以包含另一个它,例如如果在表a中查询a和b的数据,并有
类似下面的查询:
from Blog B left outer join Author A on B.author_id = A.id
那么可以这么定义resultMap:
<resultMap id = aResult type = xxx>
<id...
<result...
<association property = "b" column="b.author.id" jataType = "xxx" resultMap = "bResult"/>
<association id = "bResult" type= "xxx"
....
collection:用于复杂类型的集,对于一些特定的结果类,使用这个标签可以把多条result压缩为一个特定result结果类型。一个collection可以包含另一个collection,这取决于select的方式。
创建一个这样的映射可能也会比较麻烦,但是如果能创建好的话会很强大。
诀窍就是从简单往复杂创建,利用单元测试来推进。
我没有找到例子去练习复杂映射和语言,希望以后有机会。
明天做的事:
学单元测试,spring等等。
补充:
如上所述,在插入一条数据的时候往往可能不能给所有项赋值,那么在编写mapper的时候就必须注意,在sql中,如果缺项或者不给指定项传值的话,是会报错的,但是mybatis这边是不会抛出异常的,原因是mybatis不能进行错误类型转换,所以,在写insert时,在values语句后面创建缺省值如:
#{ID}时,需要在后面加入jdbcType = ”数据类型“,如INTEGET或者CHAR,这样当赋予空值时可以自动创建NULL值。
评论