博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Mybatis学习与问题
阅读量:3914 次
发布时间:2019-05-23

本文共 4868 字,大约阅读时间需要 16 分钟。

Mybatis学习与问题

遇到的问题

  1. theType interface com.ahdeer.UserDao is not known to the MapperRegistry
    答:我自己是因为在 UserDao.xml 这个针对UserDao接口的配置写错了,我把mapper标签中的UserDao路径写错了。

关于使用代理对象执行dao接口的方法

  • 步骤:
    1、//读取配置文件
    2、//创建SqlSessionFactory工厂
    3、//使用工厂生产对象
    4、//使用SqlSession创建UserDao接口的代理对象,类似于实现类实现接口
    5、//使用代理对象执行方法
    6、//释放资源
    以下为代码:
    InputStream in = Resources.getResourceAsStream(“SqlMapConfig.xml”);
    //读取配置文件
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = builder.build(in);
    //创建SqlSessionFactory工厂
    SqlSession session = factory.openSession();
    //使用工厂生产对象
    UserDao userDao = session.getMapper(UserDao.class);
    //使用SqlSession创建UserDao接口的代理对象,类似于实现类实现接口
    List users = userDao.findAll();
    //使用代理对象执行方法
    for (User user : users) {
    System.out.println(user);
    }
    session.close();
    in.close();
    //释放资源
  • 解释一下内存图的内存关系
    在这里插入图片描述
    - 我的疑惑的问题:
    为什么不直接用第四步呢,然后写一个实现类来调用呢?
    其实都行,但是build方法和session方法可以重载,也就意味着可以传入更多类型的参数,也就意味着更加灵活。所以看着麻烦,其实是为了更加灵活。不过后面学springboot就可以省去了,我们真正关心的就真的只是sql语句了。

一些问题

  1. 连接右边工具栏数据库时报错
    Server returns invalid timezone. Go to ‘Advanced’ tab and set ‘serverTimezone’ property manually.
    解决:cmd进入数据库,进入mysql数据库,输入:show variables like’%time_zone’; 输入:set global time_zone = ‘+8:00’;
    解决(永久):修改配置文件,window下是my.ini,linux下是my.cnf,优点:可以永久修改,因为每次启动时mysql都会去读这个配置文件,修改后重启下mysql服务就行了(在mysqld下面写上default-time_zone=’+8:00’)。
    解释:因为MySQL的驱动jar中默认是全球时间,而我们北京时间快八个小时,所以需要在全球时间+8小时。
  2. 在test包中先写了一个MybatisTest类,先写了main方法,再改为用@Test注解的普通方法后运行报错
    错误: 在类 com.ahdeer.test.MybatisTest 中找不到 main 方法, 请将 main 方法定义为:
    public static void main(String[] args)
    否则 JavaFX 应用程序类必须扩展javafx.application.Application
    解决:目前未知具体原因,但是在我重新搭建一个一摸一样的mybatis项目后,并未报错,猜测可能是先使用main方法后,某些包或者 .java或者 .class文件成型了,我再擅自改为普通方法就出问题了,百度说重新保存,我也没搞懂
  3. 当我把user(id(int)、name、sex)和account(id(String)、aid(外键)、count)两个表用主表实体包含一个从表实体的引用时,输出user表就会输出相应的所有account表后,报错
    Error querying database.Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column ‘id’ from result set. Cause: java.sql.SQLException: Invalid value for getInt() - ‘Five’
    解决:我在user的id中写的是1、2、3、4、5,从表的id写的是one、two、… … ,然后我直接全部输出,从表id显示的是aid(也就是主表主键—id)。我认为是两个都叫id,冲突了,于是我主表id不输出,结果报这个错误。其实分析下来,它应该是在我的配置文件中的resultMap中的两个id弄混了,所以可能我把主表id在resultMap中删除,就不会报错,而且显示的是one、two、… …。但是这样是无法显示两个id的,所以最后结论是,两个名称相同导致的错误,在navicat中把从表id改为uid其实也就是好了。记录一下一些想偷懒导致地错误。
  4. 我在原有的一个user表与User实体类的基础上新建了一个表role与Role实体类,idea中我直接复制粘贴,然后把所有的User相关的全部改为了Role相关的(包括配置文件,导包,类,接口,test方法)。但是在改完后,运行时报错
    java.lang.ClassCastException: com.ahdeer.example.Role cannot be cast to javax.management.relation.Role
    解决:我查了半天,都说什么text与varchar的问题,听不懂,但是倒是给了我一个提示,是不是我导包导错了??
    在这里插入图片描述
    结果真是我导包的时候,这里导的时候选择了第二个,所以报错,具体错误不详,但是看大概意思,应该导入实体类型的,我却导入了另一个类型的。
  5. 一个无语的错误,直接上图
    在这里插入图片描述
    这怎么是空的从表,而且都显示null,就算没数据不也应该是【】吗?
    在这里插入图片描述
    我服了,忘了在循环输出的时候已经创造了一个User对象了,我又创建了一个,那调用自然时空的User咯,因为我是放在User类型的集合中,User1新定义的自然为空。
  6. 调用语句正常,测试的时候也不报错,但是一查看就显示表没有变动,navicat中也没改变在这里插入图片描述
    一检查才发现 “ Rolling back ” ,好家伙回滚了,难怪呢。要记住!对表进行实质性的更改操作一定要加上commit,这里我在删除操作后加上了session.commit就好了。
  7. 一个我刚刚学会搭建mybatis框架流程时不知道怎么处理的问题(后来我自己用一个跟着视频搭建好的摸索完后头来看以前的问题)
    在这里插入图片描述
    解决:这是说找不到mybatis配置文件,但是其他一切正常,target也正常,但是请看mybatis配置文件的路径,不是直接在resources下的,懂了吧,所以应该是: String sqlConfig = " mybatis / mybatis_config . xml " ; 明白了吧!因为在resources下的路径不可以用 “ . ” 只能用 “ / ” ,后面的路径就跟java包下路径一样写就行,在哪写哪。
  8. 反复报错说无法找到getter方法,但是我已经写了,最后重新找了好久,想到肯定是接口的配置文件某个名字写错了,一看蓝色框框里面应该写的是实体类里的 empSex 不为空,我写成了数据库表中的 emp_sex 了。在这里插入图片描述在这里插入图片描述
  9. 执行查询语句时报错,说我的JDBC连接不上:### Error querying database. Cause: java.sql.SQLException: Error setting driver on UnpooledDataSource. Cause: java.lang.ClassNotFoundException: Cannot find class: com.mysql.jdbc.Driver
    在这里插入图片描述
    解决:这里我总结两个,首先是我把配置文件的 com.mysq.jdbc.Driver 错写成 com.mysql.jbdc.Driver 。其次,我已经没有错误了,但还是报这个没找到JDBC的错误,要知道JDBC是 Java<——> 数据库(这里是MySQL数据库)连接的一个规范,即 jar 包,如果说找不到 JDBC ,那也就是说,我的jar包没导入,而每个数据库厂家有自带的 jar 包,我用的是 MySQL ,那也就是说我的MySQL数据库针对Jav制定的驱动 jar 包并未导入,那非常简单了:重新导入呗,就在 .pom 文件中把MySQL的版本删了重写一个不一样的,就自己导入了,至于别的导入方法肯定有,但我是初学者,自己摸索到的用用就行了(贵在会分析内在联系找问题答案)。
    补充:刚刚看了一下,一开始导入的 5.7 版本的MySQL驱动jar包,左侧 External Libraries 并未显示MySQL的jar包,也就是说我没导成功,原因不详。但是我换成 5.1.49 右侧 Maven 不报红了,左边的 External Libraries 里面也有MySQL的jar包了。

