本文衔接MyBatis基础学习知识点1,继续对以下两个问题进行探讨

1.dao配置文件主要是用来干什么的?如何进行配置?

2.使用测试方法测试程序运行是如何实现的?每条语句起什么作用?

目录

dao配置文件主要是用来干什么的?如何进行配置?

mapper标签

select标签

insert标签

update标签

delete标签

使用测试方法测试程序运行是如何实现的?每条语句起什么作用?

基础步骤

SqlSessionFactory接口

SqlSession接口

MybatisUtils工具类

实现dao接口

使用代理模式

mybatis的dao代理

理解参数

parameterType

传递一个简单类型参数

传递多个简单类型参数

使用实体类属性传递参数

按照位置传递参数

使用map传参

#占位符与$占位符的区别

封装MyBatis输出结果

resultType

当查询结果为自定义类型时

当查询的结果为简单类型时

当查询结果为Map类型时

resultMap自定义查找结果

有关like查询


dao配置文件主要是用来干什么的?如何进行配置?

我们拿出一个最简单的dao层配置文件进行分析

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ling.mybatis.dao.UserDao"><!--路径的各个包之间必须用.隔开--><select id="findAllUser" resultType="com.ling.mybatis.pojo.User">select * from user</select>
</mapper>

可以看到配置文件标签体都在http://mybatis.org/dtd/mybatis-3-mapper.dtd的约束下

其中最为核心的就是mapper标签

mapper标签

mapper标签用于配置dao接口的相关映射

namespace属性

用于定义访问sql语句的命名空间,我们在书写最终执行代码的时候可以看到

