mybatis简单介绍及初步学习实践

1、我的第一个mybatis程序

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

mybatis简单介绍及初步学习实践_intellij idea

思路:搭建环境——>导入Mybatis——>编写代码——>测试!

2、搭建环境

2.1、搭建数据库

Create database mybatis;

Use mybatis;

CREATE table `user`(
`id` int not null,
primary key (`id`),
`name` varchar(30) default null,
`pwd` varchar(30) default null
)engine=INNODB default charset=utf8;

insert into user values
(1,'fenlin','fegnk1224'),
(2,'李四','lisi123'),
(3,'王五','wangwu123');

2.2、新建项目

1、新建一个普通的maven项目

新建流程:File——>New——>Project——>maven(next)——>填写项目工程名(next)——>Finnish

mybatis简单介绍及初步学习实践_数据持久化_02

mybatis简单介绍及初步学习实践_java_03

mybatis简单介绍及初步学习实践_mybatis_04

一个maven项目创建成功。

2、删除src目录,导入依赖

3、导入maven依赖

<!--导入依赖-->
<dependencies>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>

2.3、创建一个模块

  • 编写mybatis核心配置文件
<?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核心配置文件-->
<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?serverTimezone=UTC&useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="FengHua127070"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
  • 编写mybatis类
//sqlSessionFactory ——> sqlSession
public class MybatisUtils {

private static SqlSessionFactory sqlSessionFactory;

static {
try {
//使用Mybatis第一步:获取sqlSessionFactory对象
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//既然有了SqlSessionFactory, 顾名思义,我们就可以从中获得SqlSession的实例了
//qlSession 提供了在数据库执行 SQL 命令所需的所有方法。
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}

2.4、编写代码

主要思路

1、连接数据库

在pom.xml文件中导入需要的jar包(mysql-connector, mybatis)

2、建造工具类并配置

创建MybatisUtils工具类获取SqlSessionFactory 工厂,之后编写mybatis-config.xml配置文件(配置数据库链接地址、用户名、密码等)。

3、写实体类,然后写接口

4、写Mapper文件绑定接口

  • 实体类
package com.feng.pojo;

//实体类
public class User {
private int id;
private String name;
private String pwd;

public User() {
}

public User(int id, String name, String pwd) {
this.id = id;
this.name = name;
this.pwd = pwd;
}

public int getId() {
return id;
}

public String getName() {
return name;
}

public String getPwd() {
return pwd;
}

public void setId(int id) {
this.id = id;
}

public void setName(String name) {
this.name = name;
}

public void setPwd(String pwd) {
this.pwd = pwd;
}
}
  • Dao接口
public interface UserDao {
List<User> getUserList();
}
  • 接口实现类由原来的UserDaoimpl转变为一个Mapper配置文件
<?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">
<!--namespace绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.feng.dao.UserDao">
<!--Select查询语句-->
<select id="getUserList" resultType="com.feng.pojo.User">
select * from user
</select>
</mapper>

2.5、测试

注意点:

org.apache.ibatis.binding.BindingException: Type interface com.feng.dao.UserDao is not known to the MapperRegistry.

MapperRegistry是什么

mybatis简单介绍及初步学习实践_mybatis_05

测试可能遇到的问题:

1、配置文件没有注册(mybatis-config.xml的mapper中没有注册Mapper文件)

2、绑定接口错误(接口路径或接口实现类有问题)

3、方法名不对

4、返回类型不对

5、Maven导出资源问题

**注:**测试时,修改后重新运行之前必须clean或手动删除Target文件,否则运行的还是原来的Target文件,还是会报错!!!

3、CRUD

3.1、namespace

namespace中的报名要和Dao/mapper接口的包一致!

3.2、select

选择,查询语句


  • id:就是对应的namespace中的方法名
  • resultType:Sql语句执行的返回值!
  • parameterType:参数类型!

1、编写接口

//根据ID查询指定用户
User getUserById(int id);

2、编写对应的mapper中的sql语句

<!--select查询指定Id用户信息-->
<select id="getUserById" resultType="com.feng.pojo.User" parameterType="int">
select * from mybatis.user where id=#{id}
</select>

3、测试

//测试搜索指定id的用户
@Test
public void getUserById(){
SqlSession sqlSession = MybatisUtils.getSqlSession();

UserMapper mapper = sqlSession.getMapper(UserMapper.class);

User user = mapper.getUserById(1);

System.out.println(user.toString());

System.out.println("测试这里");
sqlSession.close();
}

3.3、insert

<!--插入新用户-->
<insert id="addUser" parameterType="com.feng.pojo.User">
insert into mybatis.user (id, name, pwd) value (#{id},#{name},#{pwd})
</insert>

3.4、update

<!--更新用户数据-->
<update id="updateUser" parameterType="com.feng.pojo.User">
update mybatis.user set name=#{name}, pwd=#{pwd} where id=#{id}
</update>

3.5、delete

<!--删除用户-->
<delete id="deleteUser" parameterType="int">
delete from mybatis.user where id =#{id}
</delete>

错误分析:


  • mapper与接口标签不要匹配错误
  • resource绑定mapper,需要使用路径
  • 程序配置文件符合规范
  • NULLPointerException,没有注册到资源!
  • 输出的xml文件中存在中文乱码问题!
  • maven资源导出问题

4、配置解析

4.1、核心配置文件


  • mybatis-config.xml
  • Mybatis的配置文件包含了会深深影响MyBatis行为的设置和属性信息。

configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)

4.2、环境配置(Environments)

Mybatis可以配置成适应多种环境(通过Environment来配置,使用哪个用那个)

主义:尽管可以配置多个环境,但每个SqlSessionFactory实例智能选择一种环境

学会使用配置多套运行环境

Mybatis默认的事务管理器是JDBC,连接池:POOLED

3、属性(properties)

通过properties属性来实现引用配置文件

这些属性都是可外部配置且可动态替换的,因此可在Java的属性文件中配置,通过properties元素的子元素来传递【db.properties】

mybatis简单介绍及初步学习实践_mybatis_06

编写配置文件

driver=com.mysql.jdbc.Driver
url=url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC&autoReconnect=true&failOverReadOnly=false
username=root
password=FengHua127070

4.3、属性(properties)

<properties resource="db.properties"/>

  • 可以直接引入外部文件
  • 可以增加一些属性配置
  • 如果两个文件有同一字段,优先使用外部配置文件!

4.4、类型别名(typeAliases)

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。在mybatis-config.xlm中添加。

<typeAliases>
<typeAlias type="com.feng.pojo.User" alias="User"/>
</typeAliases>

也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean.

<typeAliases>
<package name="com.feng.pojo"/>
</typeAliases>

在实体类比较少的时候时候,使用第一种方式

实体类多的话,使用第二种方式。

第一种可以DIY(自定义),第二种默认是实体类的小写,在实体类增加@Alias()注解

4.5、设置

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。

设置名

描述

有效值

默认值

cacheEnabled

全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。

true | false

true

lazyLoadingEnabled

延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 ​​fetchType​​ 属性来覆盖该项的开关状态。

true | false

false

aggressiveLazyLoading

开启时,任一方法的调用都会加载该对象的所有延迟加载属性。 否则,每个延迟加载属性会按需加载(参考 ​​lazyLoadTriggerMethods​​)。

true | false

false (在 3.4.1 及之前的版本中默认为 true)

multipleResultSetsEnabled

是否允许单个语句返回多结果集(需要数据库驱动支持)。

true | false

true

useColumnLabel

使用列标签代替列名。实际表现依赖于数据库驱动,具体可参考数据库驱动的相关文档,或通过对比测试来观察。

true | false

true

useGeneratedKeys

允许 JDBC 支持自动生成主键,需要数据库驱动支持。如果设置为 true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作(如 Derby)。

true | false

False

autoMappingBehavior

指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示关闭自动映射;PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 FULL 会自动映射任何复杂的结果集(无论是否嵌套)。

NONE, PARTIAL, FULL

PARTIAL

autoMappingUnknownColumnBehavior

指定发现自动映射目标未知列(或未知属性类型)的行为。​​NONE​​: 不做任何反应​​WARNING​​: 输出警告日志(​​'org.apache.ibatis.session.AutoMappingUnknownColumnBehavior'​​ 的日志等级必须设置为 ​​WARN​​)​​FAILING​​: 映射失败 (抛出 ​​SqlSessionException​​)

NONE, WARNING, FAILING

NONE

defaultExecutorType

配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(PreparedStatement); BATCH 执行器不仅重用语句还会执行批量更新。

SIMPLE REUSE BATCH

SIMPLE

defaultStatementTimeout

设置超时时间,它决定数据库驱动等待数据库响应的秒数。

任意正整数

未设置 (null)

defaultFetchSize

为驱动的结果集获取数量(fetchSize)设置一个建议值。此参数只可以在查询设置中被覆盖。

任意正整数

未设置 (null)

defaultResultSetType

指定语句默认的滚动策略。(新增于 3.5.2)

FORWARD_ONLY | SCROLL_SENSITIVE | SCROLL_INSENSITIVE | DEFAULT(等同于未设置)

未设置 (null)

safeRowBoundsEnabled

是否允许在嵌套语句中使用分页(RowBounds)。如果允许使用则设置为 false。

true | false

False

safeResultHandlerEnabled

是否允许在嵌套语句中使用结果处理器(ResultHandler)。如果允许使用则设置为 false。

true | false

True

mapUnderscoreToCamelCase

是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。

true | false

False

localCacheScope

MyBatis 利用本地缓存机制(Local Cache)防止循环引用和加速重复的嵌套查询。 默认值为 SESSION,会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地缓存将仅用于执行语句,对相同 SqlSession 的不同查询将不会进行缓存。

SESSION | STATEMENT

SESSION

jdbcTypeForNull

当没有为参数指定特定的 JDBC 类型时,空值的默认 JDBC 类型。 某些数据库驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。

JdbcType 常量,常用值:NULL、VARCHAR 或 OTHER。

OTHER

lazyLoadTriggerMethods

指定对象的哪些方法触发一次延迟加载。

用逗号分隔的方法列表。

equals,clone,hashCode,toString

defaultScriptingLanguage

指定动态 SQL 生成使用的默认脚本语言。

一个类型别名或全限定类名。

org.apache.ibatis.scripting.xmltags.XMLLanguageDriver

defaultEnumTypeHandler

指定 Enum 使用的默认 ​​TypeHandler​​ 。(新增于 3.4.5)

一个类型别名或全限定类名。

org.apache.ibatis.type.EnumTypeHandler

callSettersOnNulls

指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法,这在依赖于 Map.keySet() 或 null 值进行初始化时比较有用。注意基本类型(int、boolean 等)是不能设置成 null 的。

true | false

false

returnInstanceForEmptyRow

当返回行的所有列都是空时,MyBatis默认返回 ​​null​​。 当开启这个设置时,MyBatis会返回一个空实例。 请注意,它也适用于嵌套的结果集(如集合或关联)。(新增于 3.4.2)

true | false

false

logPrefix

指定 MyBatis 增加到日志名称的前缀。

任何字符串

未设置

logImpl

指定 MyBatis 所用日志的具体实现,未指定时将自动查找。

SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING

未设置

proxyFactory

指定 Mybatis 创建可延迟加载对象所用到的代理工具。

CGLIB | JAVASSIST

JAVASSIST (MyBatis 3.3 以上)

vfsImpl

指定 VFS 的实现

自定义 VFS 的实现的类全限定名,以逗号分隔。

未设置

useActualParamName

允许使用方法签名中的名称作为语句参数名称。 为了使用该特性,你的项目必须采用 Java 8 编译,并且加上 ​​-parameters​​ 选项。(新增于 3.4.1)

true | false

true

configurationFactory

指定一个提供 ​​Configuration​​ 实例的类。 这个被返回的 Configuration 实例用来加载被反序列化对象的延迟加载属性值。 这个类必须包含一个签名为​​static Configuration getConfiguration()​​ 的方法。(新增于 3.2.3)

一个类型别名或完全限定类名。

未设置

shrinkWhitespacesInSql

Removes extra whitespace characters from the SQL. Note that this also affects literal strings in SQL. (Since 3.5.5)

true | false

false

一个配置完整的 settings 元素的示例如下:

<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25"/>
<setting name="defaultFetchSize" value="100"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

4.6、其它配置



4.7、映射器(mappers)

你可以使用相对于类路径的资源引用,或完全限定资源定位符(包括 ​​file:///​​ 形式的 URL),或类名和包名等。

【推荐使用】

<!-- 使用相对于类路径的资源引用 -->
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- 使用完全限定资源定位符(URL) -->
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>

注:使用Class注意接口与xml文件在同一包下且接口与xml必须同名

<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>

注:使用时注意接口与xml文件在同一包下且接口与xml必须同名

<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
<package name="org.mybatis.builder"/>
</mappers>

优化步骤:


  • 将数据库配置文件外部引入
  • 实体类别名
  • 保证UserMapper接口与UserMapper.xmL文件改为一致且在同一包下,按自己需求进行管理。

4.8、生命周期

SqlSessionFactoryBuilder

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。

你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但是最好还是不要让其一直存在,以保证所有的 XML 解析资源可以被释放给更重要的事情。

SqlSessionFactory

SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创

建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例

模式或者静态单例模式。

SqlSession

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实

例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。 如果你现

在正在使用一种 Web 框架,要考虑 SqlSession 放在一个和 HTTP 请求对象相似的作用域中

5、ResultMap(结果集映射)

​resultMap​​​ 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ​​ResultSets​​​ 数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 ​​resultMap​​ 能够代替实现同等功能的数千行代码。ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。

<!--结果集映射-->
<resultMap id="resultMap" type="User">
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="pwd" property="password"/>
</resultMap>

<!--select查询语句-->
<select id="getUserList" resultType="user" resultMap="resultMap">
select * from mybatis.user;
</select>

6、日志


  • SLF4J
  • LOG4J
  • LOG4J2
  • JDK_LOGGING
  • COMMONS_LOGGING
  • STDOUT_LOGGING
  • NO_LOGGING

使用哪个日志可以通过mybatis-config.xml配置文件进行设置

<settings>
<!--配置日志 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

STDOUT_LOGGING标准日志输出

mybatis简单介绍及初步学习实践_mysql_07

通过日志可以查看项目的各类参数。

本次博客分享就到此结束了,希望看了本次博文的能有所收获。


mybatis简单介绍及初步学习实践_java_08

下期博文再见。努力学习,天天向上