一、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 configuration
PUBLIC "-//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_catalog
where 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_catalog
set 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
*/
@Override
public void save(Catalog catalog) {
SqlSession sqlSession = null;
try {
//1.获取SqlSession
sqlSession = MapperFactory.getSqlSession();
//2.获取Dao
CatalogDao 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();
}
}
}
@Override
public void delete(Catalog catalog) {
SqlSession sqlSession = null;
try {
//1.获取SqlSession
sqlSession = MapperFactory.getSqlSession();
//2.获取Dao
CatalogDao 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();
}
}
}
@Override
public void update(Catalog catalog) {
SqlSession sqlSession = null;
try {
//1.获取SqlSession
sqlSession = MapperFactory.getSqlSession();
//2.获取Dao
CatalogDao 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();
}
}
}
@Override
public Catalog findById(String id) {
SqlSession sqlSession = null;
try {
//1.获取SqlSession
sqlSession = MapperFactory.getSqlSession();
//2.获取Dao
CatalogDao 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();
}
}
}
@Override
public List<Catalog> findAll() {
SqlSession sqlSession = null;
try {
//1.获取SqlSession
sqlSession = MapperFactory.getSqlSession();
//2.获取Dao
CatalogDao 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();
}
}
}
@Override
public PageInfo findAll(int page, int size) {
SqlSession sqlSession = null;
try {
//1.获取SqlSession
sqlSession = MapperFactory.getSqlSession();
//2.获取Dao
CatalogDao 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
//万能的Map
int 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>