mybatis基础学习 基于maven
一、MyBatis 简介
1.MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。
2.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
3.MyBatis可以使用简单的XML或注解用于配置和原 始映射,将接口和Java的POJO(Plain Old Java Objects 普通的Java对象)映射成数据库中的记录
二、 为什么要使用Mybatis
1.Mybatis 是半自动化的持久化层框架。
2.JDBC
--sql夹在java代码块中,耦合度高导致硬编码内伤
--维护不易且实际开发需求中sql是有变化,频繁修改的情况多见
3.对开发人员而言,核心sql还是需要自己优化
4.sql和java编码分开,功能边界清晰,一个专注业务、 一个专注数据。
三、去哪里找MyBatis?
Releases · mybatis/mybatis-3 · GitHub
四、MyBatis-HelloWorld
1.简单数据表
DROP TABLE IF EXISTS `tbl_employee`;
CREATE TABLE `tbl_employee` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`last_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`gender` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
2.采用maven 搭建项目
a.导入依赖pom.xml
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
b. 创建是实体类
@Data
public class Employee {
private Integer id;
private String lastName;
private String email;
private String gender;
}
c.在resources目录下配置文件
(1) log4j.xml 日志文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="https://logging.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>
(2) 配置数据库连接池 SqlMapConfig.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>
<!-- 配置mysql环境-->
<environments default="mysql">
<environment id="mysql">
<!--配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源-->
<dataSource type="POOLED">
<!-- 配置数据库四个基本数据信息-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="1234"/>
</dataSource>
</environment>
</environments>
<!-- 指定映射文件的位置,映射配置文件指的是dao的配置文件 -->
<mappers>
<mapper resource="com/atguigu/mybatis/EmployeeMapper.xml"></mapper>
</mappers>
</configuration>
(3) 配置映射文件 EmployeeMapper.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">
<!--
1.namespace=
名称空间
"com.atguigu.mybatis.entity.EmployeeMapper"为全限定路径
-->
<mapper namespace="com.atguigu.mybatis.EmployeeMapper">
<!-- 配置查询所有-->
<select id="findAll" resultType="com.atguigu.mybatis.entity.Employee">
select id,last_name lastName,email,gender from tbl_employee ORDER by id desc
</select>
<select id="findOne" resultType="com.atguigu.mybatis.entity.Employee" >
select id,last_name lastName,email,gender from tbl_employee where id = #{id}
</select>
</mapper>
d.在test目录下测试配置信息是否正确 MyBatisTest.java
public class MyBatisTest {
public SqlSessionFactory getSqlSessionFactory() throws IOException {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
return new SqlSessionFactoryBuilder().build(inputStream);
}
/**
* 1、根据xml配置文件(全局配置文件)创建一个SqlSessionFactory对象 有数据源一些运行环境信息
* 2、sql映射文件;配置了每一个sql,以及sql的封装规则等。
* 3、将sql映射文件注册在全局配置文件中
* 4、写代码:
* 1)、根据全局配置文件得到SqlSessionFactory;
* 2)、使用sqlSession工厂,获取到sqlSession对象使用他来执行增删改查
* 一个sqlSession就是代表和数据库的一次会话,用完关闭
* 3)、使用sql的唯一标志来告诉MyBatis执行哪个sql。sql都是保存在sql映射文件中的。
*
* @throws IOException
*/
@Test
public void test() throws IOException {
// 2、获取sqlSession实例,能直接执行已经映射的sql语句
// sql的唯一标识:statement Unique identifier matching the statement to use.
// 执行sql要用的参数:parameter A parameter object to pass to the statement.
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
try {
List<Employee> employee = openSession.selectList("findAll");
for (Employee i:employee){
System.out.println(i);
}
// Employee employee = openSession.selectOne("findOne", 1);
// System.out.println(employee);
} finally {
openSession.close();
}
}
}
e.以上测试结果正确
DEBUG 05-13 14:35:34,940 ==> Preparing: select id,last_name lastName,email,gender from tbl_employee ORDER by id desc (BaseJdbcLogger.java:145)
DEBUG 05-13 14:35:34,985 ==> Parameters: (BaseJdbcLogger.java:145)
DEBUG 05-13 14:35:35,025 <== Total: 2 (BaseJdbcLogger.java:145)
Employee(id=2, lastName=yan, email=56@qq.com, gender=1)
Employee(id=1, lastName=tom, email=29@qq.com, gender=0)
3.在原有项目基础上扩展(接口式编程)
a.创建一个dao层
public interface EmployeeMapper {
public Employee findOne(Integer id);
}
b.在配置映射文件 EmployeeMapper.xml 修改namespase 实现对dao层的动态绑定(代理对象)
namespace="com.atguigu.mybatis.dao.EmployeeMapper"
c.测试类
@Test
public void test1() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
Employee employee1 = mapper.findOne(1);
System.out.println(employee1);
openSession.close();
}
//输出结果
DEBUG 05-13 14:59:32,559 ==> Preparing: select id,last_name lastName,email,gender from tbl_employee where id = ? (BaseJdbcLogger.java:145)
DEBUG 05-13 14:59:32,681 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:145)
DEBUG 05-13 14:59:32,730 <== Total: 1 (BaseJdbcLogger.java:145)
Employee(id=1, lastName=tom, email=29@qq.com, gender=0)
d.有个dao层封装的话,就可以返回指定的对象(返回值)
4.总结
* 1、接口式编程
* 原生: Dao ====> DaoImpl
* mybatis: Mapper ====> xxMapper.xml
*
* 2、SqlSession代表和数据库的一次会话;用完必须关闭;
* 3、SqlSession和connection一样她都是非线程安全。每次使用都应该去获取新的对象。
* 4、mapper接口没有实现类,但是mybatis会为这个接口生成一个代理对象。
* (将接口和xml进行绑定)
* EmployeeMapper empMapper = sqlSession.getMapper(EmployeeMapper.class);
* 5、两个重要的配置文件:
* mybatis的全局配置文件:包含数据库连接池信息,事务管理器信息等...系统运行环境信息
* sql映射文件:保存了每一个sql语句的映射信息:
* 将sql抽取出来
五、MyBatis-全局配置文件
1.properties属性 引入外部配置文件
如果属性在不只一个地方进行了配置,那么 MyBatis 将按照下面的顺序来加载:
– 在 properties 元素体内指定的属性首先被读取。
– 然后根据 properties 元素中的 resource 属性读取类路径下属性文件或根据 url 属性指定的路径读取属性文件,并覆盖已读取的同名属性。
– 最后读取作为方法参数传递的属性,并覆盖已读取的同名属性。
a.resources目录创建properties文件
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=1234
b. 在全局数据配置文件中修改
<!--加入-->
<properties resource="dbconfig.properties"/>
<!-- 修改 -->
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
2.settings设置 会改变 MyBatis 的运行时行为。
a. 测试
1.开启驼峰命令的规则
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
2.在数据库中字段为last_name 实体类中为lastName ,就可以不用在sql语句中采用别名的方式了
3.typeAliases别名处理器
A.类型别名是为 Java 类型设置一个短的名字,可以方便我们 引用某个类。
<typeAliases>
<typeAlias type="com.atguigu.mybatis.entity.Employee" alias="employee"/>
</typeAliases>
resultType="employee"
B.类很多的情况下,可以批量设置别名这个包下的每一个类 创建一个默认的别名,就是简单类名小写。
4.typeHandlers类型处理器
无论是 MyBatis 在预处理语句(PreparedStatement)中 设置一个参数时,还是从结果集中取出一个值时, 都会 用类型处理器将获取的值以合适的方式转换成 Java 类型。
//获取获取类型处理器
@Test
public void test2() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
TypeHandlerRegistry typeHandlerRegistry = sqlSession.getConfiguration().getTypeHandlerRegistry();
Collection<TypeHandler<?>> handlers = typeHandlerRegistry.getTypeHandlers();
System.out.println(handlers.size());
for (TypeHandler<?> typeHandler : handlers) {
System.out.println(typeHandler.getClass().getName());
}
}
5.plugins插件
插件是MyBatis提供的一个非常强大的机制,我们 可以通过插件来修改MyBatis的一些核心行为。插件通过动态代理机制,可以介入四大对象的任何 一个方法的执行。
6.environments环境
a.简介
-
MyBatis可以配置多种环境,比如开发、测试和生 产环境需要有不同的配置。
-
每种环境使用一个environment标签进行配置并指 定唯一标识符
-
可以通过environments标签中的default属性指定 一个环境的标识符来快速的切换环境
b. id:指定当前环境的唯一标识 transactionManager、和dataSource都必须有
<!-- 配置mysql环境-->
<environments default="test">
<environment id="test">
<!--配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源-->
<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="dev">
<!--配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源-->
<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="123456"/>
</dataSource>
</environment>
</environments>
c.两种环境,一个是dev 密码错误的,一个是好的 用于环境测试
7.transactionManager 事物管理器
MyBatis 支持两种类型的事务管理器: JDBC and MANAGED and 自定义
JDBC 事务管理器被用作当应用程序负责管理数据库连接的生命周期(提交、回退等等)的时候。当你将
TransactionManager 属性设置成 JDBC,MyBatis 内部将使用 JdbcTransactionFactory 类创建
TransactionManager。
MANAGED 事务管理器是当由应用服务器负责管理数据库连接生命周期的时候使用。当你将
TransactionManager 属性设置成 MANAGED 时,MyBatis 内部使用 ManagedTransactionFactory 类
创建事务管理器TransactionManager。例如,当一个JavaEE的应用程序部署在类似 JBoss,WebLogic,
GlassFish 应用服务器上时,它们会使用 EJB 进行应用服务器的事务管理能力。在这些管理环境中,你
可以使用 MANAGED 事务管理器。
自定义:实现TransactionFactory接口,type=全类名/ 别
<transactionManager type="JDBC"></transactionManager>
8.dataSource 数据源配置
type: UNPOOLED | POOLED | JNDI | 自定义
– UNPOOLED:不使用连接池, UnpooledDataSourceFactory
– POOLED:使用连接池, PooledDataSourceFactory
– JNDI: 在EJB 或应用服务器这类容器中查找指定的数 据源
– 自定义:实现DataSourceFactory接口,定义数据源的 获取方式。
• 实际开发中我们使用Spring管理数据源,并进行 事务控制的配置来覆盖上述配置
9.databaseIdProvider环境
MyBatis 可以根据不同的数据库厂商执行不同的语句。
<databaseIdProvider type="DB_VENDOR">
<!-- 为不同的数据库厂商起别名 -->
<property name="MySQL" value="mysql"/>
<property name="Oracle" value="oracle"/>
<property name="SQL Server" value="sqlserver"/>
</databaseIdProvider>
10.mapper映射
mapper:注册一个sql映射
注册配置文件
resource:引用类路径下的sql映射文件
mybatis/mapper/EmployeeMapper.xml
url:引用网路路径或者磁盘路径下的sql映射文件
file:///var/mappers/AuthorMapper.xml
注册接口
class:引用(注册)接口,
1、有sql映射文件,映射文件名必须和接口同名,并且放在与接口同一目录下;
2、没有sql映射文件,所有的sql都是利用注解写在接口上;
推荐:
比较重要的,复杂的Dao接口我们来写sql映射文件
不重要,简单的Dao接口为了开发快速可以使用注解;
<!-- <mapper resource="mybatis/mapper/EmployeeMapper.xml"/> -->
<!-- <mapper class="com.atguigu.mybatis.dao.EmployeeMapperAnnotation"/> -->
<!-- 批量注册: -->
<package name="com.atguigu.mybatis.dao"/>