什么是MyBatis
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
内容来自MyBatis中文官网
说人话:MyBatis
是一个用在应用程序与数据库交互阶段(即所谓持久层,将数据由内存中的掉电即失暂时存储转为数据库中的永久存储)的框架,他可以帮助开发者完成以下工作:
- 装载JDBC,连接数据库,使用数据库连接池(默认启用)
- 运行SQL代码,自动设置参数到动态SQL中的?号位置
- 将SQL查询出来的数据自动封装为Java 对象,或Java对象的集合
体验过下面的操作之后,就可以理解它与原始JDBC操作的不同。
准备工作
引入MyBatis依赖
maven:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
为了方便调试学习,可以使用slf4j
日志框架,打印出mybatis运行日志以供观察。
slf4j maven:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.20</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
slf4j还需要一个配置文件,logback.xml
将此文件放在resources目录下
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--
CONSOLE :表示当前的日志信息是可以输出到控制台的。
-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--输出流对象 默认 System.out 改为 System.err-->
<target>System.out</target>
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度
%msg:日志消息,%n是换行符-->
<pattern>[%level] %blue(%d{HH:mm:ss.SSS}) %cyan([%thread]) %boldGreen(%logger{15}) - %msg %n</pattern>
</encoder>
</appender>
<!--
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR | ALL 和 OFF
, 默认debug
<root>可以包含零个或多个<appender-ref>元素,标识这个输出位置将会被本日志级别控制。
-->
<root level="ALL">
<!-- 注意:如果这里不配置关联打印位置,该位置将不会记录日志-->
<appender-ref ref = "CONSOLE"/>
</root>
</configuration>
配置MyBatis(使用MySQL示例)
mybatis-config.xml
文件,放在resources目录下。该文件主要是配置JDBC需要连接的数据库的名字,用户名,密码。其他配置属性详见这里
重要的属性已经包含在下面的代码块中
<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED"> <!--POOLED:启用数据库连接池-->
<property name="driver" value="com.mysql.jdbc.Driver"/><!--驱动程序名-->
<!--jdbc链接,在这里将yourDatabase配置为你的数据库名字-->
<property name="url" value="jdbc:mysql://localhost:3306/yourDatabase?useSSL=false"/>
<property name="username" value="root"/><!--用户名-->
<property name="password" value="123456"/><!--密码-->
</dataSource>
</environment>
</environments>
<mappers><!--添加映射器配置文件(下面再讲),在这里有两种方式配置-->
<!--<mapper resource="UserMapper.xml"/>--><!--第一种方式,直接写出文件名-->
<!--第二种方式,写出文件所在的包。适合用在文件很多的时候,不用像第一种方式一样一个一个写-->
<package name="xxx.yourPackage.mappers"/>
</mappers>
</configuration>
撰写映射器(mapper)
在上面mybatis-config中有一个mappers标签,这个标签里面就是放我们映射器的,resource属性指向配置文件。
映射器由一个接口和一个配置文件组成,这两个东西必须放在同一文件夹下。在idea中,我们要在resource目录下创建跟接口所在的包一样层次结构的文件夹,这样编译之后,这两个文件才能走到一块。
例如,在开发过程中这样子放置文件:
(UserMapper为用户类映射器,BrandMapper为商标类映射器,在下图中有两个映射器,也就有两个配置文件)
在resource目录下也创建形似org/learnmybatis/mapper的文件夹结构,将配置文件放在下面:
这样,接口与配置文件在编译之后就会被放到一起:
mapper.xml文件编写
为了使mybatis能够自动将数据库中的数据自动绑定到实体类对象上,数据库的字段名需要与实体类的属性名相同。实体类需生成setter和getter方法。
例如实体类User
public User{
private String username;
private String password;
public void setUsername(String username){
this.username=username;
}
public void setPassword(String password){
this.password=password;
}
//getter方法省略...
}
数据库中表头(user表)
username | password |
---|---|
张三 | e54b9p7g |
否则,需要使用resultMap标签,不写了
一个极简版本的mapper.xml: (brandMapper.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="org.learnmybatis.mapper.BrandMapper">
<insert id="addBrand"> <!--insert标签,表示插入。id需与接口中的方法名相同,下面会说-->
insert into tb_brand(brand_name, company_name, ordered, description, status)
VALUES (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status})
<!-- #{}为属性占位符,将来会根据占位符里的参数名往里面设置参数。注意,顺序需与上面数据库字段名匹配-->
</insert>
<update id="modifyBrand"> <!--update,更新操作-->
update tb_brand
set brand_name=#{brandName},
company_name=#{companyName},
description=#{description},
ordered=#{ordered},
status=#{status}
where id = #{id}
</update>
<delete id="deleteById"><!--删除操作-->
delete from tb_brand where id=#{id}
</delete>
<select id="selectAll" type="org.learnmybatis.pojo.Brand"><!--type写查询返回数据需要封装成什么实体类对象-->
select * from tb_brand;
</select>
<!--特殊字符:<小于号等 处理方法:1.转义字符< 2.CDATA区,输入CD-->
<select id="selectById" resultMap="brandResult">
select *
from tb_brand
where id = #{id}
</select>
</mapper>
然后,编写接口(brandMapper.java)
public interface BrandMapper {
//当返回多个对象时,可以使用List集合。mybatis会自动封装对象并放入集合
//方法名需与xml配置文件中每个增删改查标签的id相同
List<Brand> selectAll();
Brand selectById(int id);
//当有多个参数时,必须使用@Param注解每个形参应该匹配哪个属性占位符。也可传入pojo对象和map,这里不写
int addBrand(@Param(brandName) String brandName,@Param(companyName) String companyName,@Param(description) String description,@Param(ordered) int ordered,@Param(status) int status);
void modifyBrand(@Param(brandName) String brandName,@Param(companyName) String companyName,@Param(description) String description,@Param(ordered) int ordered,@Param(status) int status,@Param(id) int id);
void deleteById(int id);
}
调用接口里面的方法:
//加载MyBatis配置,获得SqlSessionFactory
String url = "mybatis-config.xml";
InputStream config = Resources.getResourceAsStream(url);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(config);
//获取mapper对象
SqlSession sqlSession = factory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//调用方法
List<Brand> results = mapper.selectAll();
至于动态SQL什么的,10分钟学不完,不写了