1. MyBatis概述
1.1. MyBatis是什么
MyBatis是一个持久层(DAO)框架,本质上是JDBC的一次封装。
1.2. MyBatis的作用
MyBatis是一个持久层框架,那么作用当然就是操作数据库(增删改查CRUD)。
1.3. 为什么需要学习MyBatis
MyBatis的理念:让开发者编写10%的代码(相对于原生JDBC)就可以实现数据库的操作。解决方案:持久层(DAO)的零实现,所谓的零实现,就是不用写实现类代码,直接使用接口就可以操作数据库。
MyBatis的定义,提高开发的效率、程序的健壮性、可扩展性、优雅性!!!真的写很少代码就可以增删改查。在同等实现效果下,显著减少技术代码的编写,从而可以让开发人员关注业务逻辑代码的编写。
1.4. MyBatis的作用
MyBatis框架能够让我们以最少的代码实现操作数据库。从而提高开发的效率!!!
--如何将代码减少呢?
1.5. MyBatis配置流程图
Resources:资源类,用于读取总配置文件。
SqlSessionFactoryBuilder:会话工厂构造类,通过读取的总配置文件构建会话工厂。
SqlSessionFactory:会话工厂。
SqlSession:会话操作对象,用于生成对应模块接口的代理对象(0实现)。
1.6. MyBatis的个人理解
MyBatis是一个持久层的框架,所谓的框架,无非就是一群牛逼的人封装了某一个java原生功能,而MyBatis就是对原生JDBC的一次封装,相对于我们自己的封装,MyBatis会更加的强大、健壮、高效,MyBatis的底层实现就是JDBC,我们封装过功能都清楚,封装无非就是将重复一样的代码在一个方法中写死,而那些随着业务场景不同的代码,则通过形参进行控制,封装过后,我们只需将变化的形参传递给封装的方法,那么我们就可以得到既定的返回值,封装把我们从编写繁琐无味的重复性代码中解放出来,从而使得我们可以更加关注业务逻辑代码的编写,进而降低开发成本,提高开发效率。所以学习MyBatis框架,首先学习如何使用Mybatis封装好的方法(功能),清楚MyBatis在开发中的使用流程,在熟练使用MyBatis进行业务开发之后,我们可以尝试的去学习Mybatis的源码,使得我们能更加灵活使用MyBatis进行开发。
MyBatis在项目中的使用流程:
[2] xxxMapper.xml配置文件中编写模块DAO层接口中的抽象方法的sql语句。每一个方法的实际sql类型对应一个标签(select、insert、update、delete),这样做只是为了将代码语义化,方便后期代码维护。
2. 入门示例
2.1. 配置流程说明
--获得数据库连接
--需求:插入数据到数据库
PS:数据库sql脚本
/* Navicat Premium Data Transfer Source Server : root Source Server Type : MySQL Source Server Version : 50562 Source Host : localhost:3306 Source Schema : users Target Server Type : MySQL Target Server Version : 50562 File Encoding : 65001 Date: 12/12/2019 16:25:24*/ SET NAMES utf8mb4;SET FOREIGN_KEY_CHECKS = 0; -- ------------------------------ Table structure for tb_user-- ----------------------------DROP TABLE IF EXISTS `tb_user`;CREATE TABLE `tb_user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '姓名', `age` int(11) NULL DEFAULT NULL COMMENT '年龄', `email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱', `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '密码', PRIMARY KEY (`id`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 1188715086030696464 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; SET FOREIGN_KEY_CHECKS = 1;
2.2. 配置步骤
2.2.1. 下载MyBatis框架
2.2.2. 创建一个普通java项目并导入相关jar包
2.2.3. 创建主配置文件 mybatis-config.xml
2.2.3.1.1. 具体配置参考MyBatis的官方文档即可
<?xml version="1.0" encoding="UTF-8" ?><!-- dtd约束 --><!DOCTYPE configuration PUBLIC "-//MyBatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><!-- 根元素: 用于配置MyBatis --><configuration> <!-- 配置MyBatis的运行环境 ,可以配置多个环境,但是一次只能使用一个 default属性 : 当前使用的环境 ,使用下面环境的id 即可 --> <environments default="dev_mysql"> <!-- 环境配置 id 属性,唯一标识当前环境 --> <environment id="dev_mysql"> <!-- 配置MyBatis事务管理器 type属性 : 事物类型 JDBC 使用事务(正常提交commit,异常回滚事务 rollback) 默认 MANAGED : 不使用事务 --> <transactionManager type="JDBC"/> <!-- 配置MyBatis的数据源 type : 配置连接池 POOLED :MyBatis内置的一个连接池(默认) 后期都交给spring管理了,配置 dbcp连接池,阿里巴巴的 druid连接池 --> <dataSource type="POOLED"> <!-- 连接数据库的操作 --> <!-- 数据库驱动 --> <property name="driver" value="com.mysql.jdbc.Driver"/> <!-- 连接数据库的url --> <property name="url" value="jdbc:mysql://localhost:3306/users"/> <!-- 连接数据库账号 --> <property name="username" value="root"/> <!-- 连接数据库密码 --> <property name="password" value="root"/> </dataSource> </environment> </environments> <!-- 配置映射文件 --> <mappers> <!-- <mapper resource="org/cjw/mapper/UserMapper.xml"/>--> <!--指定一个配置文件--> <!--<package name="org.cjw.mapper"/>--> <!-- 指定一个包,包含多个配置文件或者配置类,推荐 --> <mapper class="org.cjw.mapper.UserMapper" /> <!-- 指定一个配置类 --> </mappers></configuration>
MyBatisUtil2.2.4. 创建MyBatisUtil工具类package org.cjw.utils;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 java.io.IOException;import java.io.InputStream;public class MyBatisUtil { private MyBatisUtil() {} private static SqlSessionFactory sqlSessionFactory; static { try(InputStream in = Resources.getResourceAsStream("mybatis-config.xml")) { sqlSessionFactory = new SqlSessionFactoryBuilder().build(in); } catch (IOException e) { e.printStackTrace(); } } public static SqlSession openSession() { return sqlSessionFactory.openSession(); }}
2.2.5. 创建数据库表对应的实体类
package org.cjw.pojo;public class User { private Long id; private String name; private Integer age; private String email; private String password; public User() { } public User(Long id, String name, Integer age, String email, String password) { this.id = id; this.name = name; this.age = age; this.email = email; this.password = password; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; }}
2.2.6. 创建一个操作接口
package org.cjw.mapper;import org.cjw.pojo.User;public interface UserMapper { /* 使用MyBatis的动态代理开发编写代码遵循四个原则 1.映射文件的namespace命名空间的值必须是对应接口的全限定名。 2.映射文件的对应功能 id值必须等于映射接口中方法的名称。 3.映射文件的参数类型必须和接口中方法的参数类型一致。 4.映射文件查询的返回结果类型必须和接口的方法的返回数据类型一致, DML操作返回的受影响的行数,除外。 */ void insert(User user);}
2.2.7. 创建表对应的映射文件 :UserMapper.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"><!-- 配置映射namespace : 命名空间(通俗说法: 给当前映射文件的唯一标识:起一个唯一的名字) --><mapper namespace="org.cjw.mapper.UserMapper"> <!-- 新增操作 id: 当前功能的唯一标识,和接口方法同名 parameterType : 参数的类型 useGeneratedKeys:是否返回数据库生成的主键 true是/false否 keyProperty : 数据库主键对应java的pojo对象的属性 keyColumn : 数据表的主键列名 --> <insert id="insert" parameterType="org.cjw.pojo.User" keyProperty="id" keyColumn="id"> insert into tb_user (name, age, email, password) values (#{name}, #{age}, #{email}, #{password}); </insert></mapper>
2.2.8. 创建测试类准备测试
@Testpublic void testInsert() { SqlSession session = MyBatisUtil.openSession(); try { UserMapper userMapper = session.getMapper(UserMapper.class); User user = new User(); user.setName("李四"); user.setAge(14); user.setEmail("lisi@qq.com"); user.setPassword("lisi"); userMapper.insert(user); session.commit(); } catch (Exception e) { e.printStackTrace(); session.rollback(); } finally { session.close(); }}
3. log4j日志框架的配置
3.1. 说明
log4j是一个日志输出框架,就是用于输出日志的。MyBatis的日志输出是通过log4J输出的。主流框架大部分都是log4j输出的。Spring框架也可以通过log4j输出日志!!
问题:既然log4j功能类似System.out.println(),为什么使用log4j而不直接使用System.out.println()?
1.通过级别输出日志(调试、信息、警告、错误、致命异常)。
2.可以指定输出到控制台,以及输出到文件。
3.可以设置输出的日志格式。
所以学习LOG4J.需要学会自定义配置LOG4J的输出格式以及输出等级。
3.2. 下载路径
Log4j的下载地址
- http://logging.apache.org/log4j/1.2/
3.3. 配置步骤
3.3.1. 第一步:导入log4j-1.2.17.jar的包
3.3.2. 第二步:在src下创建一个log4j.properties文件
# Global logging configurationlog4j.rootLogger=debug, stdoutlog4j.logger.org.cjw.mapper=TRACE // 需要修改为自己的包名# Console output...log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
3.4. 运行效果
4. MyBatis完成CRUD操作
4.1. 单行查询
4.1.1. 映射文件
<select id="selectUserById" resultType="org.cjw.pojo.User"> select * from tb_user where id = #{id}</select>
4.1.2. 测试方法
@Testpublic void testSelectUserById() { SqlSession session = MyBatisUtil.openSession(); UserMapper userMapper = session.getMapper(UserMapper.class); User user = userMapper.selectUserById(1); System.out.println(user.getName());}
4.1.2. 测试结果
4.2. 多行查询
4.2.1. 映射文件
<!-- 多行查询 resultType : 无论是多行查询还是单行查询,返回的结果类型都是对应的JavaBean的类型--><select id="selectAll" resultType="org.cjw.pojo.User"> select * from tb_user</select>
4.2.2. 测试方法
@Testpublic void testSelectAll() { SqlSession session = MyBatisUtil.openSession(); UserMapper userMapper = session.getMapper(UserMapper.class); List<User> users = userMapper.selectAll(); for (User user : users) { System.out.println(user.getName()); }}
4.2.3. 测试结果
4.3. 删除操作
4.3.1. 映射文件
<delete id="deleteUserById"> delete from tb_user where id = #{id}</delete>
4.3.2. 测试方法
@Testpublic void testDeleteUserById() { SqlSession session = MyBatisUtil.openSession(); try { UserMapper userMapper = session.getMapper(UserMapper.class); userMapper.deleteUserById(1); session.commit(); } catch (Exception e) { e.printStackTrace(); session.rollback(); } finally { session.close(); }}
4.3.3. 测试结果
4.4. 修改操作
4.4.1. 映射文件
<update id="updateUserById" parameterType="org.cjw.pojo.User"> update tb_user set name = #{name}, age = #{age}, email = #{email}, password = #{password} where id = #{id}</update>
4.4.2. 测试方法
@Testpublic void testUpdateUserById() { SqlSession session = MyBatisUtil.openSession(); try { UserMapper userMapper = session.getMapper(UserMapper.class); User user = new User(); user.setId(2L); user.setName("zhangsan"); user.setEmail("zhangsan@126.com"); user.setPassword("zhangsan123123123"); userMapper.updateUserById(user); session.commit(); } catch (Exception e) { e.printStackTrace(); session.rollback(); } finally { session.close(); }}
4.4.2. 测试结果
5. ResultMap 手动映射
MyBatis的查询结果集都是自动映射封装的,单行查询将数据库一条数据封装成对应的Java对象。多行查询,先将每一行封装成对象,再将每个对象添加到集合中,最后返回一个List集合对象。但是:必须保证查询结果集和pojo对象的属性名相同,否则无法自动封装。
<select id="selectUserById" resultMap="user_map"> select id u_id, name u_name, age u_age, email u_email, password u_password from tb_user where id = #{id}</select><resultMap id="user_map" type="User"> <id property="id" column="u_id" /> <result property="name" column="u_name"/> <result property="age" column="u_age"/> <result property="email" column="u_email"/> <result property="password" column="u_password"/></resultMap>
6. 主配置文件说明与细节配置
<environments>:环境集标签,就是用于配置数据库的连接信息的。
<environment>:用于配置具体环境参数。
<transactionManager>:配置使用的事务类型,JDBC。
<dataSource>:配置数据源的参数,POOLED。
<property>:配置属性
<mappers>: 配置映射文件信息的
<mapper class|resource>: 配置具体指定的mapper文件
class: 配置使用注解时指定有注解的映射接口
resource: 指定映射文件
<package name>: 配置配置文件、配置类所在的包,推荐
<properties>:MyBatis读取classpath路径下配置文件,一般用于读取db.properties。
<typeAliases>:用于配置别名。
<typeAliase type alias>
type:指定取别名的全限定名
alias:别名
<package name>
name:指定取别名的包
<typeHandlers>:用于配置自定义类型处理器。
<settings>:配置MyBatis的默认设置的(开启二级缓存、驼峰命名自动映射)。
总配置文件的标签顺序
<!ELEMENT configuration (properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)> |
1.properties
2.settings
3.typeAliases
4.typeHandlers
5.objectFactory
6.objectWrapperFactory
7.reflectorFactory
8.plugins
9.environments
10.databaseIdProvider
11.mappers
DTD
6.1. 别名typeAliases标签
MyBatis框架提供了两种别名机制,一种是自定义别名,一种是内置别名。
6.1.1. 自定义别名
<?xml version="1.0" encoding="UTF-8" ?><!-- dtd约束 --><!DOCTYPE configuration PUBLIC "-//MyBatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><!-- 根元素: 用于配置MyBatis --><configuration> <!-- 别名配置 --> <typeAliases> <!-- <typeAlias type="" alias=""/> 设置单个类型的别名 type: 要设置别名的数据类型(全限定名) alias : 取的别名,一般都使用类的简单名称 <package name="" /> 设置一个包的别名,推荐 --> <typeAlias type="org.cjw.pojo.User" alias="User" /> <package name="org.cjw.pojo"/> </typeAliases> <!-- 配置MyBatis的运行环境 ,可以配置多个环境,但是一次只能使用一个 default属性 : 当前使用的环境 ,使用下面环境的id 即可 --> <environments default="dev_mysql"> <!-- 环境配置 id 属性,唯一标识当前环境 --> <environment id="dev_mysql"> <!-- 配置MyBatis事务管理器 type属性 : 事物类型 JDBC 使用事务(正常提交commit,异常回滚事务 rollback) 默认 MANAGED : 不使用事务 --> <transactionManager type="JDBC"/> <!-- 配置MyBatis的数据源 type : 配置连接池 POOLED :MyBatis内置的一个连接池(默认) 后期都交给spring管理了,配置 dbcp连接池,阿里巴巴的 druid连接池 --> <dataSource type="POOLED"> <!-- 连接数据库的操作 --> <!-- 数据库驱动 --> <property name="driver" value="com.mysql.jdbc.Driver"/> <!-- 连接数据库的url --> <property name="url" value="jdbc:mysql://localhost:3306/users"/> <!-- 连接数据库账号 --> <property name="username" value="root"/> <!-- 连接数据库密码 --> <property name="password" value="root"/> </dataSource> </environment> </environments> <!-- 配置映射文件 --> <mappers> <!-- <mapper resource="org/cjw/mapper/UserMapper.xml"/>--> <!--指定一个配置文件--> <!--<package name="org.cjw.mapper"/>--> <!-- 指定一个包,包含多个配置文件或者配置类,推荐 --> <mapper class="org.cjw.mapper.UserMapper"/> <!-- 指定一个配置类 --> </mappers></configuration>
<?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 : 命名空间(通俗说法: 给当前映射文件的唯一标识:起一个唯一的名字) --><mapper namespace="org.cjw.mapper.UserMapper"> <!-- 新增操作 id: 当前功能的唯一标识,和接口方法同名 parameterType : 参数的类型 useGeneratedKeys:是否返回数据库生成的主键 true是/false否 keyProperty : 数据库主键对应java的pojo对象的属性 keyColumn : 数据表的主键列名 --> <insert id="insert" parameterType="User" keyProperty="id" keyColumn="id"> insert into tb_user (name, age, email, password) values (#{name}, #{age}, #{email}, #{password}); </insert> <select id="selectUserById" resultType="User"> select * from tb_user where id = #{id} </select> <!-- 多行查询 resultType : 无论是多行查询还是单行查询,返回的结果类型都是对应的JavaBean的类型 --> <select id="selectAll" resultType="User"> select * from tb_user </select> <delete id="deleteUserById"> delete from tb_user where id = #{id} </delete> <update id="updateUserById" parameterType="User"> update tb_user set name = #{name}, age = #{age}, email = #{email}, password = #{password} where id = #{id} </update></mapper>
6.1.2. 内置别名
别名 | 映射的类型 |
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | java.lang.String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | java.util.Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
map | java.util.Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
6.2. properties 读取配置文件
6.2.1. 在classpath下面创建一个db.properties数据库连接配置文件
jdbc.driverClassName=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/users?characterEncoding=utf-8jdbc.username=rootjdbc.password=root
6.2.2. 在MyBatis-config.xml主配置文件中配置标签读取配置文件
<!-- 读取classpath下面的 数据库配置文件、 读取以后在下面连接数据库的配置中就可以使用 ${配置文件key}获取对应的数据库连接相关信息--><properties resource="db.properties" />
6.2.3. 连接数据库的配置修改为 ${key}的方式
<dataSource type="POOLED"> <!-- 连接数据库的操作 --> <!-- 数据库驱动 --> <property name="driver" value="${jdbc.driverClassName}"/> <!-- 连接数据库的url --> <property name="url" value="${jdbc.url}"/> <!-- 连接数据库账号 --> <property name="username" value="${jdbc.username}"/> <!-- 连接数据库密码 --> <property name="password" value="${jdbc.password}"/></dataSource>
6.3. settings标签
MyBatis默认设置了很多默认配置。有时候,我们需求与默认的配置的参数不一样,我们就需要修改这些默认配置的参数。
设置参数 | 描述 | 有效值 | 默认值 |
cacheEnabled | 该配置影响的所有映射器中配置的缓存的全局开关。 | true | false | TRUE |
lazyLoadingEnabled | 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。 | true | false | FALSE |
aggressiveLazyLoading | 当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载(参考lazyLoadTriggerMethods). | true | false | false (true in ≤3.4.1) |
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, FAILING | NONE |
defaultExecutorType | 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements); BATCH 执行器将重用语句并执行批量更新。 | SIMPLE REUSE BATCH | SIMPLE |
defaultStatementTimeout | 设置超时时间,它决定驱动等待数据库响应的秒数。 | 任意正整数 | Not Set (null) |
defaultFetchSize | 为驱动的结果集获取数量(fetchSize)设置一个提示值。此参数只可以在查询设置中被覆盖。 | 任意正整数 | Not Set (null) |
safeRowBoundsEnabled | 允许在嵌套语句中使用分页(RowBounds)。 If allow, set the false. | true | false | FALSE |
safeResultHandlerEnabled | 允许在嵌套语句中使用分页(ResultHandler)。 If allow, set the false. | true | false | TRUE |
mapUnderscoreToCamelCase | 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。 | true | false | FALSE |
localCacheScope | MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。 默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据。 | SESSION | STATEMENT | SESSION |
jdbcTypeForNull | 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。 | JdbcType enumeration. Most common are: NULL, VARCHAR and OTHER | OTHER |
lazyLoadTriggerMethods | 指定哪个对象的方法触发一次延迟加载。 | A method name list separated by commas | equals,clone,hashCode,toString |
defaultScriptingLanguage | 指定动态 SQL 生成的默认语言。 | A type alias or fully qualified class name. | org.apache.ibatis.scripting.xmltags.XMLLanguageDriver |
callSettersOnNulls | 指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法,这对于有 Map.keySet() 依赖或 null 值初始化的时候是有用的。注意基本类型(int、boolean等)是不能设置成 null 的。 | true | false | FALSE |
returnInstanceForEmptyRow | 当返回行的所有列都是空时,MyBatis默认返回null。 当开启这个设置时,MyBatis会返回一个空实例。 请注意,它也适用于嵌套的结果集 (i.e. collectioin and association)。(从3.4.2开始) | true | false | FALSE |
logPrefix | 指定 MyBatis 增加到日志名称的前缀。 | Any String | Not set |
logImpl | 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 | SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING | Not set |
proxyFactory | 指定 MyBatis 创建具有延迟加载能力的对象所用到的代理工具。 | CGLIB | JAVASSIST | JAVASSIST (MyBatis 3.3 or above) |
vfsImpl | 指定VFS的实现 | 自定义VFS的实现的类全限定名,以逗号分隔。 | Not set |
useActualParamName | 允许使用方法签名中的名称作为语句参数名称。 为了使用该特性,你的工程必须采用Java 8编译,并且加上-parameters选项。(从3.4.1开始) | true | false | TRUE |
configurationFactory | Specifies the class that provides an instance of Configuration. The returned Configuration instance is used to load lazy properties of deserialized objects. This class must have a method with a signature static Configuration getConfiguration(). (Since: 3.2.3) | A type alias or fully qualified class name. | Not set |
<settings> <setting name="mapUnderscoreToCamelCase" value="true"/></settings>
7. MyBatis的注解开发
MyBatis的映射配置除了使用xml配置以外,还支持注解配置sql语句。
SQL语句的注解标注对应的功能方法上即可,直接连XxxMapper.xml映射文件都可以省略了。本身注解开发就是Java配置的一种趋势,学习SpringBoot时候,会发现全部用纯注解配置。
MyBatis提供了下面注解进行映射文件配置
@Select 查询数据注解@Insert 插入数据注解@Delete 删除数据注解@Update 修改数据注解@Options 选项配置@Results 手动映射配置@Result @Results中的具体的某一列的映射信息配置
7.1. 案例代码
package org.cjw.mapper;import org.apache.ibatis.annotations.*;import org.cjw.pojo.User;import java.util.List;public interface UserMapper { /* 使用MyBatis的动态代理开发编写代码遵循四个原则 1.映射文件的namespace命名空间的值必须是对应接口的全限定名。 2.映射文件的对应功能 id值必须等于映射接口中方法的名称。 3.映射文件的参数类型必须和接口中方法的参数类型一致。 4.映射文件查询的返回结果类型必须和接口的方法的返回数据类型一致, DML操作返回的受影响的行数,除外。 */ @Insert("insert into tb_user (name, age, email, password) values (#{name}, #{age}, #{email}, #{password})") void insert(User user); @Select("select id u_id, name u_name, age u_age, email u_email, password u_password from tb_user where id = #{id}") @Results({ @Result(id = true, property = "id", column = "u_id"), @Result(property = "age", column = "u_age"), @Result(property = "name", column = "u_name"), @Result(property = "email", column = "u_email"), @Result(property = "password", column = "u_password") }) User selectUserById(Integer id); @Select("select * from tb_user") List<User> selectAll(); @Delete("delete from tb_user where id = #{id}") void deleteUserById(Integer id); @Update("update tb_user set age = #{age}, name = #{name}, email = #{email}, password = #{password} where id = #{id}") void updateUserById(User user);}
7.2. 注解映射的配置
<mappers> <!-- <mapper resource="org/cjw/mapper/UserMapper.xml"/>--> <!--指定一个配置文件--> <!--<package name="org.cjw.mapper"/>--> <!-- 指定一个包,包含多个配置文件或者配置类,推荐 --> <mapper class="org.cjw.mapper.UserMapper"/> <!-- 指定一个配置类 --></mappers>
8. 方法多参数传递使用-@Param注解
MyBatis默认情况下是不支持传入多个参数的,只能传入一个参数。
案例代码
@Select("select * from tb_user where name = #{name} and password = #{password}")User login(User user);@Select("select * from tb_user where name = #{name} and password = #{password}")User login2(Map<String, Object> map);@Select("select * from tb_user where name = #{name} and password = #{password}")User login3(@Param("name") String name, @Param("password") String password);
测试代码
@Testpublic void testLogin() { SqlSession session = MyBatisUtil.openSession(); UserMapper userMapper = session.getMapper(UserMapper.class); User user = new User(); user.setName("zhangsan"); user.setPassword("zhangsan123123"); User loginUser = userMapper.login(user); System.out.println(loginUser.getName());}@Testpublic void testLogin2() { SqlSession session = MyBatisUtil.openSession(); UserMapper userMapper = session.getMapper(UserMapper.class); Map<String, Object> map = new HashMap<String, Object>(); map.put("name", "zhangsan"); map.put("password", "zhangsan123123"); User loginUser = userMapper.login2(map); System.out.println(loginUser.getName());}@Testpublic void testLogin3() { SqlSession session = MyBatisUtil.openSession(); UserMapper userMapper = session.getMapper(UserMapper.class); User loginUser = userMapper.login3("zhangsan", "zhangsan123123"); System.out.println(loginUser.getName());}
9. #{}与${}的区别
#{}基于JDBC的PreparedStatement类,SQL语句参数使用?占位符,在运行阶段动态设置参数,但是?不能作为表名。预编译语句对象的SQL语句只能操作DML和DQL语句,不能操作DDL语句。
1.#{}表示设置预编译的参数,就是?的参数,所以如果要不固定的表名不能使用#{},只能使用${}
2.${}直接把值输出来,直接把参数拼接到SQL语句中.而#{}是使用?来代替.所以${}是不安全的。
3.${}只能获得参数池的值,而#{}可以获得方法的参数值,也可以获得参数池的值,如果使用${}获得参数的值,这个参数必须要加上@Param。如果非必要情况,不要使用${}。
9.1. 删除案例代码
import org.apache.ibatis.annotations.Param; public interface UserMapper { /** * 动态删除数据库中指定表名 * @param tableName 表名 * @return */ int dropTable(@Param("tableName")String tableName);}
映射文件:
<?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 : 命名空间,通俗讲,每个映射文件唯一的标识名称 --><mapper namespace="org.cjws.mybatis.mapper.UserMapper"> <!-- 使用#{} 不能使用在表名操作 --> <delete id="dropTable" parameterType="String"> <!-- drop table #{tableName} --> drop table ${tableName} </delete></mapper>
9.2. 打印效果
9.2.1. 使用 #{}