Mybatis 框架 ( 一 ) 基本步骤
1.概念
1.1.什么是Mybatis框架
(1)Mybatis是一个半ORM(Object Relation Mapping 对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高。
(2)MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
(3)通过xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。(从执行sql到返回result的过程)
1.2.Mybatis框架与JDBC区别
两者都是持久化的技术
连接数据库时 : mybatis 使用了 连接池技术 , 而jdbc需要自己写
持久化操作时 : mybatis 在映射文件中集中管理SQL语句 , 并且支持动态SQL
通常使用Mapper接口封装成面向对象的语法
而JDBC中的SQL是以参数的形式传入
结果集封装 : mybatis 封装了过程 , 只要指明对应结构就可以 , 而JDBC全手动
1.3.Mybatis框架与Hibernate框架区别
Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。
而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。
2.步骤
相较于JDBC来说, Mybatis完成持久化操作也分4个步骤, 需要七个参数
4个步骤 : 连接数据库, 持久化操作, 结果集封装, 释放资源
7个参数 : 驱动类路径, 连库信息, 用户名, 密码, SQL语句, SQL参数, 结果集封装结构
2.0.在idea中创建 Maven项目
2.1.依赖包
通过Maven 导入依赖, 同时导入 MySQL数据库的驱动依赖
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.7</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.21</version></dependency>
2.2.增加配置文件( 4/7参数 )
在 resources 文件夹中增加Mybatis的配置文件 mybatis-config.xml
在文件中 指明连接数据库的 4 个信息 驱动类路径
, url
, 用户名
, 密码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"></transactionManager><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/metamooc" /><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment></environments></configuration>
2.3.连接数据库( 1/4 操作)
建立一个操作类, 增加连接数据库代码
// 读取myBatis的配置文件Reader reader = Resources.getResourceAsReader("mybatis-config.xml");// 创建SessionFactory工厂 与数据库建立 连接 connSqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
2.4.Mapper映射 ( 3/7 参数 , 1/4 操作)
2.4.1.实体类Entity
实体类Entity 用于封装数据, 通常与数据库的表对应 , 这里以 Teacher为例
import java.io.Serializable;
import java.util.Date;/*** 教师 teacher* @TableName teacher*/public class Teacher implements Serializable {/*** 讲师主键*/private Integer tchId;/*** 讲师姓名*/private String tchName;/*** 讲师介绍*/private String tchInfo;/*** 讲师性别*/private Integer tchSex;/*** 讲师注册时间*/private Date tchRegTime;/*** 讲师头像*/private String tchPic;/*** 登录账号*/private String tchUser;/*** 登录密码*/private String tchPass;@Overridepublic String toString() {return "Teacher{" +"tchId=" + tchId +", tchName='" + tchName + '\'' +", tchInfo='" + tchInfo + '\'' +", tchSex=" + tchSex +", tchRegTime=" + tchRegTime +", tchPic='" + tchPic + '\'' +", tchUser='" + tchUser + '\'' +", tchPass='" + tchPass + '\'' +'}';}public Integer getTchId() {return tchId;}public void setTchId(Integer tchId) {this.tchId = tchId;}public String getTchName() {return tchName;}public void setTchName(String tchName) {this.tchName = tchName;}public String getTchInfo() {return tchInfo;}public void setTchInfo(String tchInfo) {this.tchInfo = tchInfo;}public Integer getTchSex() {return tchSex;}public void setTchSex(Integer tchSex) {this.tchSex = tchSex;}public Date getTchRegTime() {return tchRegTime;}public void setTchRegTime(Date tchRegTime) {this.tchRegTime = tchRegTime;}public String getTchPic() {return tchPic;}public void setTchPic(String tchPic) {this.tchPic = tchPic;}public String getTchUser() {return tchUser;}public void setTchUser(String tchUser) {this.tchUser = tchUser;}public String getTchPass() {return tchPass;}public void setTchPass(String tchPass) {this.tchPass = tchPass;}
}
2.4.2.Mapper接口
对 要执行的SQL 进行抽象声明
import com.yuan.mybatis.entity.Teacher;import java.util.List;/**
* @description 针对表【teacher(教师 teacher)】的数据库操作Mapper
* @Entity com.yuan.mybatis.entity.Teacher
*/
public interface TeacherMapper {/*** 全查*/List<Teacher> selectList();/*** 添加*/int insert(Teacher teacher);/*** 修改*/int updateById(Teacher teacher);/*** 根据id 删除记录*/int removeById(Integer id);/*** 根据id 查询一条记录*/Teacher selectOneById(Integer tchId);/*** 查询指定表的记录数*/int selectCount(String tabName);/*** 根据tch_user, tch_pass 查询一条记录*/Teacher selectOneByUserNameAndPassword(@Param("userName") String name, @Param("password") String pass);}
2.4.3. ***映射文件
在 resources 文件夹下 mapper 文件夹中 增加 Mapper接口对应的映射文件 TeacherMapper.xml
其中(重点) :
2.4.3.1. namespace
根结点 mapper 的 namespace
属性 指向 Mapper 接口
<mapper namespace="com.yuan.mybatis.mapper.TeacherMapper">
2.4.3.2.resultMap
<resultMap>
结点 与 Entity 实体类 对应 , 通过 type
属性 对应类的路径
<id>
对应 主键 字段, <result>
为普通字段
property
对应 实体类的属性名 , column
对应 字段名 , jdbcType
对应类型(这个可以不写)
<resultMap id="BaseResultMap" type="com.yuan.mybatis.entity.Teacher"><id property="tchId" column="tch_id" jdbcType="INTEGER"/><result property="tchName" column="tch_name" jdbcType="VARCHAR"/><result property="tchInfo" column="tch_info" jdbcType="VARCHAR"/><result property="tchSex" column="tch_sex" jdbcType="BOOLEAN"/><result property="tchRegTime" column="tch_reg_time" jdbcType="TIMESTAMP"/><result property="tchPic" column="tch_pic" jdbcType="VARCHAR"/><result property="tchUser" column="tch_user" jdbcType="VARCHAR"/><result property="tchPass" column="tch_pass" jdbcType="VARCHAR"/></resultMap>
2.4.3.3.SQL语句
<insert>
, <delete>
, <update>
, <select>
是用来编写 对应SQL 语句
id
与 Mapper接口 中声明的 方法名 对应
#{属性}
在SQL语句中作属性占位符, 执行时替换成对应值, 值是从Mapper接口传入的参数对应
如果传入是实体类, 属性取类的属性
<update id="updateById" parameterType="com.yuan.mybatis.entity.Teacher">update teacherset tch_name = #{tchName},tch_info = #{tchInfo},tch_sex = #{tchSex},tch_reg_time = #{tchRegTime},tch_pic = #{tchPic},tch_user = #{tchUser},tch_pass = #{tchPass}where tch_id = #{tchId}</update>
如果传入是单个值, 可以用类型如: list , array , id 等, 或者与参数名相同
<delete id="removeById" parameterType="java.lang.Integer">delete from teacherwhere tch_id = #{id}</delete>
如果传入多个参数 , 对应的方法有多种, 推荐在传参时使用@Param("别名")
进行标注(这个可以不写)
<select id="selectOneByUserNameAndPassword" resultMap="BaseResultMap">select<include refid="Base_Column_List" />from teacherwhere tch_user = #{userName} and tch_pass = #{password}limit 1</select>
${值}
也是属性占位符, 直接替换为实际的参数值, 没有预编译效果,
只用于与参数无关的字符类型数据, 所以代表字符串时要用 单引号包围起来 '${}'
#{} 只能以预编译的形式为属性赋值 , 而 ${} 可以替代SQL语句中的表名, 字段名等结构信息
<select id="selectCount" resultType="java.lang.Integer" >select count(*)from ${tabName}</select>
2.4.3.4.delete, update
<delete>
, <update>
这两个结点是用来编写 删除, 更新 对应SQL语句的
parameterType
属性 指明传入参数类型(这个可以不写)
<update id="updateById" parameterType="com.yuan.mybatis.entity.Teacher">update teacherset tch_name = #{tchName},tch_info = #{tchInfo},tch_sex = #{tchSex},tch_reg_time = #{tchRegTime},tch_pic = #{tchPic},tch_user = #{tchUser},tch_pass = #{tchPass}where tch_id = #{tchId}</update>
2.4.3.5.insert
<insert>
用于编写插入SQL语句
通常MySQL数据库主键设置成 自增长, 在添加之前不知道具体值, 通过下面的三个属性, 在添加完成后立刻可以通过实体类得到值
keyColumn
=“主键字段” keyProperty
=“对应实体类属性” useGeneratedKeys
=“使用生成的主键, 选 : true”
<insert id="insert" keyColumn="tch_id" keyProperty="tchId"parameterType="com.yuan.mybatis.entity.Teacher" useGeneratedKeys="true">insert into teacher (tch_name, tch_info, tch_sex,tch_reg_time, tch_pic, tch_user,tch_pass)values (#{tchName}, #{tchInfo}, #{tchSex},#{tchRegTime}, #{tchPic}, #{tchUser}, #{tchPass})</insert>
2.4.3.6.SQL片段
<sql>
编写 可复用的SQL语句片段,
在其它语句中 通过 <include>
进行引入 refid
与 id
属性对应
<sql id="Base_Column_List">tch_id,tch_name,tch_info,tch_sex,tch_reg_time,tch_pic,tch_user,tch_pass</sql><select id="selectList" resultMap="BaseResultMap" >select <include refid="Base_Column_List"/>from teacher</select>
2.4.3.7.select
<select>
用于编写查询SQL语句 , 通过 指定返回值类型完成结果集封装
resultMap
属性 是用于指明返回的实体类 , 与 <resultMap>
结点的 id 属性对应
<select id="selectOneById" parameterType="java.lang.Integer" resultMap="BaseResultMap">select<include refid="Base_Column_List" />from teacherwhere tch_id = #{tchId}</select>
resultType
属性 也是用于指明返回值类型, 用于指明除 实体类以外的通用类型
<select id="selectCount" resultType="java.lang.Integer" >select count(*)from ${tabName}</select>
2.4.3.8.完整文件
<?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.yuan.mybatis.mapper.TeacherMapper"><resultMap id="BaseResultMap" type="com.yuan.mybatis.entity.Teacher"><id property="tchId" column="tch_id" jdbcType="INTEGER"/><result property="tchName" column="tch_name" jdbcType="VARCHAR"/><result property="tchInfo" column="tch_info" jdbcType="VARCHAR"/><result property="tchSex" column="tch_sex" jdbcType="BOOLEAN"/><result property="tchRegTime" column="tch_reg_time" jdbcType="TIMESTAMP"/><result property="tchPic" column="tch_pic" jdbcType="VARCHAR"/><result property="tchUser" column="tch_user" jdbcType="VARCHAR"/><result property="tchPass" column="tch_pass" jdbcType="VARCHAR"/></resultMap><sql id="Base_Column_List">tch_id,tch_name,tch_info,tch_sex,tch_reg_time,tch_pic,tch_user,tch_pass</sql><select id="selectList" resultMap="BaseResultMap" >select <include refid="Base_Column_List"/>from teacher</select><select id="selectOneById" parameterType="java.lang.Integer" resultMap="BaseResultMap">select<include refid="Base_Column_List" />from teacherwhere tch_id = #{tchId}</select><select id="selectCount" resultType="java.lang.Integer" >select count(*)from ${tabName}</select><delete id="removeById" parameterType="java.lang.Integer">delete from teacherwhere tch_id = #{id}</delete><insert id="insert" keyColumn="tch_id" keyProperty="tchId"parameterType="com.yuan.mybatis.entity.Teacher" useGeneratedKeys="true">insert into teacher (tch_name, tch_info, tch_sex,tch_reg_time, tch_pic, tch_user,tch_pass)values (#{tchName}, #{tchInfo}, #{tchSex},#{tchRegTime}, #{tchPic}, #{tchUser}, #{tchPass})</insert><update id="updateById" parameterType="com.yuan.mybatis.entity.Teacher">update teacherset tch_name = #{tchName},tch_info = #{tchInfo},tch_sex = #{tchSex},tch_reg_time = #{tchRegTime},tch_pic = #{tchPic},tch_user = #{tchUser},tch_pass = #{tchPass}where tch_id = #{tchId}</update></mapper>
2.4.4.在配置文件中声明
在 Mybatis的主配置文件中, 增加映射文件的声明
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"></transactionManager><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/metamooc" /><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment></environments><!-- 映射声明 --><mappers><mapper resource="mapper/TeacherMapper.xml"></mapper></mappers>
</configuration>
2.5.持久化操作( 1/4 操作)
持久化操作先要得到 SqlSession实例,
再得到Mapper接口的实例,
// 取出一个session 得到对数据持久化操作的句柄 stmt
SqlSession session = sqlSessionFactory.openSession();
// 通过session得到Mapper, 再通过 Mapper对象调用方法完成持久化操作
TeacherMapper teacherMapper = session.getMapper(TeacherMapper.class);
通过实例调用方法完成持久化操作 如:
// 插入数据
int insert = teacherMapper.insert(teacher);
// 查询数据List<Teacher> list = teacherMapper.selectList();
2.5.1.事务提交
进行 插入数据, 修改数据, 删除数据时 要手动处理事务
如果操作没有问题 提交事务, 出现问题 事务回滚
// 提交
session.commit();
// 或者 回滚
session.rollback();
2.6.释放资源(1/4 操作)
由于 连接数据库时 使用连接池, 所以只需要释放session实例
// 关闭 session
session.close();