标签:nal and 参数 methods 序列 关闭自动 假设 允许 重用
历史
2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis
2013年11月迁移到Github
定义
一个基于Java的持久层框架
支持定制化 SQL、存储过程以及高级映射
避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 Pojos(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录
Mybatis相关资料
持久化
把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)
持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中、XML数据文件中等等
持久化是将程序数据在持久状态和瞬时状态间转换的机制
JDBC就是一种持久化机制,文件IO也是一种持久化机制
持久层
完成持久化工作的代码块
环境搭建
建数据库以及表
新建Maven项目后在pom.xml中导入依赖
<!--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>
?
<!--Lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
编写Mybatis配置文件:mybatis-config.xml
编写Mybatis工具类
1、构建SqlSessionFactory
每个基于Mybatis的应用都是以一个SqlSessionFactory的实例为核心的
SqlSessionFactoryBuilder可以从XML配置文件或者一个预先定制的Configuration的实例构建出SqlSessionFactory的实例
使用任意的输入流(InputStream)实例,通过字符串形式的文件路径,或者url形式的文件路径配置
Resources工具类可使从classpath或其他位置加载资源文件更加容易
2、从SqlSessionFactory中获取SqlSession
SqlSession 提供了在数据库执行 SQL 命令所需的所有方法
SqlSession 实例来直接执行已映射的 SQL 语句
SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession 的生命周期和作用域
SqlSessionFactoryBuilder
一旦创建了 SqlSessionFactory,就不再需要SqlSessionFactoryBuilder了
最佳作用域是方法作用域(也就是局部方法变量)
SqlSessionFactory
一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃SqlSessionFactory或重新创建另一个实例
最佳作用域是应用作用域,最简单的就是使用单例模式或者静态单例模式
SqlSession
每个线程都应该有它自己的 SqlSession 实例
最佳的作用域是请求或方法作用域
public class MybatisUtils {
?
private static SqlSessionFactory sqlSessionFactory;
?
static {
try {
//使用mybatis第一步:获取sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
?
//从 SqlSessionFactory 中获取 SqlSession
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
编写代码
实体类
Dao接口,UserMapper
public interface UserMapper {
List<User> getUserList();
}
接口实现类,UserMapper.xml
在mybatis的配置文件中给每个Mapper.xml配置mapper
<!--每一个Mapper.xml都需要在核心配置文件中注册-->
<mappers>
<mapper resource="com/hmx/dao/UserMapper.xml"/>
</mappers>
测试
public class UserMapperTest {
public static void main(String[] args) {
?
//第一步:获得SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
?
//获得mapper,执行sql语句
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = userMapper.getUserList();
?
//输出结果
for (User user : userList) {
System.out.println(user);
}
//关闭SqlSession
sqlSession.close();
}
}
注意点:常见错误
Type interface com.hmx.dao.UserDao is not known to the MapperRegistry
原因:Mapper.xml没有在核心配置文件中注册
解决:在mybatis的配置文件中给每个Mapper.xml配置mapper
<!--每一个Mapper.xml都需要在核心配置文件中注册-->
<mappers>
<mapper resource="com/hmx/dao/UserMapper.xml"/>
</mappers>
Could not find resource com/hmx/dao/UserMapper.xml
原因:资源导入失败,Maven导出资源问题
解决:在pom.xml中配置如下代码
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: 1 字节的 UTF-8 序列的字节 1 无效
原因:xml编码问题
解决:
1、在pom.xml中配置如下代码
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
若方法1没用,参考
2、把每个xml文件的文件头
改为:
实体类:User
接口类:UserMapper
public interface UserMapper {
?
//查询所有数据
List<User> getUserList();
//根据id查询数据
User selectById(int id);
//增加数据
int insertUser(User user);
//更新数据
int updateUser(User user);
//删除数据
int deleteUser(int id);
}
接口类的实现UserMapper.xml
测试
//查询所有数据
public static void selectAll(){
?
//第一步:获得SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//执行sal语句
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = userMapper.getUserList();
for (User user : userList) {
System.out.println(user);
}
//关闭SqlSession
sqlSession.close();
}
?
//根据id查询数据
public static void selectById(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
?
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.selectById(1);
System.out.println(user);
?
sqlSession.close();
}
?
//添加数据
public static void insertUser(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
?
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.insertUser(new User(9,"大黄","123"));
sqlSession.commit();
?
sqlSession.close();
}
?
//修改数据
public static void updateUser(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
?
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.updateUser(new User(4,"大黑子","333"));
sqlSession.commit();
?
sqlSession.close();
}
?
//删除数据
public static void deleteUser(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
?
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.deleteUser(9);
sqlSession.commit();
?
sqlSession.close();
}
Mybatis注解作用:
使用注解来映射简单语句会使代码显得更加简洁
但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让你本就复杂的 SQL 语句更加混乱不堪
因此,如果你需要做一些很复杂的操作,最好用 XML 来映射语句
mybatis注解本质
本质:反射机制
底层:动态代理模式
注意点:
注解写在接口类中的方法上
使用注解开发不需要写接口的实现类(XXXMapper.xml)文件,所以在配置文件中需要绑定XXXMapper.java
<mappers>
<mapper class="com.hmx.mapper.UserMapper"/>
</mappers>
@Param()注解
方法中只有一个参数,可加可不加,最好加,多个参数必须加
基本类型和String类型需要加上
和sql语句中引用的#{}相匹配
增删改查
public interface UserMapper {
?
//查询所有数据
configuration核心配置文件中包含了会深深影响 MyBatis 行为的设置和属性信息,可以配置如下配置:
properties(属性)
可以直接引入外部文件
<properties resource="db.properties"/>
#db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=root
如果db.properties中没有配置username和password,则可以可以在properties中增加一些属性配置
<properties resource="db.properties">
<property name="username" value="root"/>
<property name="password" value="root"/>
</properties>
如果两个配置文件和properties中存在同一字段,如:都含有username这个字段但是值不一样,优先使用外部配置文件
settings(设置)
一个配置完整的settings元素的示例如下:
<settings>
1、<!--全局地开启或关闭所有映射器配置文件中已配置的任何缓存,有效值true|false,默认true-->
<setting name="cacheEnabled" value="true"/>
2、<!--
延迟加载的全局开关。
当开启时,所有关联对象都会延迟加载。
特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。
有效值true|false,默认false
-->
<setting name="lazyLoadingEnabled" value="true"/>
3、<!--是否允许单个语句返回多结果集(需要数据库驱动支持),有效值true|false,默认true-->
<setting name="multipleResultSetsEnabled" value="true"/>
4、<!--
使用列标签代替列名
实际表现依赖于数据库驱动,具体可参考数据库驱动的相关文档,或通过对比测试来观察
有效值true|false,默认true
-->
<setting name="useColumnLabel" value="true"/>
5、<!--
允许 JDBC 支持自动生成主键,需要数据库驱动支持
如果设置为 true,将强制使用自动生成主键
尽管一些数据库驱动不支持此特性,但仍可正常工作(如 Derby)
有效值true|false,默认false
-->
<setting name="useGeneratedKeys" value="false"/>
6、<!--
指定 MyBatis 应如何自动映射列到字段或属性。
NONE 表示关闭自动映射
PARTIAL 只会自动映射没有定义嵌套结果映射的字段
FULL 会自动映射任何复杂的结果集(无论是否嵌套)
默认值为PARTIAL
-->
<setting name="autoMappingBehavior" value="PARTIAL"/>
7、<!--
指定发现自动映射目标未知列(或未知属性类型)的行为。
NONE: 不做任何反应
WARNING: 输出警告日志
FAILING: 映射失败 (抛出 SqlSessionException)
默认值为NONE
-->
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
8、<!--
配置默认的执行器
SIMPLE 就是普通的执行器
REUSE 执行器会重用预处理语句(PreparedStatement)
BATCH 执行器不仅重用语句还会执行批量更新
默认值为SIMPLE-->
<setting name="defaultExecutorType" value="SIMPLE"/>
9、<!--
设置超时时间,它决定数据库驱动等待数据库响应的秒数
有效值为任意正整数 默认未设置 (null)
-->
<setting name="defaultStatementTimeout" value="25"/>
10、<!--
为驱动的结果集获取数量(fetchSize)设置一个建议值,此参数只可以在查询设置中被覆盖。
有效值为任意正整数 默认未设置 (null)
-->
<setting name="defaultFetchSize" value="100"/>