Java学习笔记-Day74 MyBatis 框架(一)



一、MyBatis 框架介绍

1、简介


MyBatis 是持久层框架、轻量级框架、半自动的ORM框架,用于数据库的访问。它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

官方文档:https://mybatis.org/mybatis-3/zh/index.html

2、MyBatis的全局配置文件


MyBatis的全局配置文件(mybatis-config.xml文件)中包含了对 MyBatis 系统的核心设置,包含获取数据库连接实例的数据源(DataSource)和决定事务作用域和控制方式的事务管理器(TransactionManager)。

操作过程:从MyBatis的全局配置文件中构建 SqlSessionFactory对象,这个对象可以创建SQLSession对象,再通过SQLSession对象获取Mapper接口的实例,然后调用这个实例的增加、删除、修改和查询方法,实现对数据库数据的操作。

  • 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>
  <!-- 获取数据库连接实例的数据源 -->
  <properties resource="db.properties"></properties>
  <environments default="development">
    <environment id="development">
      <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>
  </environments>
  <!-- 映射文件的地址 -->
  <mappers>
    <mapper resource="com/etc/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>
  • db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatisdb?serverTimezone=Asia/Shanghai
username=root
password=root

3、SqlSessionFactory(工厂)


SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。

4、SqlSession(核心对象)


每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。也绝不能将 SqlSession 实例的引用放在任何类型的管理作用域中,比如 Servlet 架构中的 HttpSession。

SqlSession接口的实现类是DefaultSqlSession类。通过SqlSession对象获取Dao层某个接口的实例(底层是通过动态代理实现的)。

5、映射文件


MyBatis 的真正强大在于它的映射语句,也是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 就是针对 SQL 构建的,并且比普通的方法做的更好。

