上周学习了创建maven项目,使用的是mybatis框架该框架属于持久层,且是一个ORM框架。所谓的ORM就是一种为了解决面向对象与关系型数据库中的数据类型不匹配的奇数,它通过描述JAVA对象与数据库之间的映射关系,自动将java应用程序中的对象持久化到关系型数据库中的数据表中。
由于Mapper.xml文件中的映射路径出错(包名+类名),导致运行异常。所以整理一下配置文件及需要注意的细节。
一、所需要的的xml文件
pom.xml
mybatis-config.xml
mapper.xml
二、xml文件详细
1.pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>xyz.crud1024</groupId>
<artifactId>mybatis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
pom.xml文件中主要用于配置依赖,需要把maven依赖copy到<dependencies>标签体中。
相关依赖可以到https://mvnrepository.com/搜索到指定依赖。
也可以用一下格式自己编辑以mysql为例:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
2.mybatis-config.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" >
<configuration>
<!-- default指定默认的数据库环境为mysql'应用其中衣蛾envitonment元素的ID -->
<environments default="mysql">
<!-- 配置名为mysql该名字随意的环境 -->
<environment id="mysql">
<!-- 配置事务管理器,JDBC代表使用JDBC自带的事务提交与回滚 -->
<transactionManager type="JDBC"/>
<!-- 配置datasource数据源,使用mybatis内置的数据源 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?serverTimezone=UTCcharacterEncoding=utf8"/>
<property name="username" value="username"/>
<property name="password" value="password"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
2.properties属性
该属性主要作用就是引入外部的properties是文件,文件格式为xxx=xxx
实例:
<!-- 加载外部配置文件 -->
<properties resource="jdbc.properties"></properties>
3.settings属性
调整 settings 中的设置是非常关键的,它们会改变 MyBatis 的运行时行为。下表描述了设置中各项的意图、默认值等。
设置参数 | 描述 | 有效值 | 默认值 |
cacheEnabled | 该配置影响的所有映射器中配置的缓存的全局开关。 | true | false | true |
lazyLoadingEnabled | 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。 | true | false | false |
aggressiveLazyLoading | 当启用时,带有延迟加载属性的对象的加载与否完全取决于对任意延迟属性的调用;反之,每种属性将会按需加载。 | true | false | 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 |
defaultExecutorType | 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements);BATCH 执行器将重用语句并执行批量更新。 | SIMPLE REUSE BATCH | SIMPLE |
defaultStatementTimeout | 设置超时时间,它决定驱动等待数据库响应的秒数。 | Any positive integer | Not Set (null) |
safeRowBoundsEnabled | 允许在嵌套语句中使用行分界(RowBounds)。 | true | false | False |
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.XMLDynamicLanguageDriver |
callSettersOnNulls | 指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法,这对于有 Map.keySet() 依赖或 null 值初始化的时候是有用的。注意原始类型(int、boolean等)是不能设置成 null 的。 | 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 用来创建具有延迟加载能力的对象设置代理工具。 |
4.typeAliases别名
类型别名是为 Java 类型命名的一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。
<!-- 起别名 -->
<typeAliases>
<typeAlias alias="User" type="cn.mybatis.pojo.User"/>
</typeAliases>
Mybatis中已经定义好的别名:
5.mapper映射器
<mappers>
<mapper resource="usermapper.xml"/>
</mappers>
6.plugins插件
MyBatis中的插件,其实类似于拦截器的效果,可以实现在MyBatis的整个运行流程中的 某些指定位置进行拦截:
Executor:对执行器进行拦截,上图括号内是可以拦截的方法
ParameterHandler:参数处理时进行拦截
ResultSetHandler:处理结果集,封装Java对象时进行拦截
StatementHandler:编译statement时进行拦截3.
3.mapper.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" >
<mapper namespace="pojo.User">
<select id="afind" parameterType="int" resultType="pojo.User">
select * from users where uid = #{id}
</select>
</mapper>
以查询语句为例。
ORM需要javaBean对象,且需要接口中要定义好抽象方法,方法的参数类型也要注意。
user类:
package pojo;
public class User {
private int uid;
private String uname;
private int uage;
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(int uid, String uname, int uage) {
super();
this.uid = uid;
this.uname = uname;
this.uage = uage;
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public int getUage() {
return uage;
}
public void setUage(int uage) {
this.uage = uage;
}
@Override
public String toString() {
return "User [uid=" + uid + ", uname=" + uname + ", uage=" + uage + "]";
}
}
interface类:
package dao;
import java.util.List;
import pojo.User;
public interface UserDao {
//插入
public int insert(User user);
//更新
public int updata(User user);
//删除
public int delete(User user);
//查询单条数据
public User afind(int id);
//查询多条数据
public List<User> findAll();
//关闭流
public void close();
}
namespace="pojo.User"
指定ORM映射的对象地址,路径(包名+类名)
<select id="afind" parameterType="int" resultType="pojo.User">
id指的是interface中的抽象方法名称,parameterType指抽象方法中的形参类型,以及resultType指定的返回值类型及user对象。
具体详细配置:
1.1 查询select
标签属性
- id 唯一的名称,对应dao中mapper的接口名称
- paramterType 定义传入的参数类型
- resultType 返回数据类型对应实体类
- resultMap 外部 resultMap 的命名引用。结果集的映射是 MyBatis 最强大的特性,对其有一个很好的理解的话,许多复杂映射的情形都能迎刃而解。使用 resultMap 或 resultType,但不能同时使用
- flushCache 将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:false
- useCache 将其设置为 true,将会导致本条语句的结果被二级缓存,默认值:对 select 元素为 true
- timeout 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)
- fetchSize 这是尝试影响驱动程序每次批量返回的结果行数和这个设置值相等。默认值为 unset(依赖驱动)。
- statementType STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
- resultSetType FORWARD_ONLY,SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE 中的一个,默认值为 unset (依赖驱动)。
- databaseId 如果配置了 databaseIdProvider,MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。
- resultOrdered 这个设置仅针对嵌套结果 select 语句适用:如果为true,就是假设包含了嵌套结果集或是分组了,这样的话当返回一个主结果行的时候,就不会发生有对前面结果集的引用的情况。这就使得在获取嵌套的结果集的时候不至导致内存不够用。默认值:false。
- resultSets 这个设置仅对多结果集的情况适用,它将列出语句执行后返回的结果集并每个结果集给一个名称,名称是逗号分隔的。
1 2 3 4 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
1.2 增删改
标签属性
- id 唯一的名称,对应dao中mapper的接口名称
- parameterType 将要传入语句的参数的完全限定类名或别名。这个属性是可选的,因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset。
- flushCache 将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:true(对应插入、更新和删除语句)。
- timeout 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)。
- statementType STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
- useGeneratedKeys(仅对 insert 和 update 有用)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server这样的关系数据库管理系统的自动递增字段, oracle使用序列是不支持的,通过selectKey可以返回主键),默认值:false。
- keyProperty (仅对 insert 和 update 有用)唯一标记一个属性,MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey子元素设置它的键值,默认:unset。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
- keyColumn(仅对 insert 和 update 有用)通过生成的键值设置表中的列名,这个设置仅在某些数据库(像PostgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
- databaseId 如果配置了 databaseIdProvider,MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。
1 2 3 4 5 6 7 8 9 10 |
|
1.3 其他基础标签
1.3.1 sql 标签
定义一些常用的sql语句片段
1 2 3 |
|
1.3.2 include 标签
引用其他的常量,通常和sql一起使用
1 2 3 4 |
|
1.3.3 if 标签
基本都是用来判断值是否为空,注意Integer的判断,mybatis会默认把0变成 ‘'
1 2 3 4 5 |
|
1.3.4 别名
经常使用的类型可以定义别名,方便使用,mybatis也注册了很多别名方便我们使用,详情见底部附录
1 2 3 |
|
2. collection与association标签
collection与association的属性一样,都是用于resultMap返回关联映射使用,collection关联的是集合,而association是关联单个对象
标签属性
- property resultMap返回实体类中字段和result标签中的property一样
- column 数据库的列名或者列标签别名,是关联查询往下一个语句传送值。注意: 在处理组合键时,您可以使用column=“{prop1=col1,prop2=col2}”这样的语法,设置多个列名传入到嵌套查询语句。这就会把prop1和prop2设置到目标嵌套选择语句的参数对象中。
- javaType 一般为ArrayList或是java.util.List
- ofType java的实体类,对应数据库表的列名称,即关联查询select对应返回的类
- select 执行一个其他映射的sql语句返回一个java实体类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
1 2 3 4 |
|
3. resultMap标签
resultMap属性
- id 唯一标识
- type 返回类型
- extends 继承别的resultMap,可选
关联其他标签
- id 设置主键使用,使用此标签配置映射关系(可能不止一个)
- result 一般属性的配置映射关系,一般不止一个
- association 关联一个对象使用
- collection 关联一个集合使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
4. foreach标签
foreach属性
- collection 循环的集合。传的是集合为list,数组为array, 如果是map为java.util.HashMap
- item 循环的key
- index 循环的下表顺序
- open 循环的开头
- close 循环结束
- separator 循环的分隔符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
5. where标签
where用来去掉多条件查询时,开头多余的and
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
6. set标签
set是mybatis提供的一个智能标记,当在update语句中使用if标签时,如果前面的if没有执行,则或导致逗号多余错误。使用set标签可以将动态的配置SET 关键字,和剔除追加到条件末尾的任何不相关的逗号。
没有使用if标签时,如果有一个参数为null,都会导致错误,如下示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
7. trim标签
trim标记是一个格式化的标记,可以完成set或者是where标记的功能
标签属性
- prefix、suffix 表示再trim标签包裹部分的前面或后面添加内容(注意:是没有prefixOverrides,suffixOverrides的情况下)
- prefixOverrides,suffixOverrides 表示覆盖内容,如果只有这两个属性表示删除内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
8. choose、when、otherwise标签
有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。MyBatis提供了choose 元素,按顺序判断when中的条件出否成立,如果有一个成立,则choose结束。当choose中所有when的条件都不满则时,则执行 otherwise中的sql。类似于Java 的switch 语句,choose为switch,when为case,otherwise则为default。if是与(and)的关系,而choose是或(or)的关系
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
附Mybatis已经注册好的别名表
别名 | 映射类型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
map | Map |
hashmap | HashMap |
list | list |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
以上内容都是查资料总结整理的,方便日后巩固学习。