前言
鉴于现在mabatis教程篇幅巨长 恰巧我最近刚学完此框架,于是有了这个简短快速上手的教程
Mybatis
相信大家都应该了解了什么是Mybatis以及它在Java开发中的重要性----若有不懂请移步至Mybatis[官MyBatis中文网方文档]()。
配置教程
pom.xml初始化
- 打开idea创建maven项目
- 找到pom.xml文件注入相关jar包 这三种都是必备jar包 MySQL连接数据库 junit用来调用相关注解测试
-
定义资源文件的目录、包含规则和过滤行为 这个必须配置不要遗忘
<project> <build> <resources> <!-- 处理 src/main/resources 目录 --> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> <!-- 处理 src/main/java 目录 --> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build> </project>
配置config核心文件
-
找到目录下resourse 创建config.xml和dp.properties config用来配置依赖属性 dp作为外部配置文件封装你的数据库信息
<configuration><!--核心配置文件--> <!--1.引入外部配置文件--> <properties resource="dp.properties"/> <!--标准的日志工厂实现--> <settings> <setting name="logImpl" value="STDOUT_LOGGING"/> <!--是否开启驼峰(camel case)映射--> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <!--给实体类起别名--> <typeAliases><typeAlias type="com.crm.pojo.User" alias="User"/> </typeAliases> <!--环境配置--> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <!--注意,每一个mapper.xml都需要在Mybatis核心配置文件中注册--> <mappers> <mapper resource="com/crm/dao/UserMapper.xml"/> </mappers> </configuration> -
环境配置中数据库属性已被配置到dp中 可以调用
创建实体
-
pojo存放实体类(例如User)
-
dao持久层(UserMapper UserMapper.xml)
-
utile工具类(MybatisUtils)
-
创建数据库并连接,保障后面CRUD的进行
-
Test测试类
注意 mapper.xml注册路径必须保持一致 否则无法使用映射器
SqlSession
-
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。在Mybatis中,SqlSession极为强大,甚至可以说它是Mybatis中最重要的部分,通过它你可以调用方法接口来执行映射器中的sql语句来操纵数据库,极大简化了老掉牙的jdbc繁琐的步骤
下面是它的构建过程:打开工具类 用输入流的方式获得资源并构建 最后通过静态使它随类一起加载
属性
-
名称空间 ,位于你的mapper.xml中,请指定自己的mappper接口
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.crm.dao.UserMapper">//指定你的 -
在config.xml中有一个固定的配置属性顺序 必须严格遵守否则会报错
- typeAliases起别名,简化代码 常用于实体类型
<select id="getUserList" resultType="com.crm.pojo.User">
select * from mybatis.user
</select>
---------------------------------------------------------------
<select id="getUserList" resultType="User">
select * from mybatis.user
</select>
上述代码中第二段将返回类型com.crm.User取别名为User 减少了代码冗余
- 这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。
想要了解更多设置请移步至配置文档
因为内容太多 篇幅不够 我这里只是简短说一下驼峰命名
<!--是否开启驼峰(camel case)映射-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
在mysql中我们常常遇到create_time这种带下划线的字段,这时候我们只要开启驼峰映射我们就能用createTime与之匹配
<insert id="addBlog">
insert into mybatis.blog (id, title, author, create_time, views) VALUES
(#{id},#{title},#{author},#{createTime},#{views});
</insert>
xml映射器
MyBatis 的真正强大在于它的语句映射,这是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 致力于减少使用成本,让用户能更专注于 SQL 代码。
简单的crud
- 四个标签与sql语句的j基本含义是一样的
下面是一个简单的crud通过xml映射
<!--查询用户-->
<select id="getUserById" resultType="User" parameterType="int">
select * from mybatis.user where id= #{id}
</select>
<!--添加用户-->
<insert id="addUser" parameterType="User">
insert into mybatis.user (id, name, pwd) VALUES (#{id},#{name},#{pwd});
</insert>
<!--修改用户 -->
<update id="updateUser" parameterType="User">
update mybatis.user set name = #{name} ,pwd = #{pwd} where id=#{id}
</update>
<!--删除用户-->
<delete id="deleteUser" parameterType="int">
delete from mybatis.user where id=#{id}
</delete>
-
关于# & $
使用#{id},传入id执行sql语句时会先进行预编译参数 而不是简单的字符拼接,能够防止sql注入
而${}是直接拼接字符串,安全性极低
属性名与字段名不一致
我们可以使用resultMap进行映射 例如:在User表中pwd表示密码 而在java我们将它设置为了password
此时查出来用户密码则为为默认的null
<select id="getUserList" resultType="User"> select * from mybatis.user </select> ----------------------------------------------------------此时只要通过resultMap映射就好 column代表表的字段 property是属性
动态sql
-
什么是动态sql ?顾名思义就是指能够动态的拼接sql语句 从而避免编写大量重复代码
-
有以下常用标签
-
if:条件判断,满足时拼接sql
<select id="findUser" resultType="User"> select * from user <where> <if test="name != null"> and name = #{name} </if> <if test="age != null"> and age = #{age} </if> </where> </select>2.choose>/when/otherwise多条件选择,有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
<choose> <when test="name == 'admin'"> and level > 10 </when> <when test="name == 'user'"> and level <= 10 </when> <otherwise> and status = 1 </otherwise> </choose>依次进行条件筛选 直到出现一个条件满足就结束
3.foreach遍历集合(批量操作)
<select id="getUser" prameterTyper="map"> select * from user <where> <foreach collections="ids" item="id" open="(" separator="or" close=")"> id = #{id} </foreach> </where> </select>where:自动处理where后的首个and或or
set:动态生成update语句中的字段
trim可以自定义这些元素>
<trim prefix="WHERE" prefixOverrides="AND |OR "> ... </trim>
-
模糊查询
-
concat用于将两个或多个字符串拼接 并且它会将null当做空字符串处理
-
%用做占位符
<select id="getUserLike" resultType="User">
select * from mybatis.user where name like concat('%',#{value},'%')
</select>
一对多与多对一
- 一对多 查询一个学生的tid对应的多个老师
<!--按照结果查询-->
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid, s.name sname,t.name tname,t.id tid
from mybatis.student s,mybatis.teacher t
where s.tid = t.id and t.id=#{tid}
</select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<collection property="students" ofType="Student">
<result property="name" column="sname"/>
<result property="id" column="sid"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
<!--********************************************************************************************-->
<!--嵌套子查询-->
<select id="getTeacher2" resultMap="TeacherStudent2">
select * from mybatis.teacher where id = #{tid}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<collection property="students" javaType="ArrayList" ofType="Student" column="id" select="getStudent">
</collection>
</resultMap>
<select id="getStudent" resultType="Student">
select * from mybatis.student where tid=#{tid}
</select>
-
多对 一 查询多个学生对应一个老师
<!--按结果查询--> <select id="getStudent1" resultMap="StudentTeacher1"> select t.name tname,s.id,s.name from mybatis.student s,mybatis.teacher t where s.tid = t.id </select> <resultMap id="StudentTeacher1" type="Student"> <result column="id" property="id"/> <result column="name" property="name"/> <association property="teacher" javaType="Teacher"> <result column="tname" property="name"/> </association> </resultMap> <!--嵌套子查询--> <select id="getStudent" resultMap="StudentTeacher"> select * from mybatis.student </select> <!--查询学生信息 根据查询出来的tid寻找对应的老师--> <resultMap id="StudentTeacher" type="Student"> <result property="id" column="id"/> <result property="name" column="name"/> <!--复杂的属性需要单独处理--> <!--集合用colletion 对象用association--> <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/> </resultMap> <select id="getTeacher" resultType="Teacher"> select name from mybatis.teacher where id=#{tid} </select>
日志
日志(Log)是在计算机系统和应用程序中用于记录事件、错误、警告、调试信息或其他重要数据的一种机制。它是系统管理和故障排查的重要工具,能够帮助开发人员和系统管理员了解系统的运行状态、跟踪问题发生的原因,以及监控应用程序的行为。
Mybatis 通过使用内置的日志工厂提供日志功能。内置日志工厂将会把日志工作委托给下面的实现之一:
-
SLF4J
-
Apache Commons Logging
-
Log4j 2
-
Log4j
-
JDK logging
MyBatis 内置日志工厂会基于运行时检测信息选择日志委托实现。它会(按上面罗列的顺序)使用第一个查找到的实现。当没有找到这些实现时,将会禁用日志功能。
-
-
不过当前学习阶段我们使用默认的log足矣
如有其他需要,移步至更多日志配置
注解开发
- 使用MyBatis提供的注解(如@Select、@Insert、@Update、@Delete等)来定义SQL语句。
- 可以直接在接口上使用
- 使用于简单的句子 一般不推荐用在复杂语句
public class User {
private int id;
private String name;
private String email;
// getters and setters
}
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper {
// 使用@Select注解定义SQL查询
@Select("SELECT * FROM users WHERE id = #{id}")
User getUserById(int id);
}
SQL片段
-
在MyBatis中,SQL片段(SQL Fragment)是一种重用SQL代码的机制。通过使用
<sql>标签,你可以在MyBatis的映射文件(通常是XML文件)中定义一个SQL片段,然后在其他SQL语句中通过<include>标签来引用这个片段。这样做的好处是可以减少重复代码,提高SQL语句的可读性和可维护性。<sql id="userColumns"> id, username, password, email, created_at, updated_at </sql> <select id="selectUserById" resultType="User"> SELECT <include refid="userColumns"/> FROM users WHERE id = #{id} </select>refid属性用来指定引用的片段的id
缓存
一级缓存
- MyBatis的一级缓存是SQLSession级别的缓存,它是MyBatis框架的默认缓存机制。每一个SQLSession都有一个独立的一级缓存,用于缓存当前SQLSession中执行的查询结果。
- 当在SQLSession中执行查询操作时,MyBatis会首先检查一级缓存中是否存在相同的查询结果。
- 如果存在,则直接从缓存中返回结果,而不再执行实际的数据库查询。
- 如果缓存中不存在相应的查询结果,MyBatis会执行实际的数据库查询操作,并将查询结果存储在一级缓存中,以备后续相同查询使用。
执行了INSERT、UPDATE、DELETE等修改操作后,因为这些操作可能会改变数据状态,所以MyBatis会出于数据一致性的考虑,清空一级缓存。
手动调用SQLSession.clearCache()方法也会使一级缓存失效。
关闭当前的SQLSession也会导致一级缓存失效。
二级缓存
-
MyBatis的二级缓存是Mapper级别的缓存,它的生命周期与SQLSession无关,多个SQLSession可以共享同一个Mapper的二级缓存。相比于一级缓存,二级缓存提供了更广泛的缓存范围,但需要手动配置。默认情况下是关闭的,需要显式配置才能启用。
-
MyBatis的二级缓存是Mapper级别的缓存,它的生命周期与SQLSession无关,多个SQLSession可以共享同一个Mapper的二级缓存。相比于一级缓存,二级缓存提供了更广泛的缓存范围,但需要手动配置。默认情况下是关闭的,需要显式配置才能启用。
-
和一级缓存类似,二级缓存也会在执行INSERT、UPDATE、DELETE操作时部分或全部失效。
不过,二级缓存可以通过配置来调整其失效策略,例如设置失效时间、刷新条件等。
总结:
缓存范围:一级缓存是SQLSession级别的,适用于单个事务内多次相同查询的场景;二级缓存是Mapper级别的,适用于跨事务、频繁访问相同数据的场景。
生命周期:一级缓存的生命周期是SQLSession的生命周期,二级缓存的生命周期与SQLSession无关。
配置与使用:一级缓存默认开启且不需要额外配置;二级缓存需要显式配置才能启用。
数据一致性:两者都会在执行修改操作时失效,但二级缓存可以通过配置来调整其失效策略。
结语 :
祝大家新春快乐 需要学习的道路还很长 我们要坚持住 相信成功就在前方!