@Testpublic void test1() throws IOException {//定义mybatis核心配置文件在classes下的路径String mybatisPath = "mybatisConfig.xml";//根据路径获取字节输入流对象InputStream is = Resources.getResourceAsStream(mybatisPath);//创建SqlSessionFactoryBuilder对象SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();//通过SqlSessionFactoryBuilder对象的build方法创建SqlSessionFactory对象SqlSessionFactory factory = sqlSessionFactoryBuilder.build(is);//通过工厂类的openSession方法获取sql执行对象SqlSession sqlSession = factory.openSession();//sql执行对象的selectOne方法//获取第一个参数,即执行id:由namespace + . + SQL语句标签idString id = "com.ling.mybatis.dao.UserDao" + "." + "findUserById";User user = sqlSession.selectOne(id);System.out.println(user);//关闭sqlSessionsqlSession.close();}

最终sql语句会由SqlSession对象执行,当sql语句执行时需要传入一个字符串,该字符串就时由命名空间和sql语句id构成,如此书写可以让程序更具格式化,层次分明。

namespace的值建议设置为dao接口在src下的全路径名称,为了方便分清结构层次,以及后续工具的使用,作用是参与识别sql语句的作用。

select标签

主要用于书写select相关sql语句

id属性

设置sql语句名称,为了方便分清结构层次,以及后续工具的使用建议使用对应的方法名称

resultType属性

设置查找到的最终结果的返回值类型,类型需要写src下的全路径名称

例如:

    <select id="findAllUser" resultType="com.ling.mybatis.pojo.User">select * from user</select>

insert标签

主要用于书写insert相关sql语句

id属性

设置sql语句名称,为了方便分清结构层次,以及后续工具的使用建议使用对应的方法名称

<insert id="insertUser">insert into user values(#{id},#{username},#{password})
</insert>

update标签

主要用于书写update相关sql语句

id属性

设置sql语句名称,为了方便分清结构层次,以及后续工具的使用建议使用对应的方法名称

    <update id="updateUser">update user set password = #{password} WHERE id = #{id};</update>

delete标签

主要用于书写delete相关sql语句

id属性

设置sql语句名称,为了方便分清结构层次,以及后续工具的使用建议使用对应的方法名称

    <delete id="deleteUser">delete from user where id = #{id}</delete>

使用测试方法测试程序运行是如何实现的?每条语句起什么作用?

首先我们使用以下基础执行代码作为例子进行说明

@Testpublic void test1() throws IOException {//定义mybatis核心配置文件在classes下的路径String mybatisPath = "mybatisConfig.xml";//根据路径获取字节输入流对象InputStream is = Resources.getResourceAsStream(mybatisPath);//创建SqlSessionFactoryBuilder对象SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();//通过SqlSessionFactoryBuilder对象的build方法创建SqlSessionFactory对象SqlSessionFactory factory = sqlSessionFactoryBuilder.build(is);//通过工厂类的openSession方法获取sql执行对象SqlSession sqlSession = factory.openSession();//sql执行对象的selectOne方法//获取第一个参数,即执行id:由namespace + . + SQL语句标签idString id = "com.ling.mybatis.dao.UserDao" + "." + "findUserById";User user = sqlSession.selectOne(id);System.out.println(user);//关闭sqlSessionsqlSession.close();}

基础步骤

第一步:设置中心配置文件的路径

第二步:使用Resources静态方法,将中心配置文件加载进字节输入流

第三步:获取SqlSessionFactoryBuilder对象,该对象的主要任务是创建factory对象

第四步:使用SqlSessionFactoryBuilder对象的build方法,传入字节输入流,解析中心配置文件,初始化数据库连接池,并且获取各个dao配置文件。

第五步:通过SqlSessionFactory对象的openSession方法获取sqlSession执行对象,该对象主要用于sql语句的执行操作。

第六步:定义字符串,锁定需要执行的语句

第七步:执行sql语句

SqlSessionFactory接口

接口作用

SqlSessionFactory接口是sqlSession的工厂接口,主要作用是创建SqlSession对象

SqlSessionFactory功能众多,创建过程较之其他比较缓慢,需要更多的时间和空间,在项目中有一个即可。

接口方法

openSession();获取一个默认的SqlSession对象,默认是需要手动提交事务的

openSession(boolean):boolean参数表示是否自动提交事务

true:创建一个自动提交事务的SqlSession

false:等同于没有参数的openSession

SqlSession接口

接口作用

提供了大量的执行sql语句的方法,线程不安全

针对线程不安全,需要注意使用步骤

使用步骤

1.在方法内部执行sql语句之前,先获取sqlSession对象

2.调用sqlSession方法对象,执行sql语句

3.关闭sqlSession,执行sqlSession的close方法

如此一来,该sqlSession就只在方法内存在,在该方法所在执行的线程空间内存在,这样其他线程就无法获取这条线程内的数据对象。

接口方法

selectOne(String,Object):执行返回值只有一行的执行结果,多余一行会执行错误

selectMap(String,Object):执行返回一个map类型的接口

selectList(String,Object):执行返回一个list集合数据

insert(String,Object):执行添加操作

update(String,Object):执行修改操作

delete(String,Object):执行删除操作

commit:执行事务提交操作

rollback:执行事务回滚操作

MybatisUtils工具类

由上文实现步骤我们可以看出,每一次进行数据库操作我们都需要进行以上七步的操作,但是七步操作中有大量的代码冗余,一到五步代码基本大致相同,因此我们可以写构造一个MybatisUtils工具类,专门用于mybatis初始化操作。

public class MybatisUtils {private static SqlSessionFactory sqlSessionFactory = null;//通过静态代码块,当类进行加载时赋值static {String sqlPath = "mybatisConfig.xml";try {//根据核心配置文件路径获取字节输入流InputStream resource = Resources.getResourceAsStream(sqlPath);//使用Builder对象的build方法获取factory对象sqlSessionFactory = new SqlSessionFactoryBuilder().build(resource);} catch (IOException e) {e.printStackTrace();}}//获取SqlSession对象(不自动提交事务)public static SqlSession getSqlSession(){//openSession方法中没有参数,则取消自动提交。传入true则打开自动提交return sqlSessionFactory.openSession();}
}

此时我们简化了前五步步骤,但是第六步简单的字符串拼接和第七步方法的执行还是没有简化,而且我们在使用的过程中发现,接口好像根本没啥作用,接口的方法没有被调用,接口也没有实现类,接口好像白写了?

实现dao接口

按照Javaweb学习阶段三层架构的代码书写习观我们创建impl文件夹,并且于文件夹内部创建dao接口实现类。

public class UserDaoImpl implements UserDao {@Overridepublic List<User> findAllUser() {SqlSession sqlSession = MybatisUtils.getSqlSession();String sqlPath = "com.ling.mybatis.dao.UserDao.findAllUser";List<User> list = sqlSession.selectList(sqlPath);sqlSession.close();return list;}
}

我们将第六步第七步的操作步骤放到了接口实现类中,这样就完成了整合,当我们需要调用方法进行sql语句操作时,创建dao接口实现类对象,执行其对应的方法即可。

但是对于以上整合方案并不能帮助我们简化程序书写的步骤,只是简单的对数据操作进行了整合操作,我们需要一种可以直接完成数据操作的方法

使用代理模式

mybatis的dao代理

代码书写

getMapper(dao接口的class类)

@Testpublic void test2() {SqlSession sqlSession = MybatisUtils.getSqlSession();UserDao userDao = sqlSession.getMapper(UserDao.class);userDao.findUserById(1);sqlSession.close();}

通过sqlSession的getMapper方法获取代理对象,我们在学习Spring框架的Aop增强时学习过了proxy代理模式,主要工作原理是通过反射机制创建目标增强对象的子类,并且在不改变原方法内容的情况下强化方法的参数,内容,返回值。

这里的getMapper方法就是使用代理模式,创建userDao的实现类对象,并且通过类加载器和反射机制获取UserDao的路径名,以及方法名,自动的完成拼接,并且选择合适的sqlSession方法执行增删改查的操作。这里就回收了为什么我们在设置dao层配置文件namespace属性尽量要设置为dao接口src下全路径,为什么sql语句标签id要设置为方法名。

理解参数

通过Java程序把数据传入到mapper文件中的sql语句,这里的参数主要是指dao接口方法中的形参

parameterType

表示参数类型,指定dao方法的形参数据类型。这个形参的数据类型是给mybatis使用。mybatis在给sql语句的参数赋值时使用,我们在jdbc中学习过的防止sql语句注入,使用preparedStatement对象。我们对?内容进行属性值注入时,需要使用对应的setXXX(索引,值)方法进行输入,这里的parameterType就是在选择注入的属性类型。

<select id="findUserById" parameterType="java.lang.Integer" resultType="com.ling.mybatis.pojo.User">select * from user where id = #{id}
</select>

mybatis可以使用反射机制获取dao接口方法参数类型,因此parameterType可以省略不写

传递一个简单类型参数

简单类型:Java中的基础数据类型

当传递的参数时一个简单类型的参数时,mapper文件使用#{任意字符}获取这个参数值

<select id="findUserById"  resultType="com.ling.mybatis.pojo.User">select * from user where id = #{id}
</select>

传递多个简单类型参数

使用@Param注解,用于命名参数,在方法的形参前面使用,定义参数名。这个名称要用于mapper文件中,也就是#{}内的值就是参数命名后的名称

    List<User> findUserByIdOrUsername(@Param("Sid") Integer id, @Param("Susername") String username);
    <select id="findUserByIdOrUsername" resultType="com.ling.mybatis.pojo.User">select * from user where id = #{Sid} or username = #{Susername}</select>

使用实体类属性传递参数

方法参数直接传入一个实体类,那么mybatis就会自动解析实体类属性,并且根据属性名称查找配置文件中#{}内的参数名称,如果匹配,那么就赋值。

int insertUser(User user);
    <insert id="insertUser">insert into user values(#{id},#{username},#{password})</insert>

按照位置传递参数

按照位置传参,接口中的多个参数就不需要添加@Param注解起别名,只需要在sql语句中使用#{arg索引}就可以指定传入第几个参数

List<User> findUserByIdOrUsername(Integer id, String username);
    <select id="findUserByIdOrUsername" resultType="com.ling.mybatis.pojo.User">select * from user where id = #{arg0} or username = #{arg1}</select>

使用map传参

map中的key值就对应了#{}中的名称,value值即为注入的值。

List<User> findUserByIdOrUsername(Map map);
<select id="findUserByIdOrUsername" resultType="com.ling.mybatis.pojo.User">select * from user where id = #{id} or username = #{username}</select>

#占位符与$占位符的区别

#占位符实际上是PrepareStatement编译了sql语句之后对于值的一个注入,而$占位符做的是简单的字符串拼接,也就是使用普通的Statement。

$特点:

1.使用的是Statement对象,执行SQL语句时效率低

2.${}占位符,使用的是字符串拼接的方式,有sql注入的风险,有代码安全性问题

3.${}数据是原样使用的,不会区分数据类型

4.${}常常用作表名或者列名,在能保证数据安全的情况下使用${}

#特点:

1.使用PrepareStatement对象,执行sql语句,效率高。

2.使用PrepareStatement对象,能够避免sql语句注入问题,SQL语句执行更安全

3.#{}常常作为列值使用,位于等号的右侧,#{}位置的值和数据类型有关

封装MyBatis输出结果

resultType

resultType属性:在执行select时使用,作为<select>标签的属性出现的

resultType:表示结果类型,mysql执行sql语句,得到java对象出现的类型,他的值有两种

1.java类型的全限定名称(我们之前一直使用的)

2.在中心配置文件中设置的别名

别名我在第一篇文章中讲解中心配置文件的时候详细说过,他是在中心配置文件的typeAliases标签内部设置的,如果使用package标签取别名,那么就是整包一起取,如果使用typeAlias标签的话就是一个一个取,具体的优缺点可以看我的第一篇文章。

中心配置文件:

<typeAliases><!--路径名之间用/隔开或者用.隔开都行--><!--给一个包下所有类取别名,别名就是类名,不用区分大小写--><package name="com.ling.mybatis.pojo"/><!--给一个单独的类起任意别名--><typeAlias type="com.ling.mybatis.pojo.User" alias="user"></typeAlias>
</typeAliases>

dao层配置文件:

<select id="findUserById" resultType="user">select * from user where id = #{id}
</select>

当查询结果为自定义类型时

其实就是我们一直写的以User作为返回值结果,这就是将查询的结果封装到类对象中。

当sql语句查询到数据后,mybatis会根据resultType会根据配置内容使用java反射调用无参构造器创建对象,然后将获取到的结果集对应的key值与对象属性值进行比对,如果属性名称相同就把值注入到对象中。如果查询到多行数据,那么就会创建多个对象,并且将对象存放入list集合中。

User findUserById(Integer id);
    <select id="findUserById" resultType="user">select * from user where id = #{id}</select>

当查询的结果为简单类型时

设置resultType直接设置为java中的路径

    <select id="getSum" resultType="java.lang.Integer">select count(*) from user</select>
Integer getSum();

当查询结果为Map类型时

mybatis会将sql语句查询结果以键值对的形式添加到map集合中,但是如果使用map作为返回值,那么该程序执行结果只能有一行查询结果,多了就会报错

    <select id="getMapper" resultType="java.util.Map">select * from user where id = #{id}</select>
Map<Object,Object> getMapper(Integer id);

resultMap自定义查找结果

使用resultMap可以自定义结果集中属性与对象属性的对应关系,常用于对象属性与查询结果列名不相同的情况。

如何使用:

1.主键名使用id标签,column指定结果集中的列名,property指定类中的属性名。

2.其他列名使用result标签,column指定结果集中的列名,property指定类中的属性名。

3.id属性用于设置该结果集的名称

4.type属性用于指定需要匹配的类

5.select标签中resultMap属性设置为resultMap标签中的id值

List<UserDocument> findAllUserDocument();
    <resultMap id="userDocument" type="com.ling.mybatis.pojo.UserDocument"><!--设置列名与类属性的对应关系--><!--主键名使用id标签一一对应--><id column="id" property="userId"></id><!--其他属性使用result标签一一对应--><result column="age" property="userAge"></result><result column="game" property="userGame"></result></resultMap><select id="findAllUserDocument" resultMap="userDocument">select * from userdocument</select>

select标签属性resultMap获取了配置相关信息的resultMap标签唯一名称,通过唯一名称查找到了配置好的resultMap,根据type属性获取返回值类型,并且解析id标签与result标签内容,获取属性值对应关系,最后将查找到的值首先按照对应关系赋值,然后正常赋值。

有关like查询

当查询语句需要使用like

例如:select * from user where name like %zhang%;

第一种:将%zhang%整体作为一个字符串传入

List<User> findUserLike1(String username);
    <select id="findUserLike1" resultType="com.ling.mybatis.pojo.User">select * from user where username like #{username}</select>
@Testpublic void test(){SqlSession sqlSession = MybatisUtils.getSqlSession();UserDao userDao = sqlSession.getMapper(UserDao.class);List<User> list = userDao.findUserLike1("%z%");for (User user : list) {System.out.println(user);}sqlSession.close();}

第二种:在sql语句中按照标准书写,"%" 值 "%" 值...  其中%与值中间必须有空格

List<User> findUserLike2(String username);
    <select id="findUserLike2" resultType="com.ling.mybatis.pojo.User">select * from user where username like "%" #{username} "%"</select>
@Testpublic void test(){SqlSession sqlSession = MybatisUtils.getSqlSession();UserDao userDao = sqlSession.getMapper(UserDao.class);List<User> list = userDao.findUserLike1("z");for (User user : list) {System.out.println(user);}sqlSession.close();}

MyBatis基础学习知识点2相关推荐

  1. MyBatis基础学习知识点3

    目录 动态sql语句 if标签 where标签 foreach标签 sql标签 动态sql语句 if标签 在主SQL语句之间使用,用于sql语句的拼接 例如: <select id=" ...

  2. Mybatis基础学习之万能的Map和模糊查询

    前言: 小伙伴们,大家好,我是狂奔の蜗牛rz,当然你们可以叫我蜗牛君,我是一个学习Java半年多时间的小菜鸟,同时还有一个伟大的梦想,那就是有朝一日,成为一个优秀的Java架构师. 这个Mybatis ...

  3. Mybatis基础学习之一级缓存和二级缓存的简单使用

    前言: 小伙伴们,大家好,我是狂奔の蜗牛rz,当然你们可以叫我蜗牛君,我是一个学习Java半年多时间的小菜鸟,同时还有一个伟大的梦想,那就是有朝一日,成为一个优秀的Java架构师. 这个Mybatis ...

  4. 黑马程序员_毕向东_Java基础视频教程_Java基础学习知识点总结

    黑马程序员_毕向东_Java基础视频教程 Java基础学习知识点总结 2016年01月06日  day01 一.基础知识:软件开发 1.什么是软件?软件:一系列按照特定顺序组织的计算机数据和指令的集合 ...

  5. mybatis基础学习小记

    mybatis基础应用学习记录 1.创建项目 创建一个maven项目 2. 配置mybatis xml配置文件 3.相关代码 4.使用mybatis 5.到此mybatis入门使用就算完结了,后续还得 ...

  6. mybatis基础学习4-插件生成器(根据数据库的表生成文件)

    1:安装(根据数据库的表生成文件) 2:在所建项目单击右键输入mybatis如下图 *建项目文件时不用建包和类,插件可以根据数据表自动生成,在配置文件(generatorConfig.xml)里写即可 ...

  7. MyBatis基础入门--知识点总结

    对原生态jdbc程序的问题总结 下面是一个传统的jdbc连接oracle数据库的标准代码: public static void main(String[] args) throws Exceptio ...

  8. 前端学习笔记01---HTML5、CSS3、移动端前端基础学习知识点合集

    文章目录 HTML结构 一.标签(标记.元素) 二.列表,表格,表单 1.列表 2.图片 3.超链接--实现不同页面的跳转 4.table表格 5.表单1 --收集用户信息给后端input CSS表现 ...

  9. mybatis基础学习3---特殊sql语句(备忘)

    1: 2:  3:resultMap的用法 转载于:https://www.cnblogs.com/kaiwen/p/6486283.html

最新文章

  1. 听说你 ping 用的很 6 ?给我图解一下 ping 的工作原理!
  2. 如何利用OpenCV寻找轮廓的中心?
  3. Linux怎么查看设置系统语言包
  4. as my sql 后面加表达式_SQL.WITH AS.公用表表达式(CTE)(转)
  5. spark数据本地性级别划分
  6. Google App Engine 功能被滥用于创建无限制的钓鱼页面
  7. java入门第二季--封装--java中的this
  8. paip.为什么软件体积越来越大
  9. CImageList
  10. 结构梁配筋最牛插件_老师傅总结建筑结构设计技巧经验,看完涨知识了
  11. 斗地主功能测试实战二之用例设计
  12. 【FPGA+PWM】基于FPGA的三相PWM整流器移相触发电路的设计与实现
  13. nc数据处理,掩膜,经纬度定位格点
  14. 并发安全的计数统计类:AtomicLong和LongAdder
  15. Flixel横板游戏制作教程(四)— RandomLevels
  16. 亚马逊中国站获取全部商品分类
  17. (6.1)各种USB接口简介
  18. Javascript定义类或对象之动态原型法
  19. Java经典好资源-[http://blog.csdn.net/miaogang]
  20. Zotero简易使用教程

热门文章

  1. 排位赛一 A Cow Gymnastics
  2. 在数智化供应链里,「重估」京东云
  3. 历时17小时的暖心春运 衢州火车站助84岁老人回家
  4. 盖茨:原本想等孩子进入大学后 与保罗·艾伦共度更多时光
  5. 翻译Stairway to SQL Server Security Level 3: Principals and Securables
  6. 甘肃西部河谷科技有限公司官网上线 | LTD技术行业案例分享
  7. mac版phpstorm中文切换为英文
  8. ESP8266连接腾讯云物联网平台
  9. 从来没有一种工作叫:钱多事少离家近,位高权重责任轻
  10. 四大名著之精选22句名言:经典即是永恒,蕴藏人生哲理