目录
1、Mybatis简介
- MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。
- MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
- MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
- 通过MyBatis框架来实现Dao层接口
2、Maven依赖
- 整个Demo使用Maven搭建。
- MyBatis的Maven依赖:
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
3、MyBatis配置文件详解
3.1、Mybatis配置文件骨架
- 所有配置信息都放置在configuration标签内
<?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>
</configuration>
3.2、properties标签
- properties 标签中的配置可以提供整个配置文件使用,在任何位置都可以引入其中配置的值
- properties 标签可以通过子标签 property 标签来配置一些子元素信息,也可以配置外部的动态文件
导入配置文件
<!--也可以配置url,但url和resource只能存在一个-->
<properties resource="db.properties"/>
3.3、事务的管理和连接池的配置
<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>
3.3.1、environments标签
- environment的复数,中文意思:环境。
- MyBatis可以配置多种环境 ,default指定默认使用某种环境,可以达到快速切换环境。
3.3.2、environment标签
- environments的子标签
- 配置一个具体的环境信息
- id代表当前环境的唯一标识
3.3.3、transactionManager标签
- environment子标签
- 中文意思:事务管理器
- type属性:事务管理器的类型,可选两者其一:JDBC(JdbcTransactionFactory:Jdbc事务工厂 ) | MANAGED(ManagedTransactionFactory)
- 使用JDBC事务管理机制,就是利用java.sql.Connection对象完成对事务的提交。
- 使用MANAGED事务管理机制,这种机制Mybatis自身不会去实现事务管理,而是让程序的WEB容器(JBOSS,WebLogic,Tomcat)来实现对事务的管理
- 自定以事务管理器:实现TransactionFactory接口。(那么type属性就是全类名)
3.3.4、dataSource标签
- type:数据源类型有UNPOOLED(UnpooledDataSourceFactory)、POOLED(PooledDataSourceFactory)、JNDI(JndiDataSourceFactory)。
- 自定义数据源:实现DataSourceFactory接口,type是全类名。
3.3.5、property标签
- name和value就是键值对,在properties配置文件中取得
3.4、mappers映射器
- 只有配置了 mappers 信息后,MyBatis 才知道去哪里加载 Mapper 映射文件。
- 在日常开发中,可以根据项目中 Mapper 的配置偏好,选择整合配置文件的配置方式。
3.4.1、映射方式一
mapper标签,通过resource属性引入classpath路径的相对资源
<mappers>
<mapper resource="com/han/Dao/GoodsMapper.xml"/>
</mappers>
3.4.2、映射方式二
package标签,通过name属性指定mapper接口所在的包名 ,此时对应的映射文件必须与接口位于同一路径下,并且名称相同
- 如mapper接口采用注解的方式,则无需映射文件
- windows系统下,映射文件不区分大小写,linux系统没有验证
<mappers>
<!--自动扫描包内的Mapper接口与配置文件-->
<package name="com.han.Dao"/>
</mappers>
3.4.3、映射方式三
mapper标签,通过class属性指定mapper接口名称,此时对应的映射文件必须与接口位于同一路径下,并且名称相同
- 如mapper接口采用注解的方式,则无需映射文件
- windows系统下,映射文件不区分大小写,linux系统没有验证
<mappers>
<mapper class="com.han.Dao.GoodsMapper"/>
</mappers>
4、Mapper文件
4.1、mapper文件骨架
- 所有增删改查都写在mapper标签内
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="全限定mapper接口名">
</mapper>
4.2、增删改查配置
<mapper namespace="com.han.Dao.GoodsMapper">
<!--resultMap实体类映射类-->
<resultMap id="GoodsMap" type="com.han.pojo.Goods">
<result column="id" property="id"/>
<result column="goods_name" property="goodsName"/>
<result column="goods_type" property="goodsType"/>
<result column="goods_price" property="goodsPrice"/>
<result column="goods_num" property="goodsNum"/>
</resultMap>
<select id="selectGoods" resultMap="GoodsMap">
select * from goods
</select>
<delete id="deleteGoods" >
delete from goods where id = #{id}
</delete>
<insert id="insertGoods">
insert into goods (goods_name,goods_type,goods_price,goods_num)
values (#{goods.goodsName},#{goods.goodsType},#{goods.goodsPrice},#{goods.goodsNum})
</insert>
<update id="updateGoods">
update goods
set goods_price = #{value}
where id = #{id}
</update>
</mapper>
5、实战
项目结构
maven的pom.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>MybatisDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
</dependencies>
<!--静态过滤让mapper的xml文件能够正常导出-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
5.1、Mybatis文件配置(核心)
mybatisConfig.xml
<?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>
<properties resource="db.properties"/><!--也可以配置url,但url和resource只能存在一个-->
<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>
<mappers>
<package name="com.han.Dao"/>
</mappers>
</configuration>
db.properties配置文件
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/goods_manage?useSSL=false&&serverTimezone=UTC&&allowPublicKeyRetrieval=true&&characterEncoding=utf8
username=root
password=1234
5.2、goods表结构
5.3、mapper配置(Dao层实现)
定义GoodsMapper接口
package com.han.Dao;
import com.han.pojo.Goods;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface GoodsMapper {
void insertGoods(@Param("goods")Goods goods);
void deleteGoods(@Param("id") Integer id);
<T> void updateGoods(@Param("id") Integer id, @Param("value")T value);
List<Goods> selectGoods();
}
配置GoodsMapper.xml文件
<?xml version="1.0" encoding="UTF8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.han.Dao.GoodsMapper">
<!--resultMap实体类映射类-->
<resultMap id="GoodsMap" type="com.han.pojo.Goods">
<result column="id" property="id"/>
<result column="goods_name" property="goodsName"/>
<result column="goods_type" property="goodsType"/>
<result column="goods_price" property="goodsPrice"/>
<result column="goods_num" property="goodsNum"/>
</resultMap>
<select id="selectGoods" resultMap="GoodsMap">
select * from goods
</select>
<delete id="deleteGoods" >
delete from goods where id = #{id}
</delete>
<insert id="insertGoods">
insert into goods (goods_name,goods_type,goods_price,goods_num)
values (#{goods.goodsName},#{goods.goodsType},#{goods.goodsPrice},#{goods.goodsNum})
</insert>
<update id="updateGoods">
update goods
set goods_price = #{value}
where id = #{id}
</update>
</mapper>
5.4、SqlSession工具类
package com.han.Utils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.InputStream;
public class SqlSessionUtil {
private static SqlSessionFactory sqlSessionFactory = null;
private static final InputStream in;
static{//工厂初始化
in = SqlSessionUtil.class.getResourceAsStream("../../../mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
}
public static SqlSession createSqlSession(){
SqlSession session = null;
//通过工厂得到SQLSession
session = sqlSessionFactory.openSession();
return session;
}
public static void release(SqlSession session){
if(session!=null) session.close();
}
@Test//测试是否能拿到session
public void test1(){
System.out.println(SqlSessionUtil.createSqlSession());
}
}
5.5、业务层实现
定义GoodsService类
package com.han.service;
import com.han.Dao.GoodsMapper;
import com.han.Utils.SqlSessionUtil;
import com.han.pojo.Goods;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class GoodsService {
public void insert(Goods goods){
System.out.println("【log】使用了insert方法");
SqlSession session = SqlSessionUtil.createSqlSession();
GoodsMapper goodsMapper = session.getMapper(GoodsMapper.class);
goodsMapper.insertGoods(goods);
session.commit();
SqlSessionUtil.release(session);
}
public void delete(Integer id){
System.out.println("【log】使用了delete方法");
SqlSession session = SqlSessionUtil.createSqlSession();
GoodsMapper mapper = session.getMapper(GoodsMapper.class);
mapper.deleteGoods(id);
session.commit();
SqlSessionUtil.release(session);
}
public List<Goods> select(){
SqlSession session = SqlSessionUtil.createSqlSession();
GoodsMapper goodsMapper = session.getMapper(GoodsMapper.class);
List<Goods> list = goodsMapper.selectGoods();
SqlSessionUtil.release(session);
return list;
}
public <T>void update(Integer id, T value){
System.out.println("【log】使用了update方法");
SqlSession session = SqlSessionUtil.createSqlSession();
GoodsMapper mapper = session.getMapper(GoodsMapper.class);
mapper.updateGoods(id,value);
session.commit();
SqlSessionUtil.release(session);
}
}
5.6、测试
5.6.1、测试类
import com.han.pojo.Goods;
import com.han.service.GoodsService;
import org.junit.Test;
import java.util.List;
public class MyTest {
@Test//需要junit依赖
public void test1(){
GoodsService goodsService = new GoodsService();
List<Goods> list = goodsService.select();
printList(list);
goodsService.insert(new Goods("榴莲","水果",80,100));
printList(goodsService.select());
goodsService.update(5,999);
printList(goodsService.select());
goodsService.delete(1);
printList(goodsService.select());
}
public void printList(List list){
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("**************************************************************************");
list.clear();
}
}
5.6.2、初始表
5.6.3、输出结果
Goods{id=1, goodsName='apple', goodsType='水果', goodsPrice=5, goodsNum=100}
Goods{id=2, goodsName='banana', goodsType='水果', goodsPrice=10, goodsNum=20}
Goods{id=3, goodsName='猕猴挑', goodsType='水果', goodsPrice=1, goodsNum=1000}
Goods{id=5, goodsName='emo', goodsType='水果', goodsPrice=1, goodsNum=30}
**************************************************************************
【log】使用了insert方法
Goods{id=1, goodsName='apple', goodsType='水果', goodsPrice=5, goodsNum=100}
Goods{id=2, goodsName='banana', goodsType='水果', goodsPrice=10, goodsNum=20}
Goods{id=3, goodsName='猕猴挑', goodsType='水果', goodsPrice=1, goodsNum=1000}
Goods{id=5, goodsName='emo', goodsType='水果', goodsPrice=1, goodsNum=30}
Goods{id=7, goodsName='榴莲', goodsType='水果', goodsPrice=80, goodsNum=100}
**************************************************************************
【log】使用了update方法
Goods{id=1, goodsName='apple', goodsType='水果', goodsPrice=5, goodsNum=100}
Goods{id=2, goodsName='banana', goodsType='水果', goodsPrice=10, goodsNum=20}
Goods{id=3, goodsName='猕猴挑', goodsType='水果', goodsPrice=1, goodsNum=1000}
Goods{id=5, goodsName='emo', goodsType='水果', goodsPrice=999, goodsNum=30}
Goods{id=7, goodsName='榴莲', goodsType='水果', goodsPrice=80, goodsNum=100}
**************************************************************************
【log】使用了delete方法
Goods{id=2, goodsName='banana', goodsType='水果', goodsPrice=10, goodsNum=20}
Goods{id=3, goodsName='猕猴挑', goodsType='水果', goodsPrice=1, goodsNum=1000}
Goods{id=5, goodsName='emo', goodsType='水果', goodsPrice=999, goodsNum=30}
Goods{id=7, goodsName='榴莲', goodsType='水果', goodsPrice=80, goodsNum=100}
**************************************************************************
Process finished with exit code 0