1 MyBatis简介
MyBatis是一款优秀的半自动的ORM持久层框架,它支持自定义SQL、存储过程以及高级映射。MyBatis几乎免除了所有jdbc代码以及设置参数和获取结果集的操作。MyBatis可以通过简单的注解或XML来配置和映射原始类型、接口和Java POJO(Plan Old Java Objects:普通老式Java对象 )为数据库的记录。
官网:http://www.mybatis.org/mybatis-3/
下载地址:mybatis-3/src/site at master · mybatis/mybatis-3 · GitHub
1.1 引言
1.1.1 什么是框架
框架:软件的半成品,解决了软件开发过程中的普适性问题(可以想象成建造的房屋时的毛坯房,而剩下的装修等细节问题处理则需要自己来解决),从而提高了软件开发效率。
1.1.2 什么是ORM框架
所谓ORM,它的全称是Object Relational Mapping(即对象关系映射),也就是将数据库中的表、数据、字段与类、对象、属性一一对应的关系。
当使用jdbc完成上述ORM操作时存在大量的代码冗余,还须手工创建Connection、Statement等,还要手工将结果集封装成实体对象,不仅查询效率低,而且对数据访问没有进行过优化。
所以MyBatis框架很好将这些操作进行了一定的集成,使得我们在对数据的操作上有很大的简便之处,而MyBatis的半自动说的是他虽然JDBC相关操作进行了封装,但是我们还是得专注于对SQL语句进行编写,也就是MyBatis框架不具备自动生成SQL的功能(全自动的框架则是可以自动生成SQL语句的,开发者只需要完成对应的逻辑代码足矣),所以对于半自动框架来说,开发者本身还要具备一定的SQL能力。
2 MyBatis入门(Maven环境需要先配置好)
2.1 项目创建(此处简写,详细创建过程可参阅其它博主,本人比较懒)
新建项目---->选择Maven(记得选择自己所需的jdk版本)---->编辑GAV坐标---->完成创建
2.2 MyBatis环境搭建
在pom.xml文件中导入相关依赖
可以提前导入junit包,方便做单元测试!
<?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>com.kuangren</groupId>
<artifactId>MyBatis_One</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 依赖 -->
<dependencies>
<!-- MyBatis核心依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<!-- MySQL驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<!-- 仅仅用于测试时 -->
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
</project>
创建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>
<!-- JDBC环境配置、默认配置 -->
<environments default="development">
<!-- MySql数据库环境配置 -->
<environment id="development">
<!-- 事务管理 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 连接池,启用mysql自己的连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!-- 数据库 -->
<!-- jdk8以上版本需要加时区 -->
<property name="url" value="jdbc:mysql://localhost:3306/自己的数据库名?serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/><!-- 自己没有改的话就是root -->
<property name="password" value="自己的数据库密码"/>
</dataSource>
</environment>
</environments>
<!-- mapper路径映射,建在resources包下且最好和接口的路径相同 -->
<mappers>
<!-- 路径最好写成全路径 -->
<mapper resource="xxxMapper.xml"/>
</mappers>
</configuration>
注:mapper.xml默认建议存放在resources中,路径不能以 / 开头!
2.3 MyBatis开发步骤
2.3.1 建表
create table t_users(
id int primary key auto_increment,
name varchar(30),
password varchar(60),
sex char(6),
age int,
birthday varchar(60),
registerTime varchar(60)
)default charset utf8;
2.3.2 定义实体类
package com.kuangren.pojo;
public class User {
private Integer id;
private String name;
private String password;
private char sex;
private Integer age;
//以下全部内容可用alt+insert快速选取生成
public User() {
}
public User(Integer id, String name, String password, char sex, Integer age) {
this.id = id;
this.name = name;
this.password = password;
this.sex = sex;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", password='" + password + '\'' +
", sex=" + sex +
", age=" + age +
'}';
}
}
2.3.3 定义mapper层接口
package com.kuangren.mapper;
import com.kuangren.pojo.User;
public interface UserMapper {
//定义查询方法,查询到谁的数据
User selectUserByID(Integer id);
}
2.3.4创建mapper.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="com.kuangren.mapper.UserMapper"> <!-- 此处的namespace必须是接口的全路径 -->
<!-- id为实现类类名,resultType(输出结果集类型)为具体所需类型 -->
<select id="selectUserByID" resultType="com.kuangren.pojo.User">
select* from t_users where id = #{arg0}
</select>
</mapper>
2.3.5 做单元测试
package com.kuangren.mapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
/**
* @BelongsProject: MyBatis_One
* @BelongsPackage: com.kuangren.dao
* @Author: 青菜不会编程
* @CreateTime: 2023-03-14 10:23
* @Description: mybatis自己的API
* @Version: 1.0
*/
public class UserDaoTest {
@Test
public void test1() throws IOException {
//1.读取mybatis配置文件,获取流对象
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//2.构建sqlSessionFactory连接对象的工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.获得工厂连接对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//4.通过连接对象获取接口实现类对象
UserMapper userDao = sqlSession.getMapper(UserMapper.class);
//调用接口中的方法
System.out.println("查询结果为:"+userDao.selectUserByID(2));
}
//mybatis的传统操作方式如下所示
@Test
public void test2() throws IOException {
//1.读取mybatis配置文件,获取流对象
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//2.构建sqlSessionFactory连接对象的工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.获得工厂连接对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//4.通过连接对象直接调用接口方法
Object o = sqlSession.selectOne("com.kuangren.mapper.UserMapper.selectUserByID",2);
System.out.println("查询结果为:"+o);
}
}
注:若是jdk版本在9及以上,在运行时会出现警告,但并不会影响运行结果,如下图示例,
3 补充说明
3.1 mapper.xml文件放在resources以外时的解决方法
在pom.xml中添加<build></build>标签,将xml文件复制到classes中并在程序运行时正确读取xml文件。
<build>
<resources>
<resource>
<directory>src.main.java</directory>
<includes>
<include>*.xml</include><!-- 默认,若有新的添加则会失效 -->
<include>**/*.xml</include><!-- 新添加,*/代表一级目录,**/代表多级目录 -->
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
3.2 properties配置文件的使用
对于mybatis的核心配置文件,如果存在需要频繁的改动数据内容,可以将这些内容提取出来,以properties配置文件的形式存在。
# jdbc.properties
jdbc.driver=com.jdbc.mysql.Driver
jdbc.url=jdbc:mysql://localhost:3306/***(数据库名)?serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=******(自己的密码)
3.3 mybatis-config.xml核心配置文件优化
在前文中(2.2部分),我们做了入门式的mybatis核心配置文件的xml配置,一些小细节比较容易出现错误,若是在以后程序运行过程中逻辑代码没问题的情况下,出现配置文件的读取错误(单词拼写的错别性)的题很容易头皮发麻,因为我们在xml配置过程中会形成一种思维定式,总是以为配置文件没有问题,这就使得原本一个很简单的错误需要花费大量没必要花费的时间来进行细细排查,所以正是由于诸如此类问题的原因,我们就需要在原来的基础上做出优化或改良,使得代码易读且清晰。
3.3.1 对一些需要改动的数据提取至properties配置文件中(3.2)
3.3.2 优化核心配置文件代码(此处暂时只说mysql配置)
<configuration>
<!– 添加配置文件路径(外部配置,动态替换) –>
<properties resource="jdbc.properties" />
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></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>
</configuration>
注:$符和#符的相关讲解我将单独列出在另一篇文章中:java中$符和#符的详细说明
不难看出,通过上述优化之后,代码更加简洁易读,如果需要对某些数据做改动,则只需要更改properties配置文件中的某处数据或代码即可,而xml核心配置文件一次编写永不翻牌(在以后的开发过程中均已这种形式编写配置文件!)
3.3.3 别名配置(此处稍提一下,后续更新中会有更详细的说明!)
<?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>
<properties…… />
<typeAliases>
<!-- 方式1:<typr=eAlias>方式,
type属性值为某一个实体类的全路径,alias属性值为自己取的别名 -->
<typeAlias type="com.kuangRen.Pojo.User" alias="user" />
<!-- 方式2:<package>包扫描方式,
自动扫描包,将原类名作为别名 -->
<package name="com.kuangRen.Pojo.User">
<typeAliases>
……
</configuration>
3.4 log4j日志使用
简介:Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
3.4.1 log4j日志依赖(pom.xml中导入依赖即可)
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
3.4.2 log4j的创建与配置(properties)
#Global logging configuration
rootLogger=DEBUG,stdout
# MyBatis logging configuration ...
log4j.logger .org.mybatis .example.BlogMapper=TRACE
# Console output ..
log4j .appender .stdout=org .apache .log4j .ConsoleAppender
log4j.appender .stdout.layout=org.apache .log4j.PatternLayout
log4j.appender.stdout.layout .ConversionPattern=%5p [%t] - %m%n
3.4.3 日志级别
级别 | 说明 |
---|---|
ALL LEVEL | 打开所有日志记录开关,等级最低,用于打开所有日志记录 |
DEBUG | 输出调试信息:指出细粒度调试事件,对调试应用程序很有帮助 |
INFO | 输出提示信息:消息在粗粒度级别上突出强调应用程序的运行过程 |
WARN | 输出警告信息:表明会出现潜在错误的情形 |
ERROR | 输出错误信息:指出虽然发生错误事件,但仍然不影响系统的继续运行 |
FATAL | 输出致命错误:指出每个严重的错误事件会导致应用程序的退出 |
OFF LEVEL | 关闭所有日志记录开关:最高等级,用于关闭所有日志记录 |