Mybatis学习笔记
MyBatis学习笔记
第一章 框架概述
框架:
三层架构:页面层,业务逻辑层,数据访问层
框架:是一个半成品软件,定义好了一些基础功能,需要加入你的功能就是完善的,基础功能时可以重复使用的,可升级的。
框架特点:一般不是全能的,针对某一个领域有效
JDBC缺陷:
代码冗余(处理结果集的时候代码冗余,以及整个jdbc操作,核心语句没几句,其他都是重复的)
不能自动完成实体类和查询结果的映射(需要在处理结果集的时候手动把查询结果封装到实体类)
MyBatis框架概述
MyBatis SQL Mapper Framework For Java
SQL mapper:
sql映射,可以把数据库中的一行数据,映射为一个java对象,操作这个对象,就相当于操作表中的数据
Data Aceess Object:(DAOS)
数据库访问,对数据库进行增删改查操作
mybatis提供了哪些功能?
- 提供了创建Connection、Statement、ResultSet的能力,不用开发人员创建这些对象了
- sql语句执行能力
- 循环sql能力,把sql结果转化为java对象,List集合的能力
- 关闭资源的能力,关闭Connection、Statement、ResultSet
开发人员提供sql语句——mybatis处理sql——开发人员得到List集合或java对象(表中的数据)
总结:
mybatis是一个sql映射框架,提供操作数据库的能力,增强的JDBC,开发人员集中写sql就行了,不用关心Connection、Statement、ResultSet的创建、关闭,sql执行。
第二章 mybatis入门
入门案例:
实现步骤:
数据库新建student表
创建java项目,加入maven的mybatis坐标、mysql驱动坐标
创建实体类
创建持久层的dao接口,定义操作数据库的方法
创建一个mybatis使用的配置文件,叫做sql映射文件,用来写sql语句的,一班一个表一个sql映射文件,这个文件是xml文件,写在接口所在的目录中,文件名和接口保持一致
创建mybatis主配置文件,一般一个项目一个主配置文件,主配置文件提供了数据库的连接信息和sql映射文件的位置信息
创建使用mybatis类
主要类的介绍
1.Resource:mybatis中的一个类,负责读取主配置文件
1 |
|
2.SqlSessionFactoryBulider:创建SqlSessionFactory对象,
1 |
|
3.SqlSessionFactory:重量级对象,程序创建一个对象耗时较长,使用资源比较多,在整个项目中,有一个就够用了。
1 |
|
4.SqlSession:接口,定义了操作数据的方法,selectOne(),selectList(),insert(),update(),delete(),commit(),rollback()等
1 |
|
使用要求:SqlSession对象不是线程安全的,需要在方法内部使用,在sql语句执行之前,使用openSession()获取SqlSession对象,在sql语句执行之后,使用SqlSession.close()关闭,确保它是线程安全的。线程安全就是避免共享数据被污染。
第三章
1.动态代理:
mybatis帮你创建接口实现类,在实现类中调用SqlSession的方法执行sql语句
要求:
- dao接口和mapper文件放在一起,同一个目录
- dao接口和mapper文件名称一致
- mapper文件中的namespace值是dao接口的全限定名称
- mapper文件中的
<select><update><insert>
等标签的id值dao接口中的方法名称 - dao接口中不要使用重载方法
使用SqlSession.getMapper(dao接口.calss)获取这个dao接口的对象,是一个动态代理对象
1 |
|
2.传入参数:
从java代码中把数据传入到mapper文件的sql语句中
parameType:写在mapper文件中的一个属性,表示dao接口中方法的参数的数据类型
1
2
3
4
5
6
7
8pubulic Student selectAll(Int id);
<!--
parameType:dao接口中方法参数的数据类
值是java数据类型的全限定名或者是mybatis定义的别名
例如:parameType="java.lang.Integer"
parameType="int"
注意:别名不是必需的,因为mybatis通过反射可以知道接口中方法的参数的类型
-->一个简单类型的参数
1
2
3<!--
在mapper文件中,获取一个简单类型的一个参数的值,使用#{任意字符}
-->多个参数@Param命名参数(常用)
1
2
3接口:public List<Student> selectMultiParam(String nane,int age);
使用:@Param("参数名") String name
public List<Student> selectMultiParam(@Param("name")String nane,@Param("age")Int age);多个参数——使用对象(常用)
1
最完整方式:很少用#{对象的属性名,javaType类型名称,jdbcType数据类型} #{Student,javaType=java.lang.String,jdbcType=VARCHAR}简化方式:常用#{对象的属性名} javaType类型名称,jdbcType数据类型反射获取不用写
多个参数——按位置
1
mybatis3.4之前,使用#{0},#{1}mybatis3.4之后,使用#{arg0},#{arg1}
多个参数——使用Map
1
使用语法:#{map中的key}
3.#和$的区别
#:占位符,使用PrepareStatement对象执行sql语句,相当于jdbc中的 ?
$:字符串替换,使用Statement对象执行sql语句
$ 可以替换列名或者表名
4.mybatis输出结果
mybatis执行sql语句后,得到的java对象
resultType结果类型:
指sql语句执行完毕后,数据转为java对象,是任意类型的对象
处理方式:
- mybatis执行sql语句,然后mybatis调用类的无参构造方法,创建对象
- mybatis把ResultSet指定列值赋给同名的属性
自定义类型的别名:
不建议使用别名,建议使用全限定名
在mybatis主配置文件中定义,
1 |
|
1 |
|
Map:
列名是map的可以,列值是map的value
返回map的时候最多只能返回一行记录,否则报错
resultMap:
结果映射,指定列名和java对象的属性对应关系
- 自定义列值赋值给哪个属性
- 当你的列名和属性名不一样时,一定是要resultMap
注:resultType和resultMap不要一起使用
当你的列名和属性名不一样时:
第一种方式:resultMap
1 |
|
第二种方式:起列别名
1 |
|
5.模糊查询
like查询
1 |
|
1 |
|
1 |
|
第四章 动态Sql
动态sql:sql的内容是变化的,可以根据条件获取到不同sql语句,主要是指where部分,使用的是mybatis提供的标签,<if> <where> <foreach>
<if>
是判断条件的,语法:1
<if test="判断java对象的属性值"> 部分sql语句</if>
1
//动态sql,使用java对象作为参数List<Student> selectStudentIf(Student student);
1
<!--动态sql<if test="使用参数java对象的属性值作为判断条件 "--><select id="selectStudentIf" resultType="yxnu.edu.entity.Student"> select id,name,email,age from student where 1=1 <if test="name!=null and name!=''"> name=#{name} </if> <if test="age>0"> and age>#{age} </if></select>
1
/** * 测试动态sql */ @Test public void test8(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); Student student = new Student();// student.setName("李卡斯"); student.setAge(22); List<Student> list = dao.selectStudentIf(student); for (Student student1 : list) { System.out.println(student1); } }
如果是第一个
<if>
部门,不满足的话,在where 后面加上1=1或者id>0等恒成立条件,这样的话第二个<if>
才不会sql语法报错<where>
是用来包含多个<if>
的,当多个<if>
有一个成立的,<where>
会自动增加一个where关键字,并去掉 if 中多余的 and ,or等,这样的话就不用加什么1=1之类的了。1
<select id="selectStudentIf" resultType="yxnu.edu.entity.Student"> select id,name,email,age from student <where> <if test="name!=null and name!=''"> name=#{name} </if> <if test="age>0"> and age>#{age} </if> </where></select>
<foreach>
循环java中的数组,list集合的,主要用在sql的 in 语句中1
学生id是1001,1002,1003的三个学生select * from student where id id(1001,1002,1003)
1
<foreach collection="" item="" open="" close="" separator=""> </foreach>
collection:表示接口中的方法的参数的类型,如果是数组使用array,如果是list集合使用list
item:自定义的,表示数组和集合成员的变量
open:循环开始的字符
close:循环结束时的字符
separator:集合成员之间的分隔符
1
//foreach 用法1List<Student> selectForeach(List<Integer> list);//foreach 用法2List<Student> selectForeachTwo(List<Student> stulist);
1
<!--foreach使用1--><select id="selectForeach" resultType="yxnu.edu.entity.Student"> select * from student where id in <foreach collection="list" item="myid" open="(" close=")" separator=","> #{myid} </foreach></select><!--foreach使用2--><select id="selectForeachTwo" resultType="yxnu.edu.entity.Student"> select * from student where id in <foreach collection="list" item="stu" open="(" close=")" separator=","><!-- 相当于使用对象的getId()--> #{stu.id} </foreach></select>
1
/** * 测试foreach用法1 */@Testpublic void test9() { SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); List<Integer> list = new ArrayList<>(); list.add(1001); list.add(1002); list.add(1003); List<Student> list1 = dao.selectForeach(list); for (Student student : list1) { System.out.println(student); }}/*** 测试foreach用法2*/ @Test public void test10(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); List<Student> stulist=new ArrayList<>(); Student student = new Student(); student.setId(1005); stulist.add(student); student = new Student(); student.setId(1006); stulist.add(student); List<Student> lists = dao.selectForeachTwo(stulist); for (Student list : lists) { System.out.println(list); } }
sql代码片段,就是复用一些sql语句
步骤:先定义,再使用
1
1.先定义<sql id="自定义名称唯一"> sql语句,表名,字段等 </sql> 2.使用,<include refid="id值"/>
第五章
1.数据库的属性配置文件,把数据库连接信息放到一个单独的properties文件中,和mybatis主配置文件分开
在resources目录下定义一个属性配置文件,例如 jdbc.propertoes
key:一般做多级目录,两级三级比较合适
jdbc.mysql.driver jdbc.driver
1
2
3
4
5
6
7
8
9
10mybatis主配置文件
<!--指定properties文件的位置,从类路径开始找文件-->
<properties resource="jdbc.properties"/>
在resources目录下定义jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
...
<property name="driver" value="${jdbc.driver}"/>
...
2.多个mapper文件
第一种就是写多个
<mapper>
使用包名,
<package name="存放mapper文件的全限定包名"/>
,这样这个包下所有的mapper文件一次都能加载给mybatis主配置文件使用要求:
- mapper文件名称要和接口名称一样,区分大写的一样
- mapper文件和dao接口在同一目录
第六章 扩展
PageHelper:用来做数据分页查询