写在前面
这是博主第一次尝试写这种类似总结,文笔也不好见谅,由于总结能力很差所以本文基本是参照孤傲苍狼的博客,在基础上添加和修改了一些内容
孤傲苍狼的博客:https://www.cnblogs.com/xdp-gacl/category/655890.html
代码中会有很多重要的注释,请不要忽略
1、介绍
MyBatis是一个款优秀的持久层框架,它支持定制化的SQL、存储过程以及高级映射。MyBatis封装了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解来配置和映射原生信息,将接口和POJO对象(javaBean)映射成数据库中的记录。
2、快速入门
2.0 准备JUnit
文章中所有测试都使用JUnit5测试,此处做一个简单说明。
JUnit介绍
JUnit是一个Java的单元测试框架。(单元测试后期学习后会写一篇单独总结)
使用JUnit
1、下载JUnit架包,导入到工程中。
注:Eclipse中自带有JUnit
- 右键工程–打开properties
- 找到Java Build Path
- 在选项卡Libraries–> Add Library
2、在需要测试的方法上加上注解@Test
import org.junit.jupiter.api.Test;
/**
*Test注解的方法必须无返回值,无参数
**/
public class TestDemo {
@Test
public void print() {
System.out.println("hello world!");
}
}
3、选中方法右键 Run As --> JUnit Test
注:JUnit还可以新建JUnit Test Case,由于不常用,此处不做说明。
2.1准备MyBatis环境
1、新建工程,普通工程或web工程均可。(文章使用web工程)
-
导入架包到
lib
文件夹中 - mybatis-xxx.jar
-
mysql-connector-java-xxx.jar
2、准备数据库(本文使用mysql)
SQL
CREATE DATABASE mybatis;
USE mybatis;
CREATE TABLE `user`(
u_id INT PRIMARY KEY AUTO_INCREMENT,
u_account VARCHAR(50),
u_password VARCHAR(50)
);
INSERT INTO `user`(u_name,u_password) VALUES
("acc_1",123456),
("acc_2",654321);
2.2 使用MyBatis查询数据
MyBatis封装了JDBC几乎所有的操作,使用SqlSession来执行,所以先使用SqlSessionFactory获取SqlSession。
1、给SqlSessionFactoy配置conifg.xml
在src目录下创建config.xml
- 开头引入的dtd约束文件不能少
- config.xml文件名随意,用SqlSessionFactory获取时可以指定
<?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="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED"> <!-- 使用pooled连接池 -->
<!--数据库连接配置-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
</configuration>
2、定义和数据库对应的Bean对象
package com.project.bean;
public class UserBean {
//务必和数据库中的列名称对应
int u_id;
String u_account;
String u_password;
//提供无参构造
//提供getter、setter
//提供一个toString,方便打印测试
}
3、定义操作user表的SQL映射文件
新建一个包,在包中新建UserMapper.xml
xml放在包下是方便在不启动Tomact的情况下读取,如果有方便不启动Tomcat读取WebContent下文件的的方法麻烦回复一下
<?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">
<!-- namespac命名空间,用于外部指定这个mapper
任何名称都可以,这里使用类似类全路径的名称:
1、官方推荐这样做
2、后期使用接口时方便
-->
<mapper namespace="com.project.mapper.UserBeanMapper">
<!-- 注意这里resultType中的值是一个设置的别名,在config中设置 -->
<select id="getUser" resultType="UserBean">
SELECT * FROM user;
</select>
</mapper>
4、在config.cml中注册UserMapper.xml
不知道读者有没有注意到UserMapper中提到的resultType的别名,这是为了简化所以设置了一个别名,如果不设置可以直接写bean对象的类全路径。
为什么返回的类型是一个bean对象呢?
如果你使用过JDBC,你肯定在有从ResultSet把属性一个个取出来set到bean对象中的经历,很显然这里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>
<!-- 设置别名 [别名,类全路径]-->
<typeAliases>
<typeAlias alias="UserBean" type="com.project.bean.UserBean" />
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED"> <!-- 使用连接池 -->
<!--数据库连接配置 -->
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<mappers>
<!-- mapper.xml路径 -->
<mapper resource="com/project/xml/UserMapper.xml" />
</mappers>
</configuration>
注意:在编写config.xml时,请按照顺序写标签,下图是官方文档里给出文档结构
5、查询数据
从SqlSessionFactory中获取SqlSession,为了使用方便我们把获取SqlSession的操作封装在一个类中。
package com.project.mybatis.util;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
/*
* 在获取Factory时使用单例,这个对象创建很消耗资源,
* 而我们在使用时SqlSession时可能多次频繁获取,所以这个工厂应该一直存在。
* 官方文档在生命周期中也提到,没有任何理由对这个工厂对象进行清除、重建,所以不要重复创建多次。
*/
public class MyBatisUtil {
private static SqlSessionFactory factory = null;
public static SqlSessionFactory getSqlSessionFactory() {
if (factory == null) {
String path = "config.xml";
try {
// Resources是官方封装的工具类,导包时注意 --> org.apache.ibatis.io.Resources
InputStream in = Resources.getResourceAsStream(path);
factory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
return factory;
}
public static SqlSession getSqlSession() {
return getSqlSessionFactory().openSession();
}
public static SqlSession getSqlSession(boolean aotuCommit) {
return getSqlSessionFactory().openSession(aotuCommit);
}
}
编写一个测试类查询数据
package com.project.mian;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
import com.project.bean.UserBean;
import com.project.mybatis.util.MyBatisUtil;
public class MainClass {
//注意这里没有使用main,而是使用了前面提到的JUnit。也可以换成main来测试
@Test
public void test() {
SqlSession session = MyBatisUtil.getSqlSession();
try {
List<UserBean> list = session.selectList("com.project.mapper.UserBeanMapper.getUser");
for (UserBean user : list) {
System.out.println(user);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
session.close();
}
}
}
注意:这段代码并不会强制捕获异常,但是任应按照这种格式编写,确保SqlSession每次执行都能关闭。这也是官方推荐的写法。
SqlSession session = sqlSessionFactory.openSession();
try {
// do work
} finally {
session.close();
}
输出结果: