mybatis各阶段的详解
1 本阶段的需要注意的几个点1,首先是在核心配置文件里面的内容:
配置的顺序,不配则不用管,配则必须按顺序来!!!!
properties?,
settings?,
typeAliases?,
typeHandlers?,
objectFactory?,
objectWrapperFactory?,
reflectorFactory?,
plugins?,environments?,
databaseIdProvider?,
mappers?.-->
比如我们在引入了jdbc的配置文件使用了properties标签,引入jdbc有什么好处?,可以在配置文件中统一管理
内容而不是在很多个文件改来改去,而且在核心配置文件中把数据库连接相关的写死,显然是硬编码的所以我们用配置文件代替 nice!!! jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis_db jdbc.username=root jdbc.password=kobedu #为了解决重名的问题和风险 使用前缀jdbc. 见名示意
你可能注意到了上面的写法 用前缀jdbc. 可以很好地将他们与其他的变量区分开,(可以从名字很容易看出是jdbc相关的数据,不至于和同名变量搞混因为username这种可能
不止会出现在数据库的连接) 1,在核心配置文件中引入jdbc的配置文件
上面的代码中引入配置文件的部分为
可以从上面看到写法: 2,在核心的配置文件中设置类的别名
下面这段就是用来设置类的别名:
那么问题来了,为什么要有类的别名这种操作??
因为在映射文件中每次都要写全类名显然有点麻烦比如下面这样: insert into t_user values (null,"旺财","20")
一个项目是会有很多个映射文件的为了方便,所以类别名就出现了。可以在核心配置文件写接口类和对应的别名
这样就可以在映射文件的命名空间里可以直接写User(对大小没有要求也可以是user; 其实可以比这更加简单,也是我们在实际开发中常用的写法
就是将整个包写成别名的形式,如果不写alias属性默认为类名(不区分大小写),这样就容易多了,我们只需一行代码,便可以在所有的映射文件命名空间
中直接写对应的类名 3、在核心配置中引入映射文件
引入核心的配置文件
首先需要思考的这里是映射文件的引入,我们正常的一个项目的数据库是有很多个表组成的那么每一张表对应一个mapper接口,每个接口对应一个映射文件,那么就需要导入大量的映射文件,还容易漏掉-->
上面这种以包的形式的导入非常方便,不用每次新建一个接口就要导入它的映射文件,但是上面这种写法需要 注意 一些问题: 在当前的resource目录下建包 (新建文件 然后是文件名 com/kobedu/com.kobedu.mybatis/mapper -->enter) 用上面方式建的包必须要和mapper接口所在的包同名 在包里的映射文件必须和接口类同名 4、查询时需要返回类型
如果你在映射文件中编写查询语句的sql,但是粗心的你忘记了设置返回类型会在控制台抛异常且会看到这样的说明:
It"s likely that neither a Result Type nor a Result Map was specified.
下面只是指定返回类型的一种方式:resultType,还有 resultMap
它们的区别: resultType : 设置默认的映射关系(字段名和属性一致的情况) resultMap : 设置自定义的映射关系(字段名和属性名不一致或一对多或多对一)
查询的标签必须指定resultType或resultMap 2、mybtis获取参数的两种方式(重点)
com.kobedu.mybatis 获取参数的两种方式:${} 和 #{} ${}:本质字符串的拼接(JDBC原生中的字符串拼接) 和 #{}:本质占位符 <?xml version="1.0" encoding="UTF-8" ?>
上面是使用了 #{}写法相当于原生jdbc的占位符,这个前面已经提到过了所以不多赘述, 需要注意的是#{}里面的变量名可以是任意的username规范显然很好,但是aaaa也没错因为只是用来占位的;
还有就是在使用${}时注意""单引号问题,因为${}是字符拼接的方式,所以需要注意!!
传输参数时有多个参数时
在测试代码里通过传入两个参数分别为 username和password 但是在上面代码的(映射文件里的部分代码)执行失败,(sql语句未能解析)
报错:
Cause: org.apache.ibatis.binding.BindingException: Parameter "username" not found. Available parameters are [arg1, arg0, param1, param2]
可以从错误提示的信息不难发现我们的参数在映射文件里未能真正地接受到,可以用[arg1, arg0, param1, param2] 的方式获取,mybatis将参数放到map容器可以通过建arg0,agr1..的方式
获取参数(也可以是param1,param2..)
将上面的代码改动:
需要注意的是:使用${}时需要手动添加""才能正常访问,因为他的处理方式是字符串的拼接 class test{ @Test public void selectUser(){ ParameterMapper parameterMapper = SqlSessionUtils.getSqlSession().getMapper(ParameterMapper.class); User userById = parameterMapper.getUserByUsernameAndPassword("旺财","cwlz"); System.out.println(userById); } }
做了改动之后结果很感人!!
User{id=6, userName="旺财", age=20, password="cwlz"} 若mapper接口的参数有多个时可以手动添加到map集合
可以直接通过键访问相对应的值(通过自己的方式访问到数据,上面的形式是mybatis默认提供的map和mybatis默认的提取指的方式 arg0,arg2...)
当需要传多个参数时将他们放到一个map容器,然后将map传给对应的方法(模拟mybatis的做法,就可以在sql语句中直接通过键访问到值)代码如下: class Test{ @Test public void longinTest(){ ParameterMapper parameterMapper = SqlSessionUtils.getSqlSession().getMapper(ParameterMapper.class); Map userInfo = new HashMap<>(); userInfo.put("username","旺财"); userInfo.put("password","cwlz"); User userById = parameterMapper.login(userInfo); System.out.println(userById); if (userById!=null) { System.out.println("登录成功!"); }else{ System.out.println("用户名或密码错误"); } } }
映射文件中的部分代码 :
通过键直接获取值,注意:使用${}时不要忘了单引号!!!!
当参数以实体对象的形式传参时如何解决?
只需要通过#{}以属性名的方式访问! class Test{ @Test public void longinTest2(){ ParameterMapper parameterMapper = SqlSessionUtils.getSqlSession().getMapper(ParameterMapper.class); User userById = parameterMapper.loginByUser(new User(null,"旺财",21,"cwlz")); if (userById!=null) { System.out.println("登录成功!"); System.out.println(userById); }else{ System.out.println("用户名或密码错误"); } } } 小提醒: 在接受以实体类对象的参数时在sql语句中的属性名一定要和实体类定义时属性的名一样!! 比如在实体类的定义时用户名是这样定义的 private String userName ;但是在映射文件中#{username} 就会报错: Error querying database. Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named "username" in "class com.kobedu.com.kobedu.mybatis.pojo.User"
所以代码的编写一定要规范,才能减少这种错误!!! 使用注解的方式传递参数:(以后开发就用它)
在声明方法时在参数前用注解 @Param("参数名") public interface ParameterMapper { //用于测试使用注解的传参方式 User testZhuJie(@Param("z_username") String username, @Param("z_password") String password); }
映射文件中的部分代码:(取参数时参数名和方法声明时的注解的中的参数名一一对应) 小提示:如果映射文件中的参数的名如果和注解中的参数名不一一对应则会报错: Cause: org.apache.ibatis.binding.BindingException: Parameter "username" not found. Available parameters are [z_username, param1, z_password, param2] 可以从提示看出是参数找不到(参数名写错)!!!
一定要和注解中的参数名一一对应!!! 各种查询功能查询功能 1. 若查询出的数据只有一条,可以通过实体类对象接收或者集合类接收 2. 若查询出的数据有多条可以通过List集合接收,一定不能通过实体类对象接收,此时会抛异常TooManyResultsException:(就是预期的结果是一个或者null,但是发现多个就会抛出此类异常)
如果查询的结果只有一个,也可以通过Map集合接收,字段名为键字段的值为值:{password=0000, id=3, userName=图区, age=20} MyBatis 有默认的类型别名,可以在官方文档中查看!
java.lang.Ingeger --> int ,Integer
int --> _int,_Integer
Map --> map
String --> string 以Map集合接收多条数据首先我们测试了 Map getAllUser(); 像这样接收多个数据会报错TooManyResultsException 然后可以用List接收多条数据:List