一、mybatis简介
1.1 什么是mybatis?
(1)mybatis的概念
①mybatis是一款持久层框架;
②它支持定制化SQL、存储过程以及高级映射;
③mybatis避免了几乎所有的jdbc代码和手动设置以及获取结果集;
④mybatis可以使用简单的xml或注解来配置和映射原生类型、接口和Java的                 POJO(Plain Old Java Objects,普通老式的Java对象)为数据库中的记录;
⑤mybatis本事apache的一个开源项目Batis,在2010年这个项目由apache software foundation迁移到了Google code下,并且改名为mybatis;
2013年11月迁移至GitHub下
(2)mybatis的作用
①帮助程序开发者将数据持久化(存入到数据库中);
②方便;
③不用mybatis也可以,不过用了mybatis更容易上手,技术没有高低之分;
④优点:
- 简单易学;
 - 灵活;
 - SQL和代码分离,提高了可维护性;
 - 提供了映射标签,支持对象与数据库的ORM字段关系映射;
 - 提供对象关系映射标签,支持对象关系组件维护;
 - 提供xml标签,支持编写动态SQL;
 
(3)第一个mybatis程序
SqlSession常见的方法 | 返回值 | 方法名 | 说明 | | —- | —- | —- | | List
| selectList(String statement,Object parameter) | 执行查询语句,返回list集合 | | T | selectOne(String statement,Object parameter) | 执行查询语句,返回一个结果对象 | | int | insert(String statement,Object parameter) | 执行新增语句,返回影响行数 | | int | update(String statement,Object parameter) | 执行修改语句,返回影响行数 | | int | delete(String statement,Object parameter) | 执行删除语句,返回影响行数 | | void | commit() | 提交事务 | | void | rollback() | 回滚事务 | | T | getMapper(Class cls) | 获取指定接口的代理实现类对象 | | void | close() | 释放资源 | 新建项目
- 新建一个普通的maven项目;
 - 删除src目录;
 - 导入maven的mybatis依赖;
<!--mybatis_--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.3</version></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.46</version></dependency><!--junit--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency>
 
创建一个模块
编写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="mysql"><!--配置mysql的环境--><environment id="mysql"><!--配置事务的类型--><transactionManager type="JDBC"/><!--配置数据源信息--><dataSource type="POOLED" ><!--配置连接数据库的四个基本信息--><property name="driver" value="com.mysql.jdbc.Driver"></property><property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=true&useUnicode=true&characterEncoding=UTF-8"></property><property name="username" value="root"></property><property name="password" value="960317"></property></dataSource></environment></environments><!--配置映射配置文件的位置--><mappers><!--指定实体映射配置文件所在的包,指定的是dao接口所在的包--><package name="com.xiao.ha.dao"></package></mappers></configuration>
编写mybatis工具类 ```java package com.xiao.ha.factory;
import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
/**
- 用于生成dao接口代理实现类的工厂
 - @author HarsonLee
 @date 2021/03/15 */ public class MapperFactory {
private static SqlSessionFactory factory; private static ThreadLocal
tl = new ThreadLocal (); static {
InputStream in = null;try {//1.读取mybatis主配置文件in = Resources.getResourceAsStream("SqlMapConfig.xml");//2.创建构建者对象SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();//3.使用构建者创建SqlSessionFactory工厂factory = builder.build(in);}catch (Exception e){//打印异常信息到控制台e.printStackTrace();//抛出错误提示程序终止执行throw new ExceptionInInitializerError("初始化SqlSessionFactory失败");}finally {//释放流对象if(in != null){try{in.close();}catch (Exception e){e.printStackTrace();}}}
}
/**
- 获取SqlSession对象
 - @return
 保留此方法是为了后面对业务层方法增强,利用AOP添加事务 */ public static SqlSession getSqlSession(){ return factory.openSession(false); }
/**
- 获取Dao接口的代理实现类
 - @param daoClass dao接口字节码
 - @return
*/
public static 
T getMapper(SqlSession sqlSession,Class daoClass){ //1.判断传入的SqlSession是否为null if(sqlSession == null){ 
} //2.不为null,创建代理实现类 return sqlSession.getMapper(daoClass); } } ```return null;
 
- 编写JavaPOJO类
 - 编写dao接口
 编写mybatis映射文件
