写在前面
这是博主第一次尝试写这种类似总结,文笔也不好见谅,由于总结能力很差所以本文基本是参照孤傲苍狼的博客,在基础上添加和修改了一些内容
孤傲苍狼的博客:https://www.cnblogs.com/xdp-gacl/category/655890.html
代码中会有很多重要的注释,请不要忽略
MyBatis是一个款优秀的持久层框架,它支持定制化的SQL、存储过程以及高级映射。MyBatis封装了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解来配置和映射原生信息,将接口和POJO对象(javaBean)映射成数据库中的记录。
文章中所有测试都使用JUnit5测试,此处做一个简单说明。
JUnit是一个Java的单元测试框架。(单元测试后期学习后会写一篇单独总结)
注:Eclipse中自带有JUnit
@Test
import org.junit.jupiter.api.Test;
/**
*Test注解的方法必须无返回值,无参数
**/
public class TestDemo {
@Test
public void print() {
System.out.println("hello world!");
}
}
注:JUnit还可以新建JUnit Test Case,由于不常用,此处不做说明。
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);
MyBatis封装了JDBC几乎所有的操作,使用SqlSession来执行,所以先使用SqlSessionFactory获取SqlSession。
<configuration>
<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>
configuration>
package com.project.bean;
public class UserBean {
//务必和数据库中的列名称对应
int u_id;
String u_account;
String u_password;
//提供无参构造
//提供getter、setter
//提供一个toString,方便打印测试
}
新建一个包,在包中新建UserMapper.xml
xml放在包下是方便在不启动Tomact的情况下读取,如果有方便不启动Tomcat读取WebContent下文件的的方法麻烦回复一下
<mapper namespace="com.project.mapper.UserBeanMapper">
<select id="getUser" resultType="UserBean">
SELECT * FROM user;
select>
mapper>
不知道读者有没有注意到UserMapper中提到的resultType的别名,这是为了简化所以设置了一个别名,如果不设置可以直接写bean对象的类全路径。
为什么返回的类型是一个bean对象呢?
如果你使用过JDBC,你肯定在有从ResultSet把属性一个个取出来set到bean对象中的经历,很显然这里MyBatis帮我们做了这个麻烦事儿。
<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 resource="com/project/xml/UserMapper.xml" />
mappers>
configuration>
注意:在编写config.xml时,请按照顺序写标签,下图是官方文档里给出文档结构
从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();
}