mybatis框架的简单搭建

  1. 创建表
  2. 写pom文件,mybatis配置依赖和mysql的驱动
  3. 写user表的实例化类User
  4. 写mybatis.xml配置文件,是mybatis的主配置文件
  5. 写UserMapper接口,里面是要执行sql的方法
  6. 写MapperDao.xml文件,里面的namespace是接口的全类名路径,resultType是返回值类型(比如User类型的参数),id是接口方法的名称
  7. 在test包下创建同样路径的包,在跟Dao同层的包下写Test类来测试。首先把mybatis.xml这个配置文件转为字节流。然后通过sqlSessionFactoryBuilder的build方法创建一个sqlSessionFactory的对象,把字节流作为参数放进方法,然后利用该对象调用sSF里面的方法openSession,通过该方法创建一个sqlSession的对象,通过该对象调用sS里面的方法getMapper,并且把UserMapper.class文件作参数传入方法里面(这个时候把.java文件→.class文件(resource阶段),然后.class文件通过类加载器→关于该接口的对象(Class阶段)),得到一个UserMapper的对象,利用该对象调用接口里面的方法。然后输出即可。

待学习

  1. 标签(使得代码更加简洁):
    properties标签
    package标签
  2. Serializable接口的作用(序列化?)
  3. mybatis为什么持久化框架?怎么实现持久化的?
  4. mybatis的一、二级缓存:https://www.cnblogs.com/hopeofthevillage/p/11427438.html

未解决的问题(下班后解决)

  1. 使用实体类的包装对象作为查询条件干吗用?

关于mybatis连接池

  • dataSource的type属性取值:有三种:1、POOLED(用了连接池);2、UNPOOLED(没用连接池且与前者其它皆一样);3、JNDI(没用连接池,暂时不需要学)。
  • 反正肯定用POOLED就对了。
你可能感兴趣的文章
spring相关面试题
查看>>
java面向对象设计的六大原则
查看>>
java面向对象6大原则2
查看>>
java线程池学习
查看>>
Java线程:概念与原理
查看>>
Java线程:并发协作-死锁
查看>>
《构建高性能web站点》笔记--基础架构篇
查看>>
以太坊源码分析---go-ethereum之p2p通信分析(1)
查看>>
以太坊源码分析---go-ethereum之p2p通信分析(2)
查看>>
groupcache源码分析
查看>>
go-metrics源码分析
查看>>
beego/cache源码分析---典型的工厂模式
查看>>
Boltdb源码分析(一)-------page结构
查看>>
Boltdb源码分析(二)----node结构
查看>>
Go标准库plugin源码分析----动态库使用
查看>>
开源代码学习-nsq(v0.1.1版本)源码分析
查看>>
开源代码学习-nsq(v0.1.5版本)源码分析
查看>>
开源代码protoactor-go[e866f39]源码分析
查看>>
开源代码protoactor-go源码分析-async schedule
查看>>
开源代码TarsGo-v1.0.0源码分析之transport
查看>>