本想着寒假稳定更新的,但是一到过年事可真不少,没时间更新就补了下MySQL和JVM,瑞雪兆丰年,新的一年希望有个好的结果。
我们使用框架的原因就是因为框架可以在很大程度上简化和减少我们的工作量,让我们工作更高效。这次就让我们来看一下代替原始JDBC的主流ORM框架MyBatis。
MyBatis本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。 MyBatis是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。 --《百度百科》
提到了MyBatis就离不开ORM(Object Relational Mapping),对象关系映射。ORM是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。
简单来说就是在我的Java代码中存在与数据库相对应的持久化类,它的作用就是,在数据库表与Java对象间做一个自动映射,将表映射为Java对象,通过对象来对数据库表进行操作。
Mybatis是一个目前非常主流的ORM框架,主流的还有JPA/Hibernate。 它俩的优劣不用去评判,我感觉都很厉害的。 想必好多javer第一次了解ORM这个概念时,就是先学习的Hibernate,我当时真是感觉开启了一个新世界,完全不用去考虑具体的sql是如何实现的,因为Hibernate本身已经封装好了我们的CRUD,只是随着知识的增加,业务逻辑开始相对复杂了起来后,感觉Hibernate还是很好只是API太多了,各种组合,用的晕头转向,还不如自己写个sql。 Mybatis并没有封装相应的CRUD但是有代码生成器,还是挺不错的,与Hibernate相比Mybatis并没有将Java对象与数据库表相关联,而是将Java方法与Sql语句相关联,MyBatis提供了一个映射引擎,将SQL语句的执行结果与对象树映射起来。
这次不使用SpringBoot集成MyBatis,而是构建一个Maven项目来学习MyBatis,这样可以更好的理解MyBatis的运行流程。
我用的DBMS是mysql 8.0.18 ,可视化工具是Navicat Premium 15
具体sql语句:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for test
-- ----------------------------
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`age` int(11) NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of test
-- ----------------------------
INSERT INTO `test` VALUES (1, 'zxjj', 15);
INSERT INTO `test` VALUES (2, 'zzxjj', 16);
INSERT INTO `test` VALUES (3, 'zzxkj', 17);
SET FOREIGN_KEY_CHECKS = 1;
POM(Project Object Model),项目对象模型。通过xml可扩展标记语言(EXtensible Markup Language)格式保存的pom.xml文件。该文件用于管理:源代码、配置文件、开发者的信息和角色、问题追踪系统、组织信息、项目授权、项目的url、项目的依赖关系等等。这里是的作用是作为Maven的配置文件。在Maven项目中,我们不用再去网上下载jar包了,只需在pom.xml文件中导入相应的jar包依赖即可。
完整的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>zzxkj.mybatis</groupId>
<artifactId>Mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
/*MyBatis包,这里是3.3.0版本*/
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.0</version>
</dependency>
/*mysql驱动,这里是MySql8的驱动*/
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
/*lombok,一个很实用的插件*/
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
</dependency>
/*junit4,一个单元测试框架*/
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
<?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>
<package name="mapper"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<!-- 数据库的配置 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/xxx?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai"></property>
<property name="username" value="root"></property>
<property name="password" value="xxxx"></property>
</dataSource>
</environment>
</environments>
<!--加载映射文件-->
<mappers>
<!-- //单个文件路径配置
<mapper resource="mapper/TypeMapper.xml"></mapper>
<mapper resource="mapper/UserMapper.xml"></mapper>
-->
//通过包路径扫描
<package name="mapper"/>
</mappers>
</configuration>
(1)实体类:
注释:@Data注解为Lombok注解,可以自动为变量添加set/get方法,若不使用@Data则自行添加set/get方法
@Data
public class Test {
private int id;
private String name;
private int age;
}
(2)Mapper接口
MyBatis引用Mapper接口这种调用方式,是为了满足面向接口编程的需要。(其实还有一个原因是在于,MyBatis 3.x引入了注解,使得用户在接口上可以使用注解来配置SQL语句,这样就可以脱离XML配置文件,实现“0配置”)
public interface TestMapper {
//按名获取
Test getTest(int id);
//全部获取
List<Test> getTests();
}
(3)TestMapper.xml文件
<?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="mapper.TestMapper">
<!--前面已配置别名,这里的resultType属性可以填成Test,即类名,否则如下,填类全限定名-->
<!--返回结果为一条语句时,为Test-->
<select id="getTest" resultType="entity.Test">
select * from test where id = #{id};
</select>
<!--返回结果为多条语句时,同样为Test,而不是list,会批量返回Test类型,即为list-->
<select id="getTests" resultType="entity.Test">
select * from test;
</select>
</mapper>
注释:namespace:通过接口的全限定名来将XML与接口相关联; id:不难看出该值和接口中方法名一致,用以将接口方法与SQL语句相关联; resultType:返回结果类型,sting,JavaBean,list(还是JavaBean),map
GeneralMapper类:
public class GeneralMapper {
//在子类共享的sqlSessionFactory对象
private static SqlSessionFactory sqlSessionFactory;
//@BeforeClass在当前类的所有测试方法之前执行。注解在【静态方法】上
//测试单元共享该资源,用于初始化sqlSessionFactory
@BeforeClass
public static void init(){
try {
//读取配置文件
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
//创建sqlSessionFactory工厂对象
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
//关闭IO
reader.close();
}catch (IOException e){
e.printStackTrace();
}
}
//获取sqlSession对象
public SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
TestMapperTest类:
public class TestMapperTest extends GeneralMapper {
//获取sqlSession
SqlSession sqlSession = getSqlSession();
@Test
public void getTypeTest(){
try{
//获取UserMapper接口
TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
//调用getType,因为entity.Test与Junit的@Test名称冲突,所以这里用全限定名引入
entity.Test test= testMapper.getTest(1);
//调用getTypes
List<entity.Test> testList = testMapper.getTests();
//打印结果
System.out.println(test.toString());
System.out.println("****************");
for (entity.Test t:testList
) {
System.out.println(t.toString());
}
}finally{
sqlSession.close();
}
}
}
打印结果:
新的一年加油!💪