SQL 映射文件有很少的几个顶级元素(按照它们应该被定义的顺序):
(1)cache – 给定命名空间的缓存配置。
(2)cache-ref – 其他命名空间缓存配置的引用。
(3)resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
(4)parameterMap – 已废弃!老式风格的参数映射。内联参数是首选,这个元素可能在将来被移除,这里不会记录。
(5)sql – 可被其他语句引用的可重用语句块。
(6)insert – 映射插入语句
(7)update – 映射更新语句
(8)delete – 映射删除语句
(9)select – 映射查询语句

  • BlogMapper.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.etc.mybatis.dao.BlogMapper">
  <!-- id="selectBlog" 是一个接口中的方法名叫做selectBlog
       resultType="Blog" 是这个方法的返回值类型,这里请写完整地包名 
       #{id} 代表传递过来的参数
  -->
  <!-- 查询 -->
  <select id="selectBlog" resultType="com.etc.mybatis.entity.Blog">
    select * from blog where id = #{id}
  </select>
  <!-- 查询 -->
  <select id="selectBlogs" resultType="com.etc.mybatis.entity.Blog">
    select * from blog
  </select>
  <!-- 插入 -->
  <insert id="insertBlog">
 	 insert into blog (id,title,content) values (#{id},#{title},#{content})
  </insert>
  <!-- 修改 -->
  <update id="updateBlog">
  	update blog set title=#{title},content=#{content} where id=#{id}
  </update>
  <!-- 修改 -->
  <update id="updateBlogs">
  	update blog set title=#{title},content=#{content} where id=#{id}
  </update>
  <!-- 删除 -->
  <delete id="deleteBlog">
	delete from blog where id=#{id}
  </delete>
</mapper>

二、操作步骤


1、映射文件实现操作


(1)加入 mybatis.jar 和 mysql-connector-java.jar 这两个jar包到java项目中。
在这里插入图片描述
(2)在src目录下创建Mybatis的全局配置文件mybatis-config.xml(包含数据库连接信息和映射文件地址)和db.properties配置文件。

  • 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>
  <!-- 获取数据库连接实例的数据源 -->
  <properties resource="db.properties"></properties>
  <environments default="development">
    <environment id="development">
      <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>
  </environments>
  <!-- 映射文件的地址 -->
  <mappers>
    <mapper resource="com/etc/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>
  • db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatisdb?serverTimezone=Asia/Shanghai
username=root
password=root

(3)创建对应的数据库表,根据表结构创建实体类,并创建Dao层的接口。

package com.etc.mybatis.entity;

public class Blog {
    
    
	private int id;
	private String title;
	private String content;
	public Blog(int id, String title, String content) {
    
    
		super();
		this.id = id;
		this.title = title;
		this.content = content;
	}
	public Blog() {
    
    
		super();
	}
	public int getId() {
    
    
		return id;
	}
	public void setId(int id) {
    
    
		this.id = id;
	}
	public String getTitle() {
    
    
		return title;
	}
	public void setTitle(String title) {
    
    
		this.title = title;
	}
	public String getContent() {
    
    
		return content;
	}
	public void setContent(String content) {
    
    
		this.content = content;
	}
	@Override
	public String toString() {
    
    
		return "Blog [id=" + id + ", title=" + title + ", content=" + content + "]";
	}
}
package com.etc.mybatis.dao;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.etc.mybatis.entity.Blog;

public interface BlogMapper {
    
    
	// 通过id查询Blog数据
	public Blog selectBlog(int id);
	// 通过查询Blog的所有数据
	public List<Blog> selectBlogs();
	// 插入操作
	public boolean insertBlog(Blog blog);
	// 修改操作(使用Blog类)
	public boolean updateBlog(Blog blog);
	// 修改操作(多个参数可以使用@Param注解)
	public boolean updateBlogs(@Param("id") int id,@Param("title") String title,@Param("content") String content);
	// 删除操作
	public boolean deleteBlog(int id);
}

(4)创建映射文件BlogMapper.xml,并编写sql语句。

<?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.etc.mybatis.dao.BlogMapper">
  <!-- id="selectBlog" 是一个接口中的方法名叫做selectBlog
       resultType="Blog" 是这个方法的返回值类型,这里请写完整地包名 
       #{id}占位符 代表传递过来的参数
  -->
  <!-- 查询 -->
  <select id="selectBlog" resultType="com.etc.mybatis.entity.Blog">
    select * from blog where id = #{id}
  </select> 
  <!-- 查询 -->
  <select id="selectBlogs" resultType="com.etc.mybatis.entity.Blog">
    select * from blog
  </select> 
  <!-- 插入 -->
  <insert id="insertBlog">
 	 insert into blog (id,title,content) values (#{id},#{title},#{content})
  </insert>
  <!-- 修改 -->
  <update id="updateBlog">
  	update blog set title=#{title},content=#{content} where id=#{id}
  </update>
  <!-- 修改 -->
  <update id="updateBlogs">
  	update blog set title=#{title},content=#{content} where id=#{id}
  </update> 
  <!-- 删除 -->
  <delete id="deleteBlog">
	delete from blog where id=#{id}
  </delete>
</mapper>

(5)编写测试类,创建sqlSessionFactory对象,通过sqlSessionFactory对象得到SqlSession对象,通过SqlSession对象得到Mapper实例,调用Mapper实例的方法来完成查询、修改、增加或删除操作。查询操作不用手动提交事务,增加、删除、修改都需要手动提交事务。

  • 查询操作的测试类
public class TestMybaitsSelect {
    
    
	public static void main(String[] args) throws IOException {
    
    
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession session = sqlSessionFactory.openSession();
		BlogMapper mapper = session.getMapper(BlogMapper.class);
		Blog blog = mapper.selectBlog(1);
		System.out.println(blog);
	}
}
  • 修改操作的测试类
public class TestMybaitsUpdate {
    
    
	public static void main(String[] args) throws IOException {
    
    
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession session = sqlSessionFactory.openSession();
		BlogMapper mapper = session.getMapper(BlogMapper.class);
		Blog b = new Blog(12, "jack", "jack");
		boolean flag = mapper.updateBlog(b);
		// 手动提交事务
		session.commit();
		session.close();
		inputStream.close();
		System.out.println("flag="+flag);
	}
}
  • 增加操作的测试类
public class TestMybaitsInsert {
    
    
	public static void main(String[] args) throws IOException {
    
    
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession session = sqlSessionFactory.openSession();
		BlogMapper mapper = session.getMapper(BlogMapper.class);
		Blog b = new Blog(12, "tom", "tomaandjerry");
		boolean flag = mapper.insertBlog(b);
		// 手动提交事务
		session.commit();
		session.close();
		inputStream.close();
		System.out.println("flag="+flag);
	}
}
  • 删除操作的测试类
public class TestMybaitsDelete {
    
    
	public static void main(String[] args) throws IOException {
    
    
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession session = sqlSessionFactory.openSession();
		BlogMapper mapper = session.getMapper(BlogMapper.class);
		boolean flag = mapper.deleteBlog(12);
		// 手动提交事务
		session.commit();
		session.close();
		inputStream.close();
		System.out.println("flag="+flag);
	}
}

2、映射器注解实现操作


因为最初设计时,MyBatis 是一个 XML 驱动的框架。配置信息是基于 XML 的,而且 映射语句也是定义在 XML 中的。而到了 MyBatis3,有新的可用的选择了。MyBatis3 构建在基于全面而且强大的Java 配置 API 之上。这个配置 API 是基于 XML 的 MyBatis 配置的基础,也是新的基于注解配置的基础。注解提供了一种简单的方式来实现简单映射语句,而 不会引入大量的开销。

操作步骤:

(1)加入 mybatis.jar 和 mysql-connector-java.jar 这两个jar包到java项目中。

(2)在src目录下创建Mybatis的全局配置文件mybatis-config.xml(包含数据库连接信息和映射文件地址)和db.properties配置文件。

  • 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>
  <!-- 获取数据库连接实例的数据源 -->
  <properties resource="db.properties"></properties>
  <environments default="development">
    <environment id="development">
      <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>
  </environments>
  <!-- Mapper接口的位置 -->
  <mappers>
    <mapper class="com.etc.mybatis.example.BlogMapper"/>
  </mappers>
</configuration>
  • db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatisdb?serverTimezone=Asia/Shanghai
username=root
password=root

(3)创建对应的数据库表,根据表结构创建实体类。创建Dao层的接口,并在接口添加映射器注解。

package com.etc.mybatis.entity;

public class Blog {
    
    
	private int id;
	private String title;
	private String content;
	public Blog(int id, String title, String content) {
    
    
		super();
		this.id = id;
		this.title = title;
		this.content = content;
	}
	public Blog() {
    
    
		super();
	}
	public int getId() {
    
    
		return id;
	}
	public void setId(int id) {
    
    
		this.id = id;
	}
	public String getTitle() {
    
    
		return title;
	}
	public void setTitle(String title) {
    
    
		this.title = title;
	}
	public String getContent() {
    
    
		return content;
	}
	public void setContent(String content) {
    
    
		this.content = content;
	}
	@Override
	public String toString() {
    
    
		return "Blog [id=" + id + ", title=" + title + ", content=" + content + "]";
	}
}
public interface BlogMapper {
    
    
	@Select(value="select * from blog where id = #{id}")
	public Blog selectBlog(int id);
	
	@Select(value="select * from blog")
	public List<Blog> selectBlogs();
	
	@Insert(value="insert into blog (id,title,content) values (#{id},#{title},#{content})")
	public void insertBlog(Blog blog);
	
	@Update(value="update blog set title=#{title},content=#{content} where id=#{id}")
	public void updateBlog(Blog blog);
	
	@Update(value="update blog set title=#{title},content=#{content} where id=#{id}")
	public void updateBlogs(@Param("id") int id,@Param("title") String title,@Param("content") String content);
	
	@Delete(value="delete from blog where id=#{id}")
	public void deleteBlog(int id);
}


(4)编写测试类,创建sqlSessionFactory对象,通过sqlSessionFactory对象得到SqlSession对象,通过SqlSession对象得到Mapper实例,调用Mapper实例的方法来完成查询、修改、增加或删除操作。查询操作不用手动提交事务,增加、删除、修改都需要手动提交事务。

  • 查询操作的测试类
public class TestMybaitsSelect {
    
    
	public static void main(String[] args) throws IOException {
    
    
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession session = sqlSessionFactory.openSession();
		BlogMapper mapper = session.getMapper(BlogMapper.class);
		Blog blog = mapper.selectBlog(1);
		System.out.println(blog);
	}
}
  • 修改操作的测试类
public class TestMybaitsUpdate {
    
    
	public static void main(String[] args) throws IOException {
    
    
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession session = sqlSessionFactory.openSession();
		BlogMapper mapper = session.getMapper(BlogMapper.class);
		Blog b = new Blog(12, "jack", "jack");
		boolean flag = mapper.updateBlog(b);
		// 手动提交事务
		session.commit();
		session.close();
		inputStream.close();
		System.out.println("flag="+flag);
	}
}
  • 增加操作的测试类
public class TestMybaitsInsert {
    
    
	public static void main(String[] args) throws IOException {
    
    
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession session = sqlSessionFactory.openSession();
		BlogMapper mapper = session.getMapper(BlogMapper.class);
		Blog b = new Blog(12, "tom", "tomaandjerry");
		boolean flag = mapper.insertBlog(b);
		// 手动提交事务
		session.commit();
		session.close();
		inputStream.close();
		System.out.println("flag="+flag);
	}
}
  • 删除操作的测试类
public class TestMybaitsDelete {
    
    
	public static void main(String[] args) throws IOException {
    
    
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession session = sqlSessionFactory.openSession();
		BlogMapper mapper = session.getMapper(BlogMapper.class);
		boolean flag = mapper.deleteBlog(12);
		// 手动提交事务
		session.commit();
		session.close();
		inputStream.close();
		System.out.println("flag="+flag);
	}
}

三、ResultMap


如果实体类的属性和表的列名不一致的话,使用resultMap来处理,可以通过映射文件或者注解来实现。resultMap和resultType只能使用一个。

(1)映射文件实现

<?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.etc.mybatis.dao.BlogMapper">
	<!-- resultMap="blogResultMap" 引用的是自定义的resultMap -->
	<select id="selectBlog" resultMap="blogResultMap">
	    select * from blog where blogid = #{id}
	</select>
	
	<!-- 自定义的resultMap: (1)解决了实体类属性和表结构不一致 (2)表关联查询,实体关系(1:N 1:1 M:N) -->
	<resultMap id="blogResultMap" type="com.etc.mybatis.entity.Blog" >
		<!-- id:主属性和列对应设置 ,property="id" 类中的属性,column="blogid" 表中的列名 -->
		<id property="id" column="blogid"/>
		<!-- result:其他列和属性配置 ,property="title"是类中的属性,column="blogtitle"是表中的列名 -->
		<result property="title" column="blogtitle"/>
		<result property="content" column="blogcontent"/>
	</resultMap>
</mapper>

(2)注解实现

public interface BlogMapper {
    
    
	@Select(value="select * from blog where blogid = #{id}")
	@Results(id = "blogResultMap", value = {
    
     @Result(property="id", column="blogid", id=true),
			@Result(property="title", column = "blogtitle"), 
			@Result(property="content", column="blogcontent") })
	public Blog selectBlog(int id);
}

猜你喜欢

转载自blog.csdn.net/qq_42141141/article/details/114294596
今日推荐