一、介绍
官网简介
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
二、配置
1、导入Mybatis的 jar 包
2、classpath下mybatis的核心配置文件:【mybatis.cfg.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>
<environments default="my">
<environment id="my">
<!-- 事务管理器 -->
<transactionManager type="JDBC"/>
<!-- 数据源 -->
<dataSource type="POOLED">
<!-- 驱动类 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<!-- 数据库路径 -->
<property name="url" value="jdbc:mysql:///数据库名称?serverTimezone=UTC"/>
<!-- ///可写为:172.0.0.1 或者 localhost:3306 均表示本地计算机 -->
<!-- 数据库账号 -->
<property name="username" value="数据库账号"/>
<!-- 数据库密码 -->
<property name="password" value="数据库密码"/>
</dataSource>
</environment>
</environments>
<!-- 映射文件 -->
<mappers>
<!-- 配置映射文件 -->
<mapper resource="com\mybatis\data\pojo\映射文件.xml"/>
</mappers>
</configuration>
3、配置日志文件: 【log4j2.xml】
<?xml version="1.0" encoding="UTF-8"?>
<!-- status=debug 可以查看log4j的装配过程 -->
<configuration status="off" monitorInterval="1800">
<appenders>
<!-- 定义控制台输出 -->
<Console name="Console" target="SYSTEM_OUT" follow="true">
<PatternLayout
pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" />
</Console>
<!-- 系统打印日志
fileName:文件的名字
filePattern:文件名字的格式;
-->
<RollingRandomAccessFile name="System"
fileName="logs/mvchain/system.log" filePattern="logs/mvchain/system_%d{yyyy-MM-dd}_%i.log">
<PatternLayout
pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" />
<Policies>
<!-- 多长时间生成一个文件;默认1天 -->
<TimeBasedTriggeringPolicy interval="1"
modulate="true" />
<!-- 多大的文件要切分 -->
<SizeBasedTriggeringPolicy size="5K" />
</Policies>
</RollingRandomAccessFile>
<!-- 外部打印日志 -->
<RollingRandomAccessFile name="Outer"
fileName="logs/mvchain/outer.log" filePattern="logs/mvchain/outer_%d{yyyy-MM-dd}_%i.log">
<PatternLayout
pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1"
modulate="true" />
<SizeBasedTriggeringPolicy size="100M" />
</Policies>
</RollingRandomAccessFile>
<!-- 线程打印日志 -->
<RollingRandomAccessFile name="Timer"
fileName="logs/mvchain/timer.log" filePattern="logs/mvchain/timer_%d{yyyy-MM-dd}_%i.log">
<PatternLayout
pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1"
modulate="true" />
<SizeBasedTriggeringPolicy size="100M" />
</Policies>
</RollingRandomAccessFile>
</appenders>
<loggers>
<!-- Root Logger(这个是整个配置文件的入口 -->
<root level="debug">
<!-- 调用定义的log4j配置
console:指的是名字;(在这个标签中定义configuration==>appenders这下面标签的name属性 )
-->
<appender-ref ref="Console" />
<appender-ref ref="System" />
</root>
<!-- 外部日志,分开日志,name为getLogger()
console:指的是名字;(在这个标签中定义configuration==>appenders这下面标签的name属性 )
下面定义的多个组合,logger标签中任意组合
-->
<logger name="SystemLog" level="info" additivity="false">
<appender-ref ref="Console" />
<appender-ref ref="System" />
</logger>
<!-- 外部日志,分开日志,name为getLogger() -->
<logger name="OuterLog" level="info" additivity="false">
<!-- 日志文件要输出到三个地方,控制台,系统文件,外部文件 -->
<appender-ref ref="Console" />
<appender-ref ref="System" />
<appender-ref ref="Outer" />
</logger>
<!-- 线程日志,分开日志,name为getLogger() -->
<logger name="TimerLog" level="info" additivity="false">
<!-- 日志文件要输出到三个地方,控制台,系统文件,外部文件 -->
<appender-ref ref="Console" />
<appender-ref ref="System" />
<appender-ref ref="Outer" />
</logger>
</loggers>
</configuration>
4、创建一个 加载Mybatis配置文件 的类: 【BaseTest.java】
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.After;
import org.junit.Before;
public class BaseTest {
public Logger logger = LogManager.getLogger();
public SqlSessionFactory sessionFactory;
@Before
public void initCfg() {
String config = "mybatis.cfg.xml";
InputStream is = null;
try {
//以流的形式读取配置文件
is = Resources.getResourceAsStream(config);
//通过SqlSessionFactoryBuilder和流创建SqlSessionFactory
sessionFactory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@After
public void closeCfg() {
this.logger.info("Close All Configuration…………");
}
}
三、Mybatis的 CRUD
1、映射文件中的配置
<?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="dynasty">
<!-- 查询多条记录 -->
<select id="selectAll" resultType="com.mybatis.data.pojo.ADemoDynasty">
select * from a_demo_dynasty
</select>
<!-- 查询单条记录 -->
<select id="selectOne" parameterType="map" resultType="com.mybatis.data.pojo.ADemoDynasty">
select * from a_demo_dynasty where id = #{id}
</select>
<!-- <insert id="saveOne" parameterType="com.mybatis.data.pojo.ADemoDynasty" useGeneratedKeys="true" keyColumn="id" keyProperty="id"> -->
<insert id="saveOne" parameterType="com.jinghangzz.mybatis.data.pojo.ADemoDynasty" >
insert into a_demo_dynasty
(name, content, stYear, edYear, guoZuo, capital, status, createTime, updateTime, pubTime)
values
(#{name}, #{content}, #{stYear}, #{edYear}, #{guoZuo}, #{capital}, #{status}, #{createTime}, #{updateTime}, #{pubTime})
<selectKey keyColumn="id" keyProperty="id" order="AFTER" resultType="int">
<!-- select last_insert_id(); -->
select @@identity;
</selectKey>
</insert>
<update id="updateOne" parameterType="com.mybatis.data.pojo.ADemoDynasty">
update a_demo_dynasty set
name=#{name}, content=#{content}, stYear=#{stYear},
edYear=#{edYear}, guoZuo=#{guoZuo}, capital=#{capital},
status=#{status}, createTime=#{createTime},
updateTime=#{updateTime}, pubTime=#{pubTime}
where id = #{id}
</update>
<!--
参数类型为基本数据类型,那么参数的名称随便写都可以,但推荐见名知意
-->
<delete id="deleteOne" parameterType="int">
delete from a_demo_dynasty
where id = #{id}
</delete>
</mapper>
2、测试类中的源码
public class ADemoDynastyTest extends BaseTest{
@Test
public void selectAll() {
//由sessionFactory打开SqlSession
SqlSession session = sessionFactory.openSession();
//使用SqlSession获得List<ADemoDynasty>
List<ADemoDynasty> selectList = session.selectList("selectAll");
//遍历数组
selectList.forEach(a -> this.logger.info("朝代表===" + a));
//关闭会话
session.close();
}
}
3、控制台(Console)打印结果
2020-02-24 13:18:16.392 DEBUG [main][LogFactory.java:105] - Logging initialized using 'class org.apache.ibatis.logging.log4j2.Log4j2Impl' adapter.
2020-02-24 13:18:16.434 DEBUG [main][PooledDataSource.java:353] - PooledDataSource forcefully closed/removed all connections.
2020-02-24 13:18:16.436 DEBUG [main][PooledDataSource.java:353] - PooledDataSource forcefully closed/removed all connections.
2020-02-24 13:18:16.436 DEBUG [main][PooledDataSource.java:353] - PooledDataSource forcefully closed/removed all connections.
2020-02-24 13:18:16.436 DEBUG [main][PooledDataSource.java:353] - PooledDataSource forcefully closed/removed all connections.
2020-02-24 13:18:16.503 DEBUG [main][JdbcTransaction.java:136] - Opening JDBC Connection
2020-02-24 13:18:17.467 DEBUG [main][PooledDataSource.java:424] - Created connection 288379405.
2020-02-24 13:18:17.468 DEBUG [main][JdbcTransaction.java:100] - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1130520d]
2020-02-24 13:18:17.474 DEBUG [main][BaseJdbcLogger.java:143] - ==> Preparing: select * from a_demo_dynasty
2020-02-24 13:18:17.509 DEBUG [main][BaseJdbcLogger.java:143] - ==> Parameters:
2020-02-24 13:18:17.629 DEBUG [main][BaseJdbcLogger.java:143] - <== Total: 7
2020-02-24 13:18:17.637 INFO [main][ADemoDynastyTest.java:24] - 朝代表===ADemoDynasty [id=1, name=东汉, content=东汉, stYear=25, edYear=220, guoZuo=195, capital=洛阳, status=1, createTime=Sat Nov 23 02:06:11 CST 2019, updateTime=Sat Nov 23 02:06:11 CST 2019, pubTime=Sat Nov 23 02:06:11 CST 2019]
2020-02-24 13:18:17.637 INFO [main][ADemoDynastyTest.java:24] - 朝代表===ADemoDynasty [id=2, name=魏, content=魏, stYear=220, edYear=265, guoZuo=45, capital=洛阳, status=0, createTime=Sat Nov 23 02:06:33 CST 2019, updateTime=Sat Nov 23 02:06:33 CST 2019, pubTime=Sat Nov 23 02:06:33 CST 2019]
2020-02-24 13:18:17.638 INFO [main][ADemoDynastyTest.java:24] - 朝代表===ADemoDynasty [id=3, name=蜀汉, content=蜀汉, stYear=221, edYear=263, guoZuo=42, capital=成都, status=1, createTime=Sat Nov 23 02:07:07 CST 2019, updateTime=Sat Nov 23 02:07:07 CST 2019, pubTime=Sat Nov 23 02:07:07 CST 2019]
2020-02-24 13:18:17.638 INFO [main][ADemoDynastyTest.java:24] - 朝代表===ADemoDynasty [id=4, name=吴, content=吴, stYear=222, edYear=280, guoZuo=58, capital=建业, status=0, createTime=Sat Nov 23 02:07:51 CST 2019, updateTime=Sat Nov 23 02:07:51 CST 2019, pubTime=Sat Nov 23 02:07:51 CST 2019]
2020-02-24 13:18:17.638 INFO [main][ADemoDynastyTest.java:24] - 朝代表===ADemoDynasty [id=5, name=西晋, content=西晋, stYear=265, edYear=316, guoZuo=51, capital=洛阳, status=1, createTime=Sat Nov 23 02:09:26 CST 2019, updateTime=Sat Nov 23 02:09:26 CST 2019, pubTime=Sat Nov 23 02:09:26 CST 2019]
2020-02-24 13:18:17.639 INFO [main][ADemoDynastyTest.java:24] - 朝代表===ADemoDynasty [id=6, name=东晋, content=东晋, stYear=317, edYear=420, guoZuo=103, capital=建康, status=0, createTime=Sat Nov 23 02:09:32 CST 2019, updateTime=Sat Nov 23 02:09:32 CST 2019, pubTime=Sat Nov 23 02:09:32 CST 2019]
2020-02-24 13:18:17.639 INFO [main][ADemoDynastyTest.java:24] - 朝代表===ADemoDynasty [id=7, name=大唐, content=大唐, stYear=618, edYear=907, guoZuo=268, capital=长安, status=0, createTime=Mon Dec 02 03:08:32 CST 2019, updateTime=Mon Dec 02 03:08:32 CST 2019, pubTime=Mon Dec 02 03:08:32 CST 2019]
2020-02-24 13:18:17.640 DEBUG [main][JdbcTransaction.java:122] - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1130520d]
2020-02-24 13:18:17.650 DEBUG [main][JdbcTransaction.java:90] - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1130520d]
2020-02-24 13:18:17.651 DEBUG [main][PooledDataSource.java:381] - Returned connection 288379405 to pool.
2020-02-24 13:18:17.651 INFO [main][BaseTest.java:40] - Close All Configuration…………
3.2、CRUD
1、映射文件中的配置
<!-- 查询单条记录 -->
<select id="selectOne" parameterType="map" resultType="com.jinghangzz.mybatis.data.pojo.ADemoDynasty">
select * from a_demo_dynasty where id = #{id}
</select>
2、测试类中的源码
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import com.mybatis.data.pojo.ADemoDynasty;
/**
* 朝代表的CRUD
* @author Honker
*
*/
public class ADemoDynastyTest extends BaseTest{
/**
* 查询多条记录
*/
@Test
public void selectAll() {
//由sessionFactory打开SqlSession
SqlSession session = sessionFactory.openSession();
//1.使用SqlSession获得List
List<ADemoDynasty> selectList = session.selectList("selectAll");
//2.遍历数组
selectList.forEach(a -> this.logger.info("朝代表===" + a));
//关闭会话
session.close();
}
/**
* 查询单条记录
*/
public void selectOne() {
//由sessionFactory打开SqlSession
SqlSession session = sessionFactory.openSession();
//1.使用Map集存储值
Map<String,Object> condMap = new HashMap<String,Object>();
condMap.put("id", 1);
List<ADemoDynasty> selectList = session.selectList("selectOne", condMap);
//2.直接代入值
// List<ADemoDynasty> selectList = session.selectList("selectOne", 1);
//3.遍历数组
selectList.forEach(a -> this.logger.info("朝代表===" + a));
//关闭会话
session.close();
}
/**
* 添加单条记录
*/
@Test
public void insertOne() {
//由sessionFactory打开SqlSession
SqlSession session = sessionFactory.openSession();
try {
//name, content, stYear, edYear, guoZuo, capital, status
ADemoDynasty dynasty = new ADemoDynasty();
dynasty.setName("大清3");
dynasty.setContent("大清3");
dynasty.setStYear(1644);
dynasty.setEdYear(1912);
dynasty.setGuoZuo(268);
dynasty.setCapital("北平3");
dynasty.setCreateTime(new Date());
dynasty.setUpdateTime(new Date());
dynasty.setPubTime(new Date());
//返回受影响的行数
int rows = session.insert("saveOne", dynasty);
if(rows>0) {
this.logger.info("添加"+dynasty.getName()+"成功!!!添加的记录的主键是:" + dynasty.getId());
}
//所有写操作(增删改)都需要提交事务
session.commit();
if(session!=null) {
//关闭会话
session.close();
session = null;
}
} catch (Exception e) {
if(session != null) {
//回滚事务
session.rollback();
}
this.logger.error("更新数据报错了",e);
}
}
@Test
public void updateOne() {
//由sessionFactory打开SqlSession
SqlSession session = sessionFactory.openSession();
try {
//name, content, stYear, edYear, guoZuo, capital, status
ADemoDynasty dynasty = new ADemoDynasty();
dynasty.setId(4);
dynasty.setName("大清4");
dynasty.setContent("大清4");
dynasty.setStYear(1644);
dynasty.setEdYear(1912);
dynasty.setGuoZuo(268);
dynasty.setCapital("北平4");
dynasty.setCreateTime(new Date());
dynasty.setUpdateTime(new Date());
dynasty.setPubTime(new Date());
//返回受影响的行数
int rows = session.insert("updateOne", dynasty);
if(rows>0) {
this.logger.info("修改"+dynasty.getName()+"成功!!!");
}
//所有写操作(增删改)都需要提交事务
session.commit();
if(session!=null) {
//关闭会话
session.close();
session = null;
}
} catch (Exception e) {
if(session != null) {
//回滚事务
session.rollback();
}
this.logger.error("更新数据报错了",e);
}
}
@Test
public void deleteOne() {
//由sessionFactory打开SqlSession
SqlSession session = sessionFactory.openSession();
try {
//返回受影响的行数
int rows = session.insert("deleteOne",4);
if(rows>0) {
this.logger.info("受影响行数:{}行",rows);
}
//所有写操作(增删改)都需要提交事务
session.commit();
if(session!=null) {
//关闭会话
session.close();
session = null;
}
} catch (Exception e) {
if(session != null) {
//回滚事务
session.rollback();
}
this.logger.error("更新数据报错了",e);
}
}
}
3、控制台(Console)打印结果
2020-02-24 13:37:24.641 DEBUG [main][LogFactory.java:105] - Logging initialized using 'class org.apache.ibatis.logging.log4j2.Log4j2Impl' adapter.
2020-02-24 13:37:24.680 DEBUG [main][PooledDataSource.java:353] - PooledDataSource forcefully closed/removed all connections.
2020-02-24 13:37:24.681 DEBUG [main][PooledDataSource.java:353] - PooledDataSource forcefully closed/removed all connections.
2020-02-24 13:37:24.681 DEBUG [main][PooledDataSource.java:353] - PooledDataSource forcefully closed/removed all connections.
2020-02-24 13:37:24.681 DEBUG [main][PooledDataSource.java:353] - PooledDataSource forcefully closed/removed all connections.
2020-02-24 13:37:24.749 DEBUG [main][JdbcTransaction.java:136] - Opening JDBC Connection
2020-02-24 13:37:25.747 DEBUG [main][PooledDataSource.java:424] - Created connection 1486726131.
2020-02-24 13:37:25.748 DEBUG [main][JdbcTransaction.java:100] - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@589da3f3]
2020-02-24 13:37:25.753 DEBUG [main][BaseJdbcLogger.java:143] - ==> Preparing: select * from a_demo_dynasty where id = ?
2020-02-24 13:37:25.787 DEBUG [main][BaseJdbcLogger.java:143] - ==> Parameters: 1(Integer)
2020-02-24 13:37:25.927 DEBUG [main][BaseJdbcLogger.java:143] - <== Total: 1
2020-02-24 13:37:25.934 INFO [main][ADemoDynastyTest.java:47] - 朝代表===ADemoDynasty [id=1, name=东汉, content=东汉, stYear=25, edYear=220, guoZuo=195, capital=洛阳, status=1, createTime=Sat Nov 23 02:06:11 CST 2019, updateTime=Sat Nov 23 02:06:11 CST 2019, pubTime=Sat Nov 23 02:06:11 CST 2019]
2020-02-24 13:37:25.934 DEBUG [main][JdbcTransaction.java:122] - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@589da3f3]
2020-02-24 13:37:25.935 DEBUG [main][JdbcTransaction.java:90] - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@589da3f3]
2020-02-24 13:37:25.936 DEBUG [main][PooledDataSource.java:381] - Returned connection 1486726131 to pool.
2020-02-24 13:37:25.936 INFO [main][BaseTest.java:40] - Close All Configuration…………