Mybatis自学解析
一、简介
1.发展史
- MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis。
2.什么是mybatis
-
A).MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
-
B).MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录。
3.特点
- 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
- 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
- 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
- 提供映射标签,支持对象与数据库的orm字段关系映射
- 提供对象关系映射标签,支持对象关系组建维护
- 提供xml标签,支持编写动态sql
二、初学mybatis部署及应用测试(xml形式查询)
·初级测试
- 开发工具 IntelliJ IDEA 2019.3
- 示例图
- 依赖环境
<?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>Mybatis_review</artifactId>
<version>1.0-SNAPSHOT</version>
<!--引入依赖-->
<dependencies>
<!--引入mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.0</version>
</dependency>
<!--引入mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
</dependencies>
</project>
- Mapper-持久层
/**
* 持久层
*/
public interface studentMapper {
public List<student> findAll();
}
- 实体类
/**
* 实体类
*/
public class student {
//对象属性
private int sid;
private String name;
private String sex;
@Override
public String toString() {
return "student{" +
"sid=" + sid +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
'}';
}
//get set
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
- 6.工具类
public class sqlSesson {
//创建sqlSessionFactory
private static SqlSessionFactory sqlSessionFactory;
static{
try {
//目标文件
String url="mybatis-config.xml";
//获取目标文件数据流
InputStream is = Resources.getResourceAsStream(url);
//创建sql工厂函数
sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
e.printStackTrace();
}
}
//创建sqlSession实例 执行所有的sql语句
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
- 通过xml方式写sql语句
<?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">
<!--namespace 命名空间 与持久层对应-->
<!--id 对于持久层需要的方法名-->
<!--resultType 返回值类型-->
<!--parameterType 参数类型-->
<mapper namespace="cn.mybatis.mapper.studentMapper">
<select id="findAll" resultType="cn.mybatis.pojo.student">
select * from student
</select>
</mapper>
- 配置文件-mybatis-config.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">
<!--配置mybatis核心配置文件 configuration-->
<configuration>
<environments default="development">
<environment id="development">
<!--用jdbc做事务控制 -->
<transactionManager type="JDBC" />
<!--数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<!--useSSL=安全连接 &与&&相等 转义符 useUnicode设置使用中文编码 characterEncoding设置字符编码为UTF-8 -->
<!--配置useUnicode=true&characterEncoding=UTF-8 可避免插入中文时的乱码问题 -->
<property name="url" value="jdbc:mysql://localhost:3306/admin?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root" />
<property name="password" value="123" />
</dataSource>
</environment>
</environments>
<!--注册xml文件-->
<mappers>
<mapper resource="cn/mybatis/mapper/studentMapper.xml"></mapper>
</mappers>
</configuration>
- 测试
public class studentTest {
//获取sqlSession对象
SqlSession sqlSession=sqlSesson.getSqlSession();
@Test
public void Test(){
//执行sql语句
List<student> lst=sqlSession.selectList("cn.mybatis.mapper.studentMapper.findAll");
//遍历读取数据
for (student student : lst) {
System.out.println(student.toString());
}
}
}
三、配置文件解析
1.核心配置文件
- mybatis-config.xml
- mybatis配置文件影响着mybatis的行为和属性信息
configuration(配置)
properties(属性)*
settings(设置)*
typeAliases(类型别名)*
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)*
environment(环境变量)*
transactionManager(事务管理器)*
dataSource(数据源)*
databaseIdProvider(数据库厂商标识)
mappers(映射器)*
2.环境配置 environments
- 不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。
/**环境配置 在环境配置中可以配置多个环境变量*/
//默认default 对应 环境变量中的 id
<environments default="development">
/**环境变量 */
<environment id="development">
/**事务管理*/
<transactionManager type="JDBC">
<property name="..." value="..."/>
</transactionManager>
/**数据源*/
<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>
- 事务管理器(transactionManager)-推荐使用JDBC
MyBatis 中有两种类型的事务管理器(也就是 type="[JDBC|MANAGED]"
JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。默认情况下它会关闭连接。然而一些容器并不希望连接被关闭,因此需要将 closeConnection 属性设置为 false 来阻止默认的关闭行为。
- 数据源 (dataSource)-推荐使用POOLED
有三种内建的数据源类型(也就是 type="[UNPOOLED|POOLED|JNDI]")
UNPOOLED– 这个数据源的实现会每次请求时打开和关闭连接。
POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需 的初始化和认证时间。这种处理方式很流行,能使并发 Web 应用快速响应请求。
JNDI – 这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的数据源引用。
3.属性(properties)
-
这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。
例子:外部数据源配置文件(db.properties) -
db.properties(外部数据源)
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/admin?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=123
- 关于url后数据解释: {useSSL 译义 安全连接} {useUnicode 译义 设置使用中文编码} {characterEncoding=UTF-8 译义 设置字符编码 可避免插入中文时的乱码问题}
- mybatis设置数据库连接的两种形式
- 在mybatis-config.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">
<!--配置mybatis核心配置文件 configuration-->
<configuration>
<!--环境配置-->
<environments default="development">
<environment id="development">
<!--用jdbc做事务控制 -->
<transactionManager type="JDBC" />
<!--数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/admin? useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root" />
<property name="password" value="123" />
</dataSource>
</environment>
</environments>
<!--注册xml文件-->
<mappers>
<mapper resource="cn/mybatis/mapper/studentMapper.xml"></mapper>
</mappers>
</configuration>
- 第二种
- 通过配置外部数据源(db.properties)
- 引入外部数据源 db.properties
- 配置数据库连接池
<?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">
<!--配置mybatis核心配置文件 configuration-->
<configuration>
<!--配置外部数据源-->
<properties resource="db.properties"/>
<!--环境配置-->
<environments default="development">
<environment id="development">
<!--用jdbc做事务控制-->
<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>
<!--注册xml文件-->
<mappers>
<mapper resource="cn/mybatis/mapper/studentMapper.xml"></mapper>
</mappers>
</configuration>
4.类型别名(typeAliases)
- 特点
- 类型别名可为 Java 类型设置一个缩写名字。
- 它仅用于 XML 配置,意在降低冗余的全限定类名书写。
- 在mybatis-config.xm配置 使用{typeAlias type} 如下
配置文件中的类型便可修改成指定的别名
<!--类型别名-->
<typeAliases>
<typeAlias type="cn.mybatis.pojo.student" alias="user"></typeAlias>
</typeAliases>
<?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">
<!--namespace 命名空间 与持久层对应-->
<mapper namespace="cn.mybatis.mapper.studentMapper">
<!--id 对于持久层需要的方法名-->
<!--resultType 返回值类型-->
<!--parameterType 参数类型-->
<select id="findAll" resultType="user">
select * from student
</select>
</mapper>
- 在mybatis-config.xm配置 使用{package name} 如下
<!--类型别名-->
<typeAliases>
<!--这种方式默认使用实体类 类名 默认小写-->
<package name="cn.mybatis.pojo"/>
</typeAliases>
<!--在resultType中使用别名 或可其他位置-->
<select id="findAll" resultType="student">
select * from student
</select>
- 注意
- 在实体类比较少时候可以使用第一中,类名别名可以DIY
- 如果实体类类比较多,可使用第二中,类名不可DIY,默认使用类名 首字母小写
- .使用@Alias() 注解在实体类上使用别名
/**
* 实体类
*/
@Alias("nihao")
public class student {//属性 get set toString}
<!--类型别名-->
<typeAliases>
<!--这种方式默认使用实体类 类名 默认小写-->
<package name="cn.mybatis.pojo"/>
</typeAliases>
<select id="findAll" resultType="nihao">
select * from student
</select>
5.Mapper映射器
- 方式一:通过{< mappper resource=""/>}注册
<!--注册xml文件-->
<!--mappers映射器-->
<mappers>
<!--通过resource注册xml到映射器-->
<mapper resource="cn/mybatis/mapper/studentMapper.xml"/>
</mappers>
- 方式二:通过{< mappper class=""/>}class文件注册
- 注意:使用注解方式可以用这种方式
<mappers>
<!--通过class文件注册映射器-->
<mapper class="cn.mybatis.mapper.studentMapper"/>
</mappers>
- 方式三:通过{< package name=""/>}扫描包注册
<mappers>
<!--使用扫描包注册-->
<package name="cn.mybatis.mapper"/>
</mappers>
- 注意点
- 接口和mapper配置文件必须同名!
- 接口和mapper配置文件必须在同一包下!
6.PesultMap结果集映射
- 对于字段与属性不一致的情况下使用 xml形式映射
//数据库
id name sex
//实体类
id name sexd
<!--结果集-->
<!--type属性对应实体类 id可DIY-->
<resultMap id="stu" type="student">
<!--column 对应数据字段 property 对应实体类属性-->
<result column="sex" property="sexb"/>
</resultMap>
<!--resultMap 于结果集id对应-->
<select id="findAll" resultMap="stu">
select * from student
</select>
四、日志
- 通过settings与核心配置文件中配置
<settings>
<setting name="" value=""/>
</settings>
- SLF4J
- LOG4J 【log4j日志】
- LOG4J2
- JDK_LOGGING
- COMMONS_LOGGING
- STDOUT_LOGGING 【标准日志】
- NO_LOGGING
1.开启标准日志输出-mybatis.config.xml
<!--settings-->
<settings>
<!--自动形式的标准日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--注意空格!!!-->
//控制台输出内容!!!
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
Class not found: org.jboss.vfs.VFS
JBoss 6 VFS API is not available in this environment.
Class not found: org.jboss.vfs.VirtualFile
VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment.
Using VFS adapter org.apache.ibatis.io.DefaultVFS
Find JAR URL: file:/E:/SpaceWork-Idea/4.review_lessons/Mybatis_review/target/classes/cn/mybatis/pojo
Not a JAR: file:/E:/SpaceWork-Idea/4.review_lessons/Mybatis_review/target/classes/cn/mybatis/pojo
Reader entry: student.class
Listing file:/E:/SpaceWork-Idea/4.review_lessons/Mybatis_review/target/classes/cn/mybatis/pojo
Find JAR URL: file:/E:/SpaceWork-Idea/4.review_lessons/Mybatis_review/target/classes/cn/mybatis/pojo/student.class
Not a JAR: file:/E:/SpaceWork-Idea/4.review_lessons/Mybatis_review/target/classes/cn/mybatis/pojo/student.class
Reader entry: ���� 1 ;
Checking to see if class cn.mybatis.pojo.student matches criteria [is assignable to Object]
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 770189387.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@2de8284b]
==> Preparing: select * from student
==> Parameters:
<== Columns: sid, name, sex, age
<== Row: 1, 张三, 男, 21
<== Row: 8, 王六, 女, 40
<== Row: 12, 马克, 男, 23
<== Row: 13, 里斯, 女, 40
<== Total: 4
student{sid=1, name='张三', sex='男'}
student{sid=8, name='王六', sex='女'}
student{sid=12, name='马克', sex='男'}
student{sid=13, name='里斯', sex='女'}
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@2de8284b]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@2de8284b]
Returned connection 770189387 to pool.
Process finished with exit code 0
2.通过log4j输出日志-mybatis-config.xml
- 在核心配置文件中配置
<settings>
<!--log4j-->
<setting name="logImpl" value="LOG4J"/>
</settings>
- 引入log4依赖
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
- 导入log4j配置文件
### 设置Logger输出级别和输出目的地 ###
log4j.rootLogger=debug, stdout,logfile
### 把日志信息输出到控制台 ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
### 把日志信息输出到文件:./log/stuMybatis.log ###
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=./log/stuMybatis.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}%l %F %p %m%n
#级别 DEBUG INFO WARN ERROR FATAL
- 在需要打印日志位置加入
//加载log4j
protected static Logger logger=Logger.getLogger(studentTest.class);
- 打印日志
@Test
public void Test(){
//执行sql语句
List<student> lst=sqlSession.selectList("cn.mybatis.mapper.studentMapper.findAll");
//遍历读取数据
for (student student : lst) {
//打印日志
logger.info("info:"+student.toString());
}
sqlSession.clos();
}
五、分页
- 通过RowBounds实现分页
- mapper持久层
//分页
public List<student> pageNew(int start,int stop);
- xml配置文件
<select id="pageNew" resultType="student">
select * from student
</select>
- 测试
@Test
public void PageTest(){
int start=0;
int stop=2;
//实例RowBounds实现
RowBounds rowBounds=new RowBounds(start,stop);
//通过底层代码使用分页
//cn.mybatis.mapper.studentMapper.pageNew为接口内的方法
List<student> students=sqlSession.selectList("cn.mybatis.mapper.studentMapper.pageNew", null,rowBounds);
for (student student : students) {
System.out.println(student.toString());
}
六、使用注解开发
1.在mybatis-config核心配置文件中配置映射接口
<!--映射接口-->
<mapper class="cn.mybatis.mapper.studentMapper"/>
2.在mapper接口中写入方法和sql语句
//查询全部
@Select("select * from student")
public List<student> find();
3.测试
@Test
public void find(){
studentMapper studentMapper=sqlSession.getMapper(studentMapper.class);
List<student> lst=studentMapper.find();
//遍历读取数据
for (student student : lst) {
System.out.println(student.toString());
}
sqlSession.close();
}
如有错误,请指正,你我共同学习~
持续更新······