<?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.xiao.ha.dao.store.CatalogDao"><!--配置实体类属性和数据库表中列的对应关系--><resultMap id="BaseResultMap" type="com.xiao.ha.bean.store.Catalog"><id column="id" jdbcType="VARCHAR" property="id"/><result column="name" jdbcType="VARCHAR" property="name"/><result column="remark" jdbcType="VARCHAR" property="remark"/><result column="state" jdbcType="VARCHAR" property="state"/><result column="course_id" jdbcType="VARCHAR" property="courseId"/><result column="create_time" jdbcType="TIMESTAMP" property="createTime"/><association property="course" column="course_id" javaType="com.xiao.ha.bean.store.Catalog"select="com.xiao.ha.dao.store.CourseDao.findById"></association></resultMap><!--配置查询的列名公共SQL语句--><sql id="Base_Column_List">id, name, remark , state , create_time , course_id</sql><!--配置查询所有--><select id="findAll" resultMap="BaseResultMap">select<include refid="Base_Column_List"/>from st_catalog</select><!--配置根据ID查询--><select id="findById" parameterType="java.lang.String" resultMap="BaseResultMap">select<include refid="Base_Column_List"/>from st_catalogwhere id = #{id,jdbcType=VARCHAR}</select><!--配置根据id删除--><delete id="delete" parameterType="java.lang.String">delete from st_catalog where id = #{id,jdbcType=VARCHAR}</delete><!--配置全字段插入,当某个字段没有值时,插入null--><insert id="save" parameterType="com.xiao.ha.bean.store.Catalog">insert into st_catalog (id, name, remark , state , create_time , course_id)values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{remark,jdbcType=VARCHAR},#{state,jdbcType=VARCHAR} , #{createTime,jdbcType=TIMESTAMP}, #{courseId,jdbcType=VARCHAR})</insert><!--配置全字段更新,当提供的数据为null时,数据库数据会被更新为null--><update id="update" parameterType="com.xiao.ha.bean.store.Catalog">update st_catalogset name = #{name,jdbcType=VARCHAR},remark = #{remark,jdbcType=VARCHAR},state = #{state,jdbcType=VARCHAR},course_id = #{courseId,jdbcType=VARCHAR}where id = #{id,jdbcType=VARCHAR}</update></mapper>
编写测试类 ```java package com.xiao.ha.serevice.store.impl;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.xiao.ha.bean.store.Catalog; import com.xiao.ha.dao.store.CatalogDao; import com.xiao.ha.factory.MapperFactory; import com.xiao.ha.serevice.store.CatalogService; import com.xiao.ha.util.TransactionUtil; import org.apache.ibatis.session.SqlSession;
import java.util.Date; import java.util.List; import java.util.UUID;
public class CatalogServiceImpl implements CatalogService { /**
* 添加数据的方法* @param catalog*/@Overridepublic void save(Catalog catalog) {SqlSession sqlSession = null;try {//1.获取SqlSessionsqlSession = MapperFactory.getSqlSession();//2.获取DaoCatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);//id使用UUID的生成策略来获取String id = UUID.randomUUID().toString();catalog.setId(id);catalog.setCreateTime(new Date());//3.调用Dao层操作catalogDao.save(catalog);//4.提交事务TransactionUtil.commit(sqlSession);} catch (Exception e) {TransactionUtil.rollback(sqlSession);throw new RuntimeException(e);//记录日志} finally {try {TransactionUtil.close(sqlSession);} catch (Exception e) {e.printStackTrace();}}}@Overridepublic void delete(Catalog catalog) {SqlSession sqlSession = null;try {//1.获取SqlSessionsqlSession = MapperFactory.getSqlSession();//2.获取DaoCatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);//3.调用Dao层操作catalogDao.delete(catalog);//4.提交事务TransactionUtil.commit(sqlSession);} catch (Exception e) {TransactionUtil.rollback(sqlSession);throw new RuntimeException(e);//记录日志} finally {try {TransactionUtil.close(sqlSession);} catch (Exception e) {e.printStackTrace();}}}@Overridepublic void update(Catalog catalog) {SqlSession sqlSession = null;try {//1.获取SqlSessionsqlSession = MapperFactory.getSqlSession();//2.获取DaoCatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);//3.调用Dao层操作catalogDao.update(catalog);//4.提交事务TransactionUtil.commit(sqlSession);} catch (Exception e) {TransactionUtil.rollback(sqlSession);throw new RuntimeException(e);//记录日志} finally {try {TransactionUtil.close(sqlSession);} catch (Exception e) {e.printStackTrace();}}}@Overridepublic Catalog findById(String id) {SqlSession sqlSession = null;try {//1.获取SqlSessionsqlSession = MapperFactory.getSqlSession();//2.获取DaoCatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);//3.调用Dao层操作return catalogDao.findById(id);} catch (Exception e) {throw new RuntimeException(e);//记录日志} finally {try {TransactionUtil.close(sqlSession);} catch (Exception e) {e.printStackTrace();}}}@Overridepublic List<Catalog> findAll() {SqlSession sqlSession = null;try {//1.获取SqlSessionsqlSession = MapperFactory.getSqlSession();//2.获取DaoCatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);//3.调用Dao层操作return catalogDao.findAll();} catch (Exception e) {throw new RuntimeException(e);//记录日志} finally {try {TransactionUtil.close(sqlSession);} catch (Exception e) {e.printStackTrace();}}}@Overridepublic PageInfo findAll(int page, int size) {SqlSession sqlSession = null;try {//1.获取SqlSessionsqlSession = MapperFactory.getSqlSession();//2.获取DaoCatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);//3.调用Dao层操作PageHelper.startPage(page, size);List<Catalog> all = catalogDao.findAll();PageInfo pageInfo = new PageInfo(all);return pageInfo;} catch (Exception e) {throw new RuntimeException(e);//记录日志} finally {try {TransactionUtil.close(sqlSession);} catch (Exception e) {e.printStackTrace();}}}
}
<a name="j4aoU"></a>### (4)万能的Map假设我们的实体类或者数据库中的表的字段或参数比较多时,我们应该考虑使用map```java//万能的Mapint addUser(Map<String,Object>map);
<!--对象中的属性可以直接取出来,传递Map的Key--><insert id="save" parameterType="map">insert into st_catalog (id, name, remark , state , create_time , course_id)values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{remark,jdbcType=VARCHAR},#{state,jdbcType=VARCHAR} , #{createTime,jdbcType=TIMESTAMP}, #{courseId,jdbcType=VARCHAR})</insert>
