一、什么是myabtis
官方链接:www.mybatis.org/mybatis-3/z…
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
总而言之,mybatis是一款数据持久层框架(记得不是ORM框架)。
二、使用mybatis操作数据库
- 引入mybatis
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
复制代码
全部pom文件配置:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>source.code</groupId>
<artifactId>mybatis</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>mybatis Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
</dependencies>
<build>
<finalName>mybatis</finalName>
</build>
</project>
复制代码
- 添加mybatis配置文件,映射文件
配置文件命名为mybatis.xml,映射文件命名为article.xml
mybatis.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>
<properties resource="config.properties">
<property name="username" value="root"/>
<property name="password" value="root"/>
</properties>
<typeAliases>
<typeAlias type="com.mybatis.demo.entity.Article" alias="Article"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<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>
</environments>
<mappers>
<mapper resource="article.xml"></mapper>
</mappers>
</configuration>
复制代码
分析:mybatis.xml文件配置了数据库,映射文件等信息。
(1)properties标签配置一些基本属性值,可以在里面配置一些常量方便其它标签引用。properties标签可以使用resource属性来指定配置文件的路径。其中,会先读取读取配置文件,如果配置文件存在,则获取配置文件的键值对内容,如果在properties的子标签property有配置了和读取到键值对的配置文件的同key内容,则覆盖掉键值对配置文件的内容。也就是优先级是:property标签 > proerties文件;
(2)environments标签配置数据库的一些环境,比如数据源、事务管理
(3)mappers标签配置了映射文件的路径可以配置多个mappers文件
(4)还有更多标签和属性在这篇文章先不分析,后续文章会详细分析
config.properties文件内容
url=jdbc:mysql://localhost:3306/my_test_db?characterEncoding=UTF-8&useSSL=false
driver=com.mysql.jdbc.Driver
复制代码
article.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="com.mybatis.demo.mapper.ArticleMapper">
<select id="selectOne" parameterType="int" resultType="Article">
SELECT title, content FROM article WHERE id = #{id}
</select>
<insert id="insert" parameterType="Article">
INSERT INTO article (title, content) VALUES (#{title}, #{content})
</insert>
<update id="update" parameterType="Article">
UPDATE article SET title = #{title} WHERE id = #{id}
</update>
<delete id="delete" parameterType="int">
DELETE FROM article WHERE id = #{id}
</delete>
</mapper>
复制代码
- 创建实体类
Article.java
public class Article {
private Integer id;
private String title;
private String content;
public String getTitle() {
return title;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
复制代码
- 创建Mapper类
ArticleMapper.java
@Mapper
public interface ArticleMapper {
/**
* 添加文章
*
* @param article
* @return
*/
boolean insert(Article article);
/**
* 获取一条文章
*
* @param id 文章id
* @return
*/
Article selectOne(int id);
/**
* 更新文章
*
* @param article
* @return
*/
int update(Article article);
/**
* 删除文章
*
* @param id
* @return
*/
int delete(int id);
}
复制代码
- 创建测试类
ArticleMapperTest.java
public class ArticleMapperTest {
private SqlSessionFactory sqlSessionFactory;
private ArticleMapper mapper;
private SqlSession sqlSession;
@Before
public void setUp() throws IOException {
String mybatisCfg = "mybatis.xml";
InputStream in = Resources.getResourceAsStream(mybatisCfg);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
sqlSession = sqlSessionFactory.openSession();
mapper = sqlSession.getMapper(ArticleMapper.class);
}
@After
public void close() {
if (sqlSession != null) {
sqlSession.close();
}
}
@Test
public void testDelete() {
int count = mapper.delete(3);
sqlSession.commit();
System.out.println(count);
}
@Test
public void testUpdate() {
Article article = new Article();
article.setId(3);
article.setTitle("source code");
int count = mapper.update(article);
sqlSession.commit();
System.out.println(count);
}
@Test
public void testSelectOne() {
Article article = mapper.selectOne(1);
System.out.println("title:" + article.getTitle() + " " + "content:" + article.getContent());
sqlSession.close();
}
@Test
public void testInsertV1() {
Article article = new Article();
article.setTitle("我是标题");
article.setContent("我是文本内容");
int count = sqlSession.insert("com.mybatis.demo.mapper.ArticleMapper.insert", article);
sqlSession.commit();
sqlSession.close();
System.out.println(count);
}
@Test
public void testInsertV2() {
Article article = new Article();
article.setTitle("v2-标题");
article.setContent("v2-文本内容");
boolean flag = mapper.insert(article);
sqlSession.commit();
sqlSession.close();
System.out.println(flag);
}
}
复制代码
我们依次分析上面测试代码:
首先看下在运行测试用例之前,我们干了什么:
@Before
public void setUp() throws IOException {
String mybatisCfg = "mybatis.xml";
InputStream in = Resources.getResourceAsStream(mybatisCfg);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
sqlSession = sqlSessionFactory.openSession();
mapper = sqlSession.getMapper(ArticleMapper.class);
}
复制代码
我们是通过
InputStream in = Resources.getResourceAsStream(mybatisCfg);
来加载配置文件,创建SqlSessionFactory,由SqlSessionFactory获取SqlSession。
在mybatis中,一个SqlSession实例代表着一次数据库连接,SqlSession由SqlSessionFactory来获取。在整个应用运行过程,我们只需要一个SqlSessionFactory实例,但是可以有多个SqlSession实例。SqlSession是线程不安全的,所以我们最好在方法级别使用SqlSession,并且在使用完毕及时关闭连接,避免资源的浪费。
接下来我们看添加一条数据的操作是怎么样的
@Test
public void testInsertV1() {
Article article = new Article();
article.setTitle("我是标题");
article.setContent("我是文本内容");
int count = sqlSession.insert("com.mybatis.demo.mapper.ArticleMapper.insert", article);
sqlSession.commit();
sqlSession.close();
System.out.println(count);
}
复制代码
(1)我们通过SqlSession来操作数据库,调用insert方法,第一个参数指定对应的映射类的方法的全路径,第二个参数是添加的数据。
(2)执行insert方法的时候,mybatis会根据方法第一个参数指定的的全路径去查找对应的sql映射配置。在这里mybatis会根据“com.mybatis.demo.mapper.ArticleMapper.insert”来查找对应的映射文件对应的sql映射配置。mybatis的映射文件的每一个sql映射配置都会有一个唯一的id与之对应,可以简单理解为(映射文件的命名空间+sql映射配置的id属性值)的哈希值。于是mabtis找到命名空间为“com.mybatis.demo.mapper.ArticleMapper”,sql映射配置id属性值为“insert”的sql映射配置
我们在操作数据库的时候,可以不直接操作SqlSession,而是通过SqlSession获取Mapper,由Mapper来操作数据库。
@Test
public void testInsertV2() {
Article article = new Article();
article.setTitle("v2-标题");
article.setContent("v2-文本内容");
boolean flag = mapper.insert(article);
sqlSession.commit();
sqlSession.close();
System.out.println(flag);
}
复制代码
原理和使用SqlSession直接操作数据库一样,只不过是Mapper和SqlSession关联起来,执行Mapper的insert方法的时候,也是查找对应的sql映射配置。但是,这时候是使用Mapper的全路径名+执行的方法名(不用参数)来查找sql映射配置的。所以,我们的映射文件的命名空间需要的Mapper的全路径名,sql映射配置的id属性值必须和Mapper的方法同名
我们再来看一下,获取一条数据库记录的操作:
@Test
public void testSelectOne() {
Article article = mapper.selectOne(1);
System.out.println("title:" + article.getTitle() + " " + "content:" + article.getContent());
sqlSession.close();
}
复制代码
在执行Mapper的selectOne方法的时候,前面流程和插入一条数据一样,查找配置文件,解析sql,执行sql。只是在执行完sql后,mybatis还会对结果进行映射,然后返回映射结果集
删除和更新操作原理一样,就不过多分析了。 配置文件和映射文件的目录如图:
广告时间,可以忽略:
更多文章会在公众号第一时间发布,欢迎扫码关注公众号:深夜程猿
由于微信最近不允许修改公众号头像,公众号最近才是运营,所以还没有设置头像~~是不是很丑……