MyBatis
2022-06-22 09:14:28 52 举报
AI智能生成
MyBatis学习笔记!!!!Spring,SpringMVC都开放克隆了,mybatis之前忘记了,开一下
作者其他创作
大纲/内容
其他
阿里巴巴开发手册
GoogleJava编程风格指南
关于#和$的区别
1、 #就是PreparedStatement 安全,效率比$高
2、 $就是Statement 不安全,sql注入
3、 #就是?之后填充占位符
4、$就是字符串的连接,可以用在能够保证数据安全的情况下
模糊查询的两种方式
1、直接传入字符串进行模糊查询
String likeName = "%张%";
List<Student> studentList = studentDao.selectLikeOne(likeName);
studentList.forEach(stu -> System.out.println(stu));
List<Student> studentList = studentDao.selectLikeOne(likeName);
studentList.forEach(stu -> System.out.println(stu));
2、在mapper文件中拼接模糊查询
<select id="selectLikeTwo" resultType="Student">
select id,name,email,age from student where name like "%" #{name} "%"
</select>
select id,name,email,age from student where name like "%" #{name} "%"
</select>
初识框架
java框架就是一些类和接口的集合,通过这些类和接口协调来完成一系列的程序实现。JAVA框架可以分为三层:表示层,业务层和物理层。框架又叫做开发中的半成品,它不能提供整个WEB应用程序的所有东西,但是有了框架,我们就可以集中精力进行业务逻辑的开发而不用去关心它的技术实现以及一些辅助的业务逻辑。大家熟知的Structs和Spring就是表示层和业务层框架的强力代表。
现在具有代表性的框架:Spring+SpringMVC+Mybatis
框架的三层架构
1、界面层(User Interface layer)比如:jsp,html还有直接和用户交互的servlet对应的包:controller
2、业务逻辑层(Business Logic layer)比如:service,处理业务逻辑,调用dao对应的包:service
3、数据访问层(Data Access layer)比如:dao,持久层对应的包:dao
4、框架对应
界面层--------> springMVC
业务逻辑层----> spring
持久层--------> mybatis
界面层--------> springMVC
业务逻辑层----> spring
持久层--------> mybatis
mybatis简介:
MyBatis 本是apache的一个开源项目iBatis
2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。
2013年11月迁移到Github。iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。
iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)
当前,最新版本是MyBatis 3.5.4 ,其发布时间是2020年2月4日。(又有新版本了)
2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。
2013年11月迁移到Github。iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。
iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)
当前,最新版本是MyBatis 3.5.4 ,其发布时间是2020年2月4日。(又有新版本了)
下载地址:https://github.com/mybatis/mybatis-3/releases
mybatis-开发步骤
1、新建表,我这里新建了一个student表
2、加入依赖
1、mysql依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
2、mybatis依赖
<!-- mybatis的依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
3、 创建实体类Student,保存表中的数据
4、 创建持久层的dao接口,定义操作数据库的方法
就是CRUD方法
5、创建sql映射文件,也就是sql-mapper文件
是用来写sql语句的,一般来说一个表对应一个sql映射
这个文件是一个xml文件
- 这个文件写在和接口同一个目录之下
- 这个文件的名字和接口名相同
- 这个文件写在和接口同一个目录之下
- 这个文件的名字和接口名相同
6、 创建一个mybatis的主配置文件
一个项目就一个主配置文件
主配置文件提供了数据库的连接信息,以及sql映射文件位置信息
7、mybatis执行sql语句的步骤
1、指定mybatis主配置文件位置:String config = "mybatis.xml";
编译后的target目录就是类路径,就是根路径
2、以流的形式读取这个配置文件:InputStream is = Resources.getResourceAsStream(config);
3、创建SqlSessionFactory工厂建造者对象:SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
4、建造者通过builder方法建造工厂:SqlSessionFactory factory = builder.build(is);,
建造工厂需要主配置文件就是is通过流读取到
5、通过工厂的open方法创建车间也就是SqlSession对象:SqlSession sqlSession = factory.openSession();
【重点】
6、指定需要执行的sql语句标识,sql映射文件的namespace+.+标签的id:String sqlId = "com.javase.mybatis.dao.StudentDao"+"."+"selectStudents";
这里的具体内容看下面的文件配置
7、执行sql语句,通过sqlId查找sql语句
8、输出结果
studentList.forEach(student -> System.out.println(student));
studentList.forEach(student -> System.out.println(student));
9、关闭对象
sqlSession.close();
sqlSession.close();
10、通过工具类封装这些执行步骤
工厂通过静态代码快在类加载是执行一次
private static SqlSessionFactory factory = null;
static {
String config = "mybatis.xml";
try {
InputStream is = Resources.getResourceAsStream(config);
factory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
e.printStackTrace();
}
}
private static SqlSessionFactory factory = null;
static {
String config = "mybatis.xml";
try {
InputStream is = Resources.getResourceAsStream(config);
factory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
e.printStackTrace();
}
}
1、自动提交事务
/**
* 获取sqlSession对象,并且设置自动提交事务
* @param autoCommit true则自动提交事务
* @return SqlSession对象
*/
public static SqlSession getSqlSession(boolean autoCommit){
SqlSession sqlSession= null;
if (factory != null){
sqlSession = factory.openSession(autoCommit);
}
return sqlSession;
}
2、手动提交事务
/**
* 获取sqlSession对象,设置不自动提交事务,需要手动提交
* @return SqlSession对象
*/
public static SqlSession getSqlSession(){
SqlSession sqlSession= null;
if (factory != null){
sqlSession = factory.openSession();
}
return sqlSession;
}
* 获取sqlSession对象,设置不自动提交事务,需要手动提交
* @return SqlSession对象
*/
public static SqlSession getSqlSession(){
SqlSession sqlSession= null;
if (factory != null){
sqlSession = factory.openSession();
}
return sqlSession;
}
【默认】
8、通过JDK动态代理创建对象
1、 StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
2、这个studentDao就是dao接口的代理类,并且和映射文件联系了起来
1、getMapper()底层执行流程分析
1、SqlSession.java 的默认实现:DefaultSqlSession.java
2、DefaultSqlSession.java重写父类的方法:
@Override
public <T> T getMapper(Class<T> type) {
return configuration.getMapper(type, this);【这里就已经吧SudentDao.class和sqlSession传进去了】
}
3、configuration.java的getMapper源码
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return mapperRegistry.getMapper(type, sqlSession);
}
4、MapperRegistry.java这个类的getMapper源码:
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
//根据接口类型获取一个mapperProxyFactory
final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
}
try {
//
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception e) {
throw new BindingException("Error getting mapper instance. Cause: " + e, e);
}
}
5、 return mapperProxyFactory.newInstance(sqlSession);
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
6、 创建代理对象
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}
1、SqlSession.java 的默认实现:DefaultSqlSession.java
2、DefaultSqlSession.java重写父类的方法:
@Override
public <T> T getMapper(Class<T> type) {
return configuration.getMapper(type, this);【这里就已经吧SudentDao.class和sqlSession传进去了】
}
3、configuration.java的getMapper源码
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return mapperRegistry.getMapper(type, sqlSession);
}
4、MapperRegistry.java这个类的getMapper源码:
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
//根据接口类型获取一个mapperProxyFactory
final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
}
try {
//
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception e) {
throw new BindingException("Error getting mapper instance. Cause: " + e, e);
}
}
5、 return mapperProxyFactory.newInstance(sqlSession);
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
6、 创建代理对象
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}
9、参数传递的五种类型
1、普通的一个数据类型
直接通过占位符进行赋值。#{参数名}
2、两个以上的数据,通过@Param(“重命名”)
Student selectStudents(@Param(id) Integer id, @Param(name) String name);
读取的时候直接就是填充占位符:id = #{id},name = #{name}
读取的时候直接就是填充占位符:id = #{id},name = #{name}
3、使用对象
Student selectStudents(Student student);
select id,name,email,age from student where id = #{id} or name = #{name}
select id,name,email,age from student where id = #{id} or name = #{name}
4、使用参数的位置进行传参
注意:在mybatis3.4版本之前使用的是#{0},#{1}
Student selectStudents(Integer id, Integer age)
select id,name,email,age from student where id = #{arg0},age=#{arg1}
Student selectStudents(Integer id, Integer age)
select id,name,email,age from student where id = #{arg0},age=#{arg1}
5、 使用map集合传参数
Map<String,Object> map = new HashMap<>();
map.put("name",name);
map.put("id",id);
Student selectStudents(Map map);
select id,name,email,age from student where id = #{id},name = #{name}
map.put("name",name);
map.put("id",id);
Student selectStudents(Map map);
select id,name,email,age from student where id = #{id},name = #{name}
mybatis-sql映射文件
1、配置文件是一个xml文件
文件名:和dao接口名完全一直。
比如:接口是StudentDao,这个mapper文件名必须是StudentDao.xml
2、文件头部是:
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
1、 这是一个约束文件
2、 mybatis-3-mapper.dtd,这个是约束文件的名称,是一个dtd文件
就是固定的,规定了这个文件中的内容必须是他规定好的标签才行
就是固定的,规定了这个文件中的内容必须是他规定好的标签才行
3、根标签:<mapper>
<mapper namespace="com.javase.mybatis.dao.StudentDao">
</mapper>
<mapper namespace="com.javase.mybatis.dao.StudentDao">
</mapper>
1、 mapper是这个文件的根标签,是固定的
2、 namespace叫做命名空间,是个唯一值,可以是自定义的字符串,但是一般都是
dao接口的全限定名称
dao接口的全限定名称
全限定名称:完整包名+类名
4、关于mapper标签中可以出现的四个标签
1、 select:查询语句
2、 update:更新语句
3、 delete:删除语句
4、 insert:插入语句
5、关于增删改的标签
<insert id="insertStudent">
insert into student values (#{id},#{name},#{email},#{age})
</insert>
1、增删改标签都是只有一个属性就是ID,是这个sql语句的唯一标识。
6、关于select标签
例子:
<select id="selectStudents" resultType="com.javase.mybatis.domain.Student">
select id,name,email,age from student order by id
</select>
<select id="selectStudents" resultType="com.javase.mybatis.domain.Student">
select id,name,email,age from student order by id
</select>
1、 id:要执行的sql语句的唯一标识,使用接口中的方法名称selectStudents
List<Student> selectStudents();
2、 resultType:表示结果类型,是sql语句执行后得到的ResultSet的这个java对象的类型
这个值写的是类型的权限定名称:包名+类名
这个值写的是类型的权限定名称:包名+类名
这个结果就是List集合中的Student,因此是填写学生类的全限定名称
7、关于mapper文件中resultType的填写
是结果集中封装的那个数据,比如说是List<Student> 就是Student,一般需要写全限定名称比如com.javase.dao.domain.Student
简化:需要在主配置文件中声明
<typeAliases>
<!-- 定义别名,这个类对应的别名数stu,则resultType就可以是stu -->
<typeAlias type="com.javase.domain.Student" alias="stu"/>
<!-- 省略包名,就是说这个包中的类只需要填写类名即可比如:这个时候直接就是Student -->
<package name="com.javase.domain"/>
</typeAliases>
<typeAliases>
<!-- 定义别名,这个类对应的别名数stu,则resultType就可以是stu -->
<typeAlias type="com.javase.domain.Student" alias="stu"/>
<!-- 省略包名,就是说这个包中的类只需要填写类名即可比如:这个时候直接就是Student -->
<package name="com.javase.domain"/>
</typeAliases>
建议还是写全限定名称,见名知意,不会出错
8、关于mapper文件中的resultMap的填写
1、resultMap和resultType不能同时使用,二选其一
2、使用时机:当字段名和属性名不一样的时候使用
解决数据库字段名和对象属性名不一致的第二个办法
使用as进行字段的重命名
使用as进行字段的重命名
3、目的就是通过配置文件,指定你的数据库中的某个字段就是和某个对象中的属性值对应
比如:数据库中的字段叫myname,但是实体类中的对应字段我们叫做name
这个时候是无法赋值的,查询的对应结果就是null
可以通过resultMap就行定义
column就是数据库中的字段,property就是对象中的属性
id就是这个resultMap的唯一标识,后面可以直接引用
这个时候是无法赋值的,查询的对应结果就是null
可以通过resultMap就行定义
column就是数据库中的字段,property就是对象中的属性
id就是这个resultMap的唯一标识,后面可以直接引用
<resultMap id='studentMap' type='com.javase.domain.Student'>
<id column='id' property='id' />
<id column='myname' property='name' />
<id column='email' property='email' />
<id column='age' property='age' />
</resultMap>
<id column='id' property='id' />
<id column='myname' property='name' />
<id column='email' property='email' />
<id column='age' property='age' />
</resultMap>
9、关于参数parameterType
parameterType:这个就是参数的类型,是全限定名称
parameterType:java.lang.Integer
mybatis自己编写了一套对应的短小的类型
比如:
Integet - > int
Double - > double 等等
这个parameterType可以不写,通过反射机制会自动识别你的数据类型
parameterType:java.lang.Integer
mybatis自己编写了一套对应的短小的类型
比如:
Integet - > int
Double - > double 等等
这个parameterType可以不写,通过反射机制会自动识别你的数据类型
mybatis-主配置文件
1、mybatis主配置文件是一个xml文件
2、文件名一般都叫做mybatis.xml
3、文件头部是:
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
1、 这是一个约束文件
2、 mybatis-3-config.dtd,这个是约束文件的名称,是一个dtd文件
就是固定的,规定了这个文件中的内容必须是他规定好的标签才行
就是固定的,规定了这个文件中的内容必须是他规定好的标签才行
4、settings标签
控制全局行为,可以设置显示日志等
<!-- 设置输出日志 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<setting name="logImpl" value="STDOUT_LOGGING"/>
5、配置数据库连接的相关信息称之为:环境,可以配置多个,有的时候上线发布和测试使用是不一的
<!-- default就是你默认使用的是哪个环境 -->
<environments default="mydev">
<!-- 环境的名称,唯一标识 -->
<environment id="mydev">
<!-- 事务的处理,这里是jdbc中的commit和rollback -->
<transactionManager type="JDBC"/>
<!--
1、dateSource:数据源
2、type:表示使用连接池
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:8080/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="ht520520"/>
</dataSource>
</environment>
</environments>
<environments default="mydev">
<!-- 环境的名称,唯一标识 -->
<environment id="mydev">
<!-- 事务的处理,这里是jdbc中的commit和rollback -->
<transactionManager type="JDBC"/>
<!--
1、dateSource:数据源
2、type:表示使用连接池
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:8080/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="ht520520"/>
</dataSource>
</environment>
</environments>
6、配置插件,配置插件需要在配置环境之前,但是这个环境配置后面会有spring框架解决
配置分页工具插件
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
7、指定mapper文件的地址,就是sql映射文件的地址。这样在读取主配置文件的时候才能读取到数据库操作的信息
!-- 就是处理的sql文件的路径,就是sql mapper(sql映射文件) -->
<mappers>
<mapper resource="com/javase/mybatis/dao/StudentDao.xml"/>
</mappers>
<mappers>
<mapper resource="com/javase/mybatis/dao/StudentDao.xml"/>
</mappers>
8、数据库的属性配置文件
1、 将数据库的相关信息放入配置文件
2、 在mybatis.xml文件中读取文件
<properties resource="资源路径的根路径"/>
读取方式:${key }
<properties resource="资源路径的根路径"/>
读取方式:${key }
9、关于配置mappers中的mapper路径(就是处理sql语句的xml)
第一种:配置多个包
<mappers>
<mapper resource="com/javase/dao/StudentDao.xml" />
<mapper resource="com/javase/dao/UserDao.xml" />
</mappers>
<mapper resource="com/javase/dao/StudentDao.xml" />
<mapper resource="com/javase/dao/UserDao.xml" />
</mappers>
第二种:指定包
使用package的形式,将这个包中的mapper配置文件全部加载
name:某个包的全限定名称
<mappers>
<package name="com/javase/dao" />
</mappers>
name:某个包的全限定名称
<mappers>
<package name="com/javase/dao" />
</mappers>
10、关于分页插件
1、引入依赖
<!-- 添加pageHelper需要的依赖 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
2、添加插件
<!-- 配置插件,必须在环境前面 -->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
3、使用方法:
在查询方法执行之前
Page<Object> objects = PageHelper.startPage(5, 2);
第一个参数:pageNum:展示第几页
第二个参数:pageSize:一页几条数据
4、获取总页数
int pages = objects.getPages();
5、获取总数据数
long total = objects.getTotal();
mybatis-动态SQL
1、if标签
<if text="条件"> <if test="name != null">
条件成立则执行 name = #{name}
</if> </if>
条件成立则执行 name = #{name}
</if> </if>
2、 where标签
<where>
<if test="">
name = #{name}
</if>
<if test="">
or id = #{id}
</if>
</where>
<if test="">
name = #{name}
</if>
<if test="">
or id = #{id}
</if>
</where>
如果使用了这个标签,如果里面有if语句成立,框架会自动去掉或者增加or或者and等连接词
比如:
select id,name,email,age from student
<where>
<if test="name != null and name != '' ">
name = #{name }
</if>
<if test="id > 0 ">
or id = #{id }
</if>
</where>
select id,name,email,age from student
<where>
<if test="name != null and name != '' ">
name = #{name }
</if>
<if test="id > 0 ">
or id = #{id }
</if>
</where>
只有存在if语句并且成立才会有where
如果第一个if不成立,会自动去掉 or
3、 foreach标签
1、使用在in语句中:比如:select id,name,email,age from student where id in (1001,1002)
2、第一种用法
select id,name,email,age from student where id in
<foreach collection="list" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
<foreach collection="list" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
3、第二种用法
select id,name,email,age from student where id in (
<foreach collection="list" item="student" separator=",">
#{student.id }
</foreach>
)
<foreach collection="list" item="student" separator=",">
#{student.id }
</foreach>
)
4、SQL代码片段
1、定义代码片段
<sql id="">
select id,name,email,age from student
</sql>
<sql id="">
select id,name,email,age from student
</sql>
2、引用代码片段
<include refid="" />
<include refid="" />
0 条评论
下一页