Mybatis
Mybatis
持久化
数据持久化
- 持久化就是将程序的数据在持久状态和瞬时状态转化的过程
- 内存:断电即失
- 数据库(jdbc),io文件持久化.
持久层
- 完成持久化工作的代码块
- 界限十分明显。
第一个mybatis程序
- 导入依赖
junit
junit
4.11
test
org.mybatis
mybatis
3.5.6
mysql
mysql-connector-java
8.0.29
- 编写mybatis工具类
package com.fiee.utlis;
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;
//sqlSessionFactory sqlsession
public class MybatisUtlis {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
//使用mybatis第一步获取sqlSessionFactory对象
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//既然有了sqlSessionFactory,顾名思义,我们就可以获得sqlsession的实例了
//sqlsession完全包含了面向数据库执行sql命令所需的所有方法
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
编写代码
-
实体类
package com.fiee.pojo; //实体类 public class Account { private int id; private String name; private double money; public Account() { } public Account(int id, String name, double money) { this.id = id; this.name = name; this.money = money; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } @Override public String toString() { return "Account{" + "id=" + id + ", name='" + name + '\'' + ", money=" + money + '}'; } } -
Dao类
-
package com.fiee.dao; import com.fiee.pojo.Account; import java.util.List; public interface AccountDao { ListgetAccountList(); } -
接口实现类,由原来接口实现类转变为一个Mapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
测试
package com.fiee;
import com.fiee.dao.AccountDao;
import com.fiee.pojo.Account;
import com.fiee.utlis.MybatisUtlis;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class TestDao {
@Test
public void test(){
//获得sqlsession对象
SqlSession sqlSession = MybatisUtlis.getSqlSession();
//执行SQL
AccountDao mapper = sqlSession.getMapper(AccountDao.class);
List accountList = mapper.getAccountList();
for (Account account:accountList) {
System.out.println(account);
}
//关闭sqlsession
sqlSession.close();
}
}
Map
传递Map中的key
Map传递参数,直接在sql中取出key即可[parameterType="map"]
对象传递参数,直接在sql中取对象的属性即可!
只有一个基本类型参数的情况下,可以直接在sql中取到!
多个参数用Map,或者注解
配置解析
1.核心配置文件
-
mybatis-config.xml
-
MyBatis的配置文件包含了会深深影响MyBatis行为的设置和属性信息
configuration
配置环境(environments)
Mybatis可以配置成适应多种环境
不过要记住:尽管可以配置多个环境,但每个sqlsessionFactory实例只能选择一种环境
学会适应配置多套运行环境
Mybatis默认的事务管理器就是JDBC,连接池:POOLED
属性(properties)
我们可以通过properties属性来实现引用配置文件
这些属性都是可外部配置且动态替换的,既可以在典型的java属性文件中配置,亦可以通过properties元素的子元素来传递(db.properties)
db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/accountinfo?useSSl=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=123456
在核心配置文件中映入
- 可以直接引入外部文件
- 可以在其中增加一些属性配置
- 如果两个文件有同一个字段,优先使用外部配置文件的
类型别名(typeAliases)
- 类型别名可为 Java 类型设置一个缩写名字。
- 意在降低冗余的全限定类名书写
-
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,
- 扫描实体类的包,它的默认别名就为这个类的首字母小写的类名
-
在实体类上使用注解命名@Alias("")
-
在实体类比较少的时候使用第一种
实体类十分多,使用第二种
第一种可以diy别名,第二种不行(但可以在注解取@Alias(""))
设置
这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。
| 设置名 | 描述 | 有效值 | 默认值 |
|---|---|---|---|
| cacheEnabled | 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 | true | false | true |
| lazyLoadingEnabled | 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。 |
true | false | false |
| logImpl | 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 | SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING | 未设置 |
映射器(mappers)
MapperRegistry:注册绑定我们的Mapper文件;
方式一:
方式二:
注意点:
- 接口和他的Mapper配置文件必须同名
- 接口和他的Mapper配置文件必须在同一个包下!
方式三:
注意点:
- 接口和他的Mapper配置文件必须同名
- 接口和他的Mapper配置文件必须在同一个包下!
生命周期和作用域
作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。
SqlSessionFactoryBuilder
- 一旦创建了 SqlSessionFactory,就不再需要它了。
- 局部变量
SqlSessionFactory
- 说白了就是可以想象为:数据库连接词
- SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。
- 因此 SqlSessionFactory 的最佳作用域是应用作用域。
- 最简单的就是使用单例模式或者静态单例模式。
SqlSession
- 连接到连接池的一个请求!
- 用完关闭,否则资源被占用!
解决属性名和字段名不一致的问题
resultMap
结果集映射
-
resultMap元素是Mybatis中最强大的元素
-
ResultMap的设计是想是,对于简单的语句根本不需要配置显示的结果集映射,而复杂一点的语句只需要描述他们的关系就行了
-
ResultMap的优秀之处——你完全可以不用显式地配置它们 -
需要映射谁就写谁就好了
日志
日志工厂
如果一个数据库操作,出现了异常,我们需要排错。日志就是最好的助手!
曾经:sout,debug
现在:日志工厂
logImpl 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING 未设置
Log4j
什么是Log4j
- 可以通过控制日志信息输送的目的地是控制台,文件,GUI组件
- 我们也可以控制每一条日志的输出格式
- 通过定义每一条日志信息的级别,我们能够更加细致的控制日志的生成过程
- 通过一个配置文件来灵活地配置,而不需要修改应用代码
1.先导入log4j的包
log4j
log4j
1.2.17
后面要用百度配置
简单使用
-
在要使用log4j的类中,导入包import org.apache.log4j.Logger
-
在日志对象,参数为当前类的class
static Logger logger=Logger.getLogger(UserDaoTest.class) -
日志级别
logger.info("info:进入了testLog4j"); logger.debug("debug:进入了testLog4j"); logger.error("error:进入了testLog4j");
分页
- 减少数据的处理量
使用mybatis实现分页,核心SQL
- 接口
- Mapper.xml
- 测试
注解开发
-
注解在接口上实现
-
@select("select * from user") ListgetUsers(); -
需要在核心配置文件中绑定接口!
-
<绑定接口> -
测试
Lombok
使用步骤:
- 在idea中安装Lombok插件
- 在项目中导入lombok的jar包(maven)
- 在实体类上加上注解即可(data)
多对一
使用结果集映射
复杂的属性,我们需要单独处理
对象:association
集合:collection
注:
? javaType指定属性的类型
? 集合中的泛型信息,我们使用ofType获取
动态SQL
什么是动态SQL:动态SQL就是指根据不同的条件生成不同的SQL语句
if -where标签
接口方法 查询员工 根据不同的条件来判断
/**
* 动态sql if where 标签 根据传入参数不同动态判断条件
*/
Employee selectDByEmp(Employee employee);
choose标签
/**
* 动态sql choose 标签 单条件查询 有一个条件满足就只接受一个条件 即使有多个条件满足 也无法加入进来
* 相当于 if-else 或者 switch-case
*/
Employee selectDByChoose(Employee employee);
set标签
set标签 解决语句上的逗号问题 注意写在where前面
update tbl_employee
last_name=#{lastName},
email=#{email},
salary=#{salary},
where
id=#{id}
Sql片段
有时候,我们可能会将一些功能的部分抽取出来,方便复用!
- 使用SQL标签抽取公共部分
- 在需要使用的地方使用include标签引用即可
注意事项:
- 最好基于单表来定义SQL片段!
- 不要存where标签
- 尽量只存if判断就可以了
Foreach
二级缓存
步骤:
-
开启缓存
-
-
在当前Mapper.xml中使用二级缓存
-
小结:
- 只要开启了二级缓存,在同一个Mapper下就有效
- 所有的数据都会先放在一级缓存中
- 只有当会话提交,或者关闭的时候,才会提交到二级缓存中