MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。——From Baidu encyclopedia
Mybatis官方中文文档:https://mybatis.org/mybatis-3/zh/index.html
Maven仓库:https://mvnrepository.com/artifact/org.mybatis/mybatis
A:数据持久化,即将程序的数据在持久状态和瞬时状态转化的过程。
A:完成持久化工作的代码块,层的界限是十分明显的。
A:
创建父项目
导入依赖
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.13.1version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.6version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.22version>
dependency>
创建子项目
在resources中创建Mybatis配置文件,文件名一般默认为mybatis-config.xml
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/computer03?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="niushijian"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/ola/dao/AuthorMapper.xml"/>
mappers>
configuration>
编写工具类MybatisUtils
package com.ola.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;
/**
* ClassName:MybatisUtils Package:com.ola.utils
*
* @author morningj
* @date 2021/1/10 15:39
*/
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
编写代码
实体类
package com.ola.pojo;
/**
* ClassName:Author Package:com.ola.pojo
*
* @author morningj
* @date 2021/1/10 15:50
*/
public class Author {
private String AuthorID;
private String Name;
public Author(String authorID, String name) {
AuthorID = authorID;
Name = name;
}
public Author() {
}
@Override
public String toString() {
return "Author{" + "AuthorID='" + AuthorID + '\'' + ", Name='" + Name + '\'' + '}';
}
public String getAuthorID() {
return AuthorID;
}
public void setAuthorID(String authorID) {
AuthorID = authorID;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
}
Dao接口
package com.ola.dao;
import com.ola.pojo.Author;
import java.util.List;
/**
* ClassName:AuthorDao Package:com.ola.dao
*
* @author morningj
* @date 2021/1/10 15:52
*/
public interface AuthorDao {
List<Author> getAuthorList();
}
AuthorMapper.xml(即原来的Dao接口实现类)
<mapper namespace="com.ola.dao.AuthorDao">
<select id="getAuthorList" resultType="com.ola.pojo.Author">
select *
from computer03.Name
select>
mapper>
命名空间的作用有两个,一个是利用更长的全限定名来将不同的语句隔离开来,同时也实现了你上面见到的接口绑定。就算你觉得暂时用不到接口绑定,你也应该遵循这里的规定,以防哪天你改变了主意。 长远来看,只要将命名空间置于合适的 Java 包命名空间之中,你的代码会变得更加整洁,也有利于你更方便地使用 MyBatis。
为了减少输入量,MyBatis 对所有具有名称的配置元素(包括语句,结果映射,缓存等)使用了如下的命名解析规则。
测试
package com.ola.dao;
import com.ola.pojo.Author;
import com.ola.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
/**
* ClassName:AuthorDaoTest Package:com.ola.dao
*
* @author morningj
* @date 2021/1/10 16:08
*/
public class AuthorDaoTest {
@Test
public void test() {
// 获取session对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
// 方式一
AuthorDao mapper = sqlSession.getMapper(AuthorDao.class);
List<Author> authorList = mapper.getAuthorList();
// 方式二(不推荐使用)
// List authorsList = sqlSession.selectList("com.ola.dao.AuthorDao.getAuthorList");
// for (Author author : authorsList) {
// System.out.println(author);
// }
for (Author author : authorList) {
System.out.println(author);
}
sqlSession.close();
}
}
错误使用会导致非常严重的并发问题!
INSERT:注意增删改需要提交事务,才能完成增删改操作!!!
<insert id="addAuthor" parameterType="com.ola.pojo.Author">
insert into computer03.Name(AuthorID, Name)
values (#{AuthorID}, #{Name});
insert>
@Test
public void addAuthor() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
AuthorMapper mapper = sqlSession.getMapper(AuthorMapper.class);
mapper.addAuthor(new Author("12345678-1", "olarian"));
sqlSession.commit();
sqlSession.close();
}
UPDATE:注意增删改需要提交事务,才能完成增删改操作!!!
<update id="updateAuthor" parameterType="com.ola.pojo.Author">
update computer03.Name
set AuthorID =#{AuthorID},
Name=#{Name}
where AuthorID = #{AuthorID};
update>
@Test
public void updateAuthor() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
AuthorMapper mapper = sqlSession.getMapper(AuthorMapper.class);
mapper.updateAuthor(new Author("12345678-1", "ola"));
sqlSession.commit();
sqlSession.close();
}
DELETE:注意增删改需要提交事务,才能完成增删改操作!!!
<delete id="deleteAuthor" parameterType="String">
delete
from computer03.Name
where AuthorID = #{id};
delete>
@Test
public void deleteAuthor() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
AuthorMapper mapper = sqlSession.getMapper(AuthorMapper.class);
mapper.deleteAuthor("12345678-1");
sqlSession.commit();
sqlSession.close();
}
官方文档:https://mybatis.org/mybatis-3/zh/configuration.html
properties(属性):这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置.【db.properties】
优先级:外部配置文件>内部属性引入
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/computer03?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=niushijian
在核心配置文件中引入:
<properties resource="db.properties"/>
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
environment>
typeAliases(类型别名)
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:
<select id="getAuthorList" resultType="com.ola.pojo.Author">
select *
from computer03.Name
select>
<select id="getAuthorById" resultType="com.ola.pojo.Author" parameterType="String">
select *
from computer03.Name
where AuthorID = #{id};
select>
<insert id="addAuthor" parameterType="com.ola.pojo.Author">
insert into computer03.Name(AuthorID, Name)
values (#{AuthorID}, #{Name});
insert>
<update id="updateAuthor" parameterType="com.ola.pojo.Author">
update computer03.Name
set AuthorID =#{AuthorID},
Name=#{Name}
where AuthorID = #{AuthorID};
update>
<delete id="deleteAuthor" parameterType="String">
delete
from computer03.Name
where AuthorID = #{id};
delete>
这里的parameterType和resultType都需要完全限定名,这就产生了冗余,为解决这个问题,使用typeAliases!
<typeAliases>
<typeAlias type="com.ola.pojo.Author" alias="Author"/>
typeAliases>
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,例如:
<typeAliases>
<package name="com.ola.pojo"/>
typeAliases>
每一个在包 domain.blog
中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author
的别名为 author
;若有注解,则别名为其注解值。
@Alias("author")
public class Author {
...
}
settings(设置):这是 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 | 从SQL中删除多余的空格字符。请注意,这也会影响SQL中的文字字符串。 (新增于 3.5.5) | true | false | false |
defaultSqlProviderType | Specifies an sql provider class that holds provider method (Since 3.5.6). This class apply to the type (or value ) attribute on sql provider annotation(e.g. @SelectProvider ), when these attribute was omitted. |
A type alias or fully qualified class name | Not set |
一个配置完整的 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>
mappers(映射器)
方式一:使用相对于类路径的资源引用(推荐)
<mappers>
<mapper resource="com/ola/dao/AuthorMapper.xml"/>
mappers>
方式二:使用映射器接口实现类的完全限定类名(不推荐,会出问题,如:不在一个包下;类名和xml名不同)
<mappers>
<mapper class="com.ola.dao.AuthorMapper"/>
mappers>
方式三:将包内的映射器接口实现全部注册为映射器(不推荐,会出问题,如:不在一个包下;类名和xml名不同)
<mappers>
<package name="com.ola.dao"/>
mappers>
ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
<resultMap id="AuthorMap" type="Author">
<result column="AuthorID" property="id"/>
resultMap>
<select id="getAuthorById" parameterType="String" resultMap="AuthorMap">
select *
from computer03.Name
where AuthorID = #{id};
select>
日志工厂
如果一个数据库操作出现了异常,我们需要排除错误,就要使用日志!
设置名 | 描述 | 有效值 | 默认值 |
---|---|---|---|
logPrefix | 指定 MyBatis 增加到日志名称的前缀。 | 任何字符串 | 未设置 |
logImpl | 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 | SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING | 未设置 |
在Mybatis中具体使用哪个日志需要再settings中设定!
STDOUT_LOGGING (标准日志输出):
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 1008315045.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3c19aaa5]
==> Preparing: select * from computer03.Name where AuthorID = ?;
==> Parameters: 12345678-1(String)
<== Columns: AuthorID, Name
<== Row: 12345678-1, olarian
<== Total: 1
Author{AuthorID='12345678-1', Name='olarian'}
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3c19aaa5]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3c19aaa5]
Returned connection 1008315045 to pool.
LOG4J:
导包
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
在resources中创建log4j.properties
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/Mybatis_study_ola.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
在mybatis-config.xml中配置settings为LOG4J日志实现
<settings>
<setting name="logImpl" value="LOG4J"/>
settings>
LOG4J的使用
[org.apache.ibatis.logging.LogFactory]-Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
[org.apache.ibatis.logging.LogFactory]-Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Opening JDBC Connection
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Created connection 30578394.
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1d296da]
[com.ola.dao.AuthorMapper.getAuthorById]-==> Preparing: select * from computer03.Name where AuthorID = ?;
[com.ola.dao.AuthorMapper.getAuthorById]-==> Parameters: 12345678-1(String)
[com.ola.dao.AuthorMapper.getAuthorById]-<== Total: 1
Author{AuthorID='12345678-1', Name='olarian'}
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1d296da]
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1d296da]
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Returned connection 30578394 to pool.
类中使用
// 注意这里导入的Logger包应该为org.apache.log4j.Logger
static Logger logger = Logger.getLogger(AuthorMapperTest.class);
@Test
public void log4jTest() {
logger.info("---------info:进入了TESTLOG4J方法!!---------");
logger.debug("---------debug:进入了TESTLOG4J方法!!---------");
logger.error("---------error:进入了TESTLOG4J方法!!---------");
}
[DEBUG][21-01-11][org.apache.ibatis.logging.LogFactory]Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
[DEBUG][21-01-11][org.apache.ibatis.logging.LogFactory]Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
[DEBUG][21-01-11][org.apache.ibatis.datasource.pooled.PooledDataSource]PooledDataSource forcefully closed/removed all connections.
[DEBUG][21-01-11][org.apache.ibatis.datasource.pooled.PooledDataSource]PooledDataSource forcefully closed/removed all connections.
[DEBUG][21-01-11][org.apache.ibatis.datasource.pooled.PooledDataSource]PooledDataSource forcefully closed/removed all connections.
[DEBUG][21-01-11][org.apache.ibatis.datasource.pooled.PooledDataSource]PooledDataSource forcefully closed/removed all connections.
[DEBUG][21-01-11][org.apache.ibatis.transaction.jdbc.JdbcTransaction]Opening JDBC Connection
[DEBUG][21-01-11][org.apache.ibatis.datasource.pooled.PooledDataSource]Created connection 30578394.
[DEBUG][21-01-11][org.apache.ibatis.transaction.jdbc.JdbcTransaction]Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1d296da]
[DEBUG][21-01-11][com.ola.dao.AuthorMapper.getAuthorById]==> Preparing: select * from computer03.Name where AuthorID = ?;
[DEBUG][21-01-11][com.ola.dao.AuthorMapper.getAuthorById]==> Parameters: 12345678-1(String)
[DEBUG][21-01-11][com.ola.dao.AuthorMapper.getAuthorById]<== Total: 1
[DEBUG][21-01-11][org.apache.ibatis.transaction.jdbc.JdbcTransaction]Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1d296da]
[DEBUG][21-01-11][org.apache.ibatis.transaction.jdbc.JdbcTransaction]Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1d296da]
[DEBUG][21-01-11][org.apache.ibatis.datasource.pooled.PooledDataSource]Returned connection 30578394 to pool.
[DEBUG][21-01-11][org.apache.ibatis.logging.LogFactory]Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
[DEBUG][21-01-11][org.apache.ibatis.logging.LogFactory]Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
[DEBUG][21-01-11][org.apache.ibatis.datasource.pooled.PooledDataSource]PooledDataSource forcefully closed/removed all connections.
[DEBUG][21-01-11][org.apache.ibatis.datasource.pooled.PooledDataSource]PooledDataSource forcefully closed/removed all connections.
[DEBUG][21-01-11][org.apache.ibatis.datasource.pooled.PooledDataSource]PooledDataSource forcefully closed/removed all connections.
[DEBUG][21-01-11][org.apache.ibatis.datasource.pooled.PooledDataSource]PooledDataSource forcefully closed/removed all connections.
[DEBUG][21-01-11][org.apache.ibatis.transaction.jdbc.JdbcTransaction]Opening JDBC Connection
[DEBUG][21-01-11][org.apache.ibatis.datasource.pooled.PooledDataSource]Created connection 30578394.
[DEBUG][21-01-11][org.apache.ibatis.transaction.jdbc.JdbcTransaction]Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1d296da]
[DEBUG][21-01-11][com.ola.dao.AuthorMapper.getAuthorById]==> Preparing: select * from computer03.Name where AuthorID = ?;
[DEBUG][21-01-11][com.ola.dao.AuthorMapper.getAuthorById]==> Parameters: 12345678-1(String)
[DEBUG][21-01-11][com.ola.dao.AuthorMapper.getAuthorById]<== Total: 1
[DEBUG][21-01-11][org.apache.ibatis.transaction.jdbc.JdbcTransaction]Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1d296da]
[DEBUG][21-01-11][org.apache.ibatis.transaction.jdbc.JdbcTransaction]Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1d296da]
[DEBUG][21-01-11][org.apache.ibatis.datasource.pooled.PooledDataSource]Returned connection 30578394 to pool.
[INFO][21-01-11][dao.AuthorMapperTest]---------info:进入了TESTLOG4J方法!!---------
[DEBUG][21-01-11][dao.AuthorMapperTest]---------debug:进入了TESTLOG4J方法!!---------
[ERROR][21-01-11][dao.AuthorMapperTest]---------error:进入了TESTLOG4J方法!!---------
Q:为什么要分页?
A:为了减少数据的处理量
使用Limit分页,语法:select * from Table limit startIndex,pageSize;
使用Mybatis实现分页
接口
List<Author> getAuthorByLimit(Map<String, Integer> map);
Mapper.xml
<select id="getAuthorByLimit" resultType="Author" parameterType="map">
select *
from computer03.Name
limit #{startIndex},#{pageSize};
select>
测试
@Test
public void getAuthorByLimit() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
AuthorMapper mapper = sqlSession.getMapper(AuthorMapper.class);
HashMap<String, Integer> map = new HashMap<>();
map.put("startIndex", 0);
map.put("pageSize", 15);
List<Author> authorByLimit = mapper.getAuthorByLimit(map);
for (Author author : authorByLimit) {
System.out.println(author);
}
sqlSession.close();
}
使用RowBounds实现分页(不推荐使用)
接口
List<Author> getAuthorByRowBounds();
Mapper.xml
<select id="getAuthorByRowBounds" resultType="Author">
select *
from computer03.Name
select>
测试
@Test
public void getAuthorByRowBounds() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
RowBounds rowBounds = new RowBounds(0, 3);
List<Author> authorList =
sqlSession.selectList("com.ola.dao.AuthorMapper.getAuthorByRowBounds", null, rowBounds);
for (Author author : authorList) {
System.out.println(author);
}
sqlSession.close();
}
使用分页插件 Mybatis PageHelper
引入Jar包
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelperartifactId>
<version>5.2.0version>
dependency>
配置拦截器插件
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<property name="param1" value="value1"/>
plugin>
plugins>
分页插件参数介绍
底层实现机制:反射(动态代理)
增加接口
public interface AuthorMapper {
@Select("select * from computer03.Name limit 0,15")
List<Author> getAuthors();
}
绑定接口
<mappers>
<mapper class="com.ola.dao.AuthorMapper"/>
mappers>
测试
package com.ola.dao;
import com.ola.pojo.Author;
import com.ola.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
/**
* ClassName:authorTest Package:com.ola.dao
*
* @author morningj
* @date 2021/1/11 12:34
*/
public class authorTest {
@Test
public void getAuthors() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
AuthorMapper mapper = sqlSession.getMapper(AuthorMapper.class);
List<Author> authors = mapper.getAuthors();
for (Author author : authors) {
System.out.println(author);
}
sqlSession.close();
}
}
Attention: 使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让你本就复杂的 SQL 语句更加混乱不堪。 因此,如果你需要做一些很复杂的操作,最好用 XML 来映射语句。
SELECT:
@Select("select * from computer03.Name where AuthorID = #{id}")
Author getAuthorById(@Param("id") String id);
@Test
public void getAuthorById() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
AuthorMapper mapper = sqlSession.getMapper(AuthorMapper.class);
Author authorById = mapper.getAuthorById("12345678-1");
System.out.println(authorById);
sqlSession.close();
}
INSERT:
@Insert("insert into computer03.Name(AuthorID,Name) values(#{id},#{name})")
void addAuthor(@Param("id") String authorID, @Param("name") String name);
@Test
public void addAuthor() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
AuthorMapper mapper = sqlSession.getMapper(AuthorMapper.class);
mapper.addAuthor("12345678-2", "niushijian");
sqlSession.close();
}
法二
@Insert("insert into computer03.Name(AuthorID,Name) values(#{AuthorID},#{Name})")
void addAuthor02(Author author);
@Test
public void addAuthor() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
AuthorMapper mapper = sqlSession.getMapper(AuthorMapper.class);
mapper.addAuthor02(new Author("12345678-3", "olarional"));
sqlSession.close();
}
UPDATE:
@Update("update computer03.Name set AuthorID=#{AuthorID},Name=#{Name} where AuthorID=#{AuthorID}")
void updateAuthor(Author author);
@Test
public void updateAuthor() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
AuthorMapper mapper = sqlSession.getMapper(AuthorMapper.class);
mapper.updateAuthor(new Author("12345678-3", "o"));
sqlSession.close();
}
DELETE:
@Delete("delete from computer03.Name where AuthorID=#{deleteId}")
void deleteAuthor(@Param("deleteId") String id);
@Test
public void deleteAuthor() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
AuthorMapper mapper = sqlSession.getMapper(AuthorMapper.class);
mapper.deleteAuthor("12345678-4");
sqlSession.close();
}
关于@Param()注解
关于==#{}和${}==的区别
#是预编译的,相当于PreparedStatement!一般会使用#{}来防止SQL注入问题!