第一章:MyBatis上
1.1:MyBatis简介
-
MyBatis
历史
MyBatis
最初是Apache
的一个开源项目iBatis
,2010年6月这个项目由Apache Software Foundation
迁移到了Google Code
。随着开发团队转投Google Code
旗下,iBatis 3.x
正式更名为MyBatis
。代码与2013年11月迁移到GitHub
。
iBatis
一词来源于internet
和abatis
的组合,是一个基于java
的持久层框架。iBatis
提供的持久层框架包括SQL Maps
和Data Access Objects(DAO)
。 -
MyBatis
特性MyBatis
是支持定制化SQL
,存储过程以及高级映射的优秀的持久层框架。MyBatis
避免了几乎所有的JBDC
代码和手动设置参数以及获取结果集。MyBatis
可以使用简单的XML
或注解用于配置和原始映射,将接口和Java
的POJO
(Plain Old Java Objects
,普通的Java
对象)映射成数据库中的记录。MyBatis
是一个半自动话的ORM
(Object Relation Mapper
)框架。
-
MyBatis
下载MyBatis
下载地址:https://github.com/mybatis/mybatis-3
-
和其他持久化层技术对比
JDBC
SQL
夹杂在Java
代码中耦合度高,导致硬编码内伤。- 维护不易且实际开发需求中
SQL
有变化,频繁修改的情况多见。 - 代码冗长,开发效率低。
Hibernate
和JPA
- 操作简便,开发效率高。
- 程序中的长难复杂
SQL
需要绕过框架。 - 内部自动生产的
SQL
,不容易做特殊优化。 - 基于全映射的自动框架,大量字段的
POJO
进行部分映射时比较困难。 - 反射操作太多,导致数据库性能下降。
NyBatis
- 轻量级,性能出色。
SQL
和Java
编码分开,功能边界清晰。Java
代码专注业务,SQL
语句专注数据。- 开发效率稍逊于
Hibernate
,但是完全能够个接受。
1.2:搭建MyBatis
-
创建一个空项目
SSM
以后都在这个项目里面添加模块。
-
添加一个模块
mybatis_helloworld_01
添加后续模块都是如此步骤。
-
在
pom.xml
导入jar
包<packaging>jar</packaging> <dependencies> <!-- Mybatis核心 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <!-- junit测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- MySQL驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency> </dependencies>
-
创建一个
ssm
的数据库,并创建一张t_user
表CREATE DATABASE ssm; USE ssm; CREATE TABLE t_user ( id int NOT NULL AUTO_INCREMENT, username varchar(20) DEFAULT NULL, password varchar(20) DEFAULT NULL, age int DEFAULT NULL, gender char(1) DEFAULT NULL, email varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) );
-
创建
t_user
表对应的实体类在
src/main/java
路径下创建。java
代码都放在这路径下面。package com.wang.pojo; public class User { private Integer id; private String username; private String password; private Integer age; private String gender; private String email; // 如下省略空参构造、全参构造、get/set方法、toString方法 }
-
创建
MyBatis
的核心配置文件 习惯上命名为
mybatis-config.xml
,这个文件名仅仅只是建议,并非强制要求。核心配置文件主要用于配置连接数据库的环境以及MyBatis
的全局配置信息。 核心配置文件存放的位置是
src/main/resources
目录下,其他的配置文件也都是放在这个路径下。<?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"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="abc123"/> </dataSource> </environment> </environments> <mappers> <mapper resource=""/> </mappers> </configuration>
-
创建
mapper
接口
MyBatis
中的mapper
接口相当于以前的dao
。但是区别在于,mapper
仅仅是接口,我们不需要提供实现类。package com.wang.mapper; public interface UserMapper { int insertUser(); }
-
创建
MyBatis
的映射文件-
映射文件的命名规则
表对应的实体类的类名+
mapper.xml
。MyBatis
映射文件存放的位置是src/main/resources/mappers
目录下。 -
MyBatis
中可以面向接口操作数据,要保证两个一直mapper
接口的全类名和映射文件的命名空间namespace
保持一致。mapper
接口中方法的方法名和映射文件中编写的SQL
标签的id
属性保持一致。
<?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.wang.mapper.UserMapper"> <!-- int insertUser();--> <insert id="insertUser"> insert into t_user values(null, 'admin', '123456', 23, '男', '123456@qq.com') </insert> </mapper>
-
-
通过
junit
测试功能测试的代码放在
src/test/java
路径下。package com.wang.test; public class MyBatisTest { @Test public void testInsert() throws IOException { // 获取核心配置文件的输入流 InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); // 获取SqlSessionFactoryBuilder对象 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); // 获取SqlSessionFactory对象 SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is); // 获取sql的会话对象SqlSession(不会自动提交事务),是MyBatis提供的操作数据库的对象 // SqlSession sqlSession = sqlSessionFactory.openSession(); // 获取sql的会话对象SqlSession(会自动提交事务),是MyBatis提供的操作数据库的对象 SqlSession sqlSession = sqlSessionFactory.openSession(true); // 获取UserMapper的代理实现类对象 UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 调用mapper接口中的方法,实现添加用户信息的功能 int result = mapper.insertUser(); // 提供sql以及的唯一标识找到sql并执行,唯一标识是namespace.sqlId // int result = sqlSession.insert("com.wang.mybatis.mapper.UserMapper.insertUser"); System.out.println("结果: " + result); // 默认事务回滚,需要手动提交 //sqlSession.commit(); sqlSession.close(); } }
-
加入
log4j
日志功能-
在
pom.xml
添加jar
包<!-- log4j日志 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
-
加入
log4j
的配置文件log4j
的配置文件名为log4j.xml
。日志的级别:
FATAL
(致命) >ERROR
(错误) >WARN
(警告) >INFO
(信息) >DEBUG
(调试)。从左到右打印的内容越来越详细。<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> <param name="Encoding" value="UTF-8" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" /> </layout> </appender> <logger name="java.sql"> <level value="debug" /> </logger> <logger name="org.apache.ibatis"> <level value="info" /> </logger> <root> <level value="debug" /> <appender-ref ref="STDOUT" /> </root> </log4j:configuration>
-
1.3:MyBatis的增删改查
-
创建工具类
SqlSessionUtil
获取SqlSession
package com.wang.utils; public class SqlSessionUtil { public static SqlSession getSqlSession() { SqlSession sqlSession = null; try { InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is); sqlSession = sqlSessionFactory.openSession(true); } catch (IOException e) { e.printStackTrace(); } return sqlSession; } }
-
删
-
在
UserMapper.java
中添加接口// 删除用户信息 void deleteUser();
-
在
UserMapper.xml
映射文件添加SQL
<!-- 删除用户信息 --> <delete id="deleteUser"> delete from t_user where id = 3 </delete>
-
测试功能
@Test public void testDelete() { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); mapper.deleteUser(); sqlSession.close(); }
-
-
改
-
在
UserMapper.java
中添加接口// 修改用户信息 void updateUser();
-
在
UserMapper.xml
映射文件添加SQL
<!-- 修改用户信息 --> <update id="updateUser"> update t_user set username='root', password='123' where id = 2 </update>
-
测试功能
@Test public void testUpdate() { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); mapper.updateUser(); sqlSession.close(); }
-
-
查
-
在
UserMapper.java
中添加接口// 根据id查询用户信息 User getUserById(); // 查询所有的用户信息 List<User> getAllUser();
-
在
UserMapper.xml
映射文件添加SQL
<!-- 结果集映射,这两种映射只能二选一: resultType: 设置结果类型,即查询的数据要转换为的java类型。 resultMap: 自定义映射,处理多对一或一对多的映射关系 --> <!-- 根据id查询用户信息 --> <select id="getUserById" resultType="com.wang.pojo.User"> select * from t_user where id = 1 </select> <!-- 查询所有的用户信息 --> <select id="getAllUser" resultType="com.wang.pojo.User"> select * from t_user </select>
-
测试功能
@Test public void testGetUserById() { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.getUserById(); System.out.println(user); sqlSession.close(); } @Test public void testGetAllUser() { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> list = mapper.getAllUser(); list.forEach(System.out::println); sqlSession.close(); }
-
1.4:核心配置文件详解
<?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>
<!--
MyBatis核心配置文件中的标签必须要按照指定的顺序配置
properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,
reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?
-->
<!-- 引入properties文件,此后就可以在当前文件中使用${key}的方式访问value -->
<properties resource="jdbc.properties" />
<!--
typeAliases: 设置类型别名,即为某个具体的类型设置一个别名,在MyBatis的范围中,就可以使用别名表示一个具体的类型
-->
<typeAliases>
<!--
type: 设置需要起别名的类型
alias: 设置某个类型的别名, 如果没有此属性,则默认是类名,且不区分大小写。
-->
<!-- <typeAlias type="com.wang.pojo.User" alias="abc"></typeAlias>-->
<!-- <typeAlias type="com.wang.pojo.User"></typeAlias>-->
<!-- 通过包设置类型别名,指定包下所有的类型将全部拥有默认的别名,即类名且不区分大小写 -->
<package name="com.wang.pojo" />
</typeAliases>
<!--
environments:配置连接数据库的环境
default: 设置默认使用的环境的id
-->
<environments default="development">
<!--
environment:设置一个具体的连接数据库的环境
id: 设置环境的唯一标识,不能重复
-->
<environment id="development">
<!--
transactionManager:设置事务管理器
type: 设置事务管理的方式,属性值为JDBC或MANAGED
JDBC:标识使用JDBC中原生的事务管理方式
MANAGED:被管理,例如Spring
-->
<transactionManager type="JDBC"/>
<!--
dataSource:设置数据源
type: 设置数据源的类型,属性值为POOLED、UNPOOLED或JNDI
POOLED:表示使用数据库连接池
UNPOOLED:表示不使用数据库连接池
JNDI: 表示使用上下文中的数据源
-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="abc123"/>
</dataSource>
</environment>
</environments>
<!-- 引入mybatis的映射文件 -->
<mappers>
<!-- <mapper resource="mappers/UserMapper.xml"/>-->
<!--
以包的方式引入映射文件,但是必须满足两个条件:
1. mapper接口和映射文件所在的包必须一致。
2. mapper接口的名字和映射文件的名字必须一致。
-->
<package name="com.wang.mapper" />
</mappers>
</configuration>
需要引入jdbc.properties
文件:
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
jdbc.username=root
jdbc.password=abc123