MyBatis学习记录(一)

分三部分记录,MyBatis,MyBatis Spring和Mybatis Generator。

这一片记录MyBatis的一些学习心得。

基本概念

  • SqlSession :创建查询使用的是SqlSession,叫做Session,实际上也是维护了一个数据库的连接,内部通过Connection对象连接数据库。
  • SqlSessionFactory:用来创建SqlSession,可以指定一些SqlSession的属性
  • SqlSessionFacotryBuilder:用来创建SqlSessionFactory。而SqlSessionFacotryBuilder是通过MyBatis的配置文件或配置类创建的

配置

可以通过文件或者类的方法,一个简单的配置文件:

<?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>
	<typeAliases>
		<typeAlias alias="User"
			type="com.mosakashaka.mybatissample.model.User" />
	</typeAliases>

	<!-- 环境,可以配置多个,default:指定采用哪个环境 -->
	<environments default="dev">
		<!-- id:唯一标识 -->
		<environment id="dev">
			<!-- 事务管理器,JDBC类型的事务管理器 -->
			<transactionManager type="JDBC" />
			<!-- 数据源,池类型的数据源 -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.cj.jdbc.Driver" />
				<property name="url"
					value="jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" />
				<property name="username" value="root" />
				<property name="password" value="123456" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="mappers/MyMapper.xml" />
	</mappers>
</configuration>

有这写信息(不完全列出)

  • typeAliases:mapper中使用的类型别名,MyBatis内置java标准类的别名,如果是自定义类,包名比较长,定义别名比较方便
  • environments:可以定义多个环境,一般用来指定不同的dataSource配置,其中dataSource也可以指定不同的类型,这里POOLED标识会维护一个连接缓存池,避免频繁建立断开连接
  • 定义Mappers:mapper是mybatis中的一个基本概念,表示数据库中的表(或者是查询返回的结果),如何map到实体类中。

mappers

一个包含了基本配mapper配置的mapper文件:

<?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="MyMapper">
	<resultMap id="result" type="User">
		<result property="id" column="id" />
		<result property="username" column="username" />
		<result property="password" column="password" />
		<result property="name" column="name" />
		<result property="age" column="age" />
		<result property="sex" column="sex" />
		<result property="birthday" column="birthday" />
	</resultMap>

	<select id="getAll" resultMap="result">
		SELECT * FROM tb_user;
	</select>

	<select id="getById" parameterType="int" resultType="User">
		SELECT *
		FROM tb_user WHERE id = #{id} ;
	</select>
	<insert id="insertList" useGeneratedKeys="true" keyProperty="id">
		insert into tb_user (username, password, name, age, sex, birthday)
		values
		<foreach item="item" collection="list" separator=",">
			(#{item.username}, #{item.password}, #{item.name}, #{item.age},
			#{item.sex}, #{item.birthday})
		</foreach>
	</insert>

</mapper>
  • mapper文件有namespace属性,在这里并没有很大的约束,但是到spring里会比较关键
  • mappers定义一系列sql语句段:selectinsertupdatedelete等,在其中写sql语句执行
  • sql语句段有id,这也是关进属性,代码中指定要执行哪个sql时,需要靠namespace.sqlid来说明执行的语句
  • sql中可以通过#{param}的方式注入调用传入的参数
  • sql支持条件化拼接:ifwhenforeach等。
  • 强大的resultMap功能,可以将查询结果map到复杂的实体类

resultMap

通过语句中的resultMap=xxx标签,指定语句返回结果被一个resultMap解析关联到实体类。

一个复杂的查询selectBlogDetails通过id为detailedBlogResultMap的ResultMap关联到Blog实体类:

<!-- Very Complex Statement -->
<select id="selectBlogDetails" resultMap="detailedBlogResultMap">
  select
       B.id as blog_id,
       B.title as blog_title,
       B.author_id as blog_author_id,
       A.id as author_id,
       A.username as author_username,
       A.password as author_password,
       A.email as author_email,
       A.bio as author_bio,
       A.favourite_section as author_favourite_section,
       P.id as post_id,
       P.blog_id as post_blog_id,
       P.author_id as post_author_id,
       P.created_on as post_created_on,
       P.section as post_section,
       P.subject as post_subject,
       P.draft as draft,
       P.body as post_body,
       C.id as comment_id,
       C.post_id as comment_post_id,
       C.name as comment_name,
       C.comment as comment_text,
       T.id as tag_id,
       T.name as tag_name
  from Blog B
       left outer join Author A on B.author_id = A.id
       left outer join Post P on B.id = P.blog_id
       left outer join Comment C on P.id = C.post_id
       left outer join Post_Tag PT on PT.post_id = P.id
       left outer join Tag T on PT.tag_id = T.id
  where B.id = #{id}
</select>

<!-- Very Complex Result Map -->
<resultMap id="detailedBlogResultMap" type="Blog">
  <constructor>
    <idArg column="blog_id" javaType="int"/>
  </constructor>
  <result property="title" column="blog_title"/>
  <association property="author" javaType="Author">
    <id property="id" column="author_id"/>
    <result property="username" column="author_username"/>
    <result property="password" column="author_password"/>
    <result property="email" column="author_email"/>
    <result property="bio" column="author_bio"/>
    <result property="favouriteSection" column="author_favourite_section"/>
  </association>
  <collection property="posts" ofType="Post">
    <id property="id" column="post_id"/>
    <result property="subject" column="post_subject"/>
    <association property="author" javaType="Author"/>
    <collection property="comments" ofType="Comment">
      <id property="id" column="comment_id"/>
    </collection>
    <collection property="tags" ofType="Tag" >
      <id property="id" column="tag_id"/>
    </collection>
    <discriminator javaType="int" column="draft">
      <case value="1" resultType="DraftPost"/>
    </discriminator>
  </collection>
</resultMap>
  • association:一对一的查询,通过id属性匹配
  • collection:一对多的匹配,通过id属性匹配
  • discriminator:根据某一列不同的值,指定resultMap使用其他形式。这个例子里不是那么有用,因为这个属性会覆盖所有跟属性。

使用

创建连接

      // 指定全局配置文件
			String resource = "mybatis-config.xml";
			// 读取配置文件
			InputStream inputStream = Resources.getResourceAsStream(resource);
			// 构建sqlSessionFactory
			SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
			// 获取sqlSession

			try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
      //执行一些CRUD操作
      }

这里用配置文件创建了SqlSessionFactoryBuilder,进而创建SqlSessionFactory->sqlSession

sqlSession执行一些数据库操作

使用

try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
				System.out.println("sessecion:" + sqlSession.toString());
				// 操作CRUD,第一个参数:指定statement,规则:命名空间+“.”+statementId
				// bulk insert
				User u1 = new User();
				u1.setName("测试1");
				u1.setUsername("test1");
				u1.setPassword("123456");
				u1.setSex(0);
				u1.setAge(30);
				u1.setBirthday(new Date(-1, 2, 10));
				User u2 = new User();
				u2.setName("测试2");
				u2.setUsername("test2");
				u2.setPassword("123456");
				u2.setSex(0);
				u2.setAge(320);
				u2.setBirthday(new Date(1, 3, 10));

				sqlSession.insert("MyMapper.insertList", new ArrayList<User>() {

					{
						add(u1);
						add(u2);
					}
				});
				sqlSession.commit();

				User user = sqlSession.selectOne("MyMapper.getById", 1);
				List<User> users = sqlSession.<User>selectList("MyMapper.getAll");
				System.out.println(user);
				for (User u : users) {
					System.out.println(u);
				}
			}

通过SqlSessionselectListselectOnedeleteinsert等方法,调用xml中配置的sql(传入namespace.sqlId)调用,参数是sql中指定的参数。

原文地址:https://www.cnblogs.com/mosakashaka/p/12609135.html

时间: 2024-07-31 11:21:58

MyBatis学习记录(一)的相关文章

MyBatis 学习记录5 MyBatis的二级缓存

主题 之前学习了一下MyBatis的一级缓存,主要涉及到BaseExecutor这个类. 现在准备学习记录下MyBatis二级缓存. 配置二级缓存与初始化发生的事情 首先二级缓存默认是不开启的,需要自己配置开启. 如上图,需要在configuration里去开启. 其次在需要用到二级缓存的Mapper的配置里做一些操作,如下图,增加一个cache节点 至此就可以在UserMapper上开启二级缓存了. 当MaBatis初始化的时候,需要解析各种XML配置来生成SQLSessionFactory,

MyBatis 学习记录3 MapperMethod类

主题 之前学习了一下MapperProxy的生产过程,自定义Mapper类的对象是通过动态代理生产的,调用自定义方法的时候实际上是调用了MapperMethod的execute方法:mapperMethod.execute(sqlSession, args);所以想再简单学习记录下MapperMethod类 组成 从上图可知,MapperMethod只有2个成员域,都是静态内部类,所以 MapperMethod ≈ SqlCommand + MethodSignature SqlCommand

Mybatis学习记录(三)--Mybatis配置文件详解

关于mybatis的配置文件,主要有两个,一个是SqlMapperConfig.xml文件一个是mapper.xml文件,分别对这两个进行深入全面学习. 一.SqlMapperConfig.xml文件 1.标签概况 在SqlMapperConfig.xml中主要有以下标签,其中环境集合environments和spring整合后废除不用.objectFactory和plugins不经常使用. properties(属性) settings(全局配置参数) typeAliases(类型别名) ty

Mybatis学习记录(四)--高级查询和缓存

这些都是连贯的学习笔记,所以有的地方因为之前都说过,所以也就没怎么写详细了,看不太明白的可以看看之前的笔记. 一.高级查询 高级查询主要是一对一查询,一对多查询,多对多查询 1.一对一查询 有用户和订单两个表,用户对订单是1对1查询.也就是订单中有一个外键是指向用户的. 先创建实体类: User.java public class User { private int id; private String username; private String password; private St

MyBatis 学习记录6 TypeHandler

主题 因为对MyBatis在JDBC数据和Java对象之间数据转化比较感兴趣,所以就记录并学习一下TypeHandler. 使用场景 如上图所示,观察下接口方法就能明白.TypeHandler主要用于JDBC数据与Java对象数据之间转化,比如更新数据库的时候可以设置java对象里的字段怎么映射到JDBC数据库支持的类型.或者查询数据的时候,返回的JDBC的数据怎么转化成Java对象中的属性. 这篇文章主要以一个select查询为例,学习下TypeHandler都被应用在了哪些阶段? 怎么被使用

Mybatis学习记录(六)----Mybatis的高级映射

作者:余家小子 1.一对多查询 1.1 需求 查询订单及订单明细的信息. 1.2 sql语句 确定主查询表:订单表 确定关联查询表:订单明细表 在一对一查询基础上添加订单明细表关联即可. SELECT orders.*, USER.username, USER.sex, USER.address, orderdetail.id orderdetail_id, orderdetail.items_id, orderdetail.items_num, orderdetail.orders_id FR

mybatis学习记录

转自:http://www.yihaomen.com/article/java/302.htm (读者注:其实这个应该叫做很基础的入门一下下,如果你看过Hibernate了那这个就非常的简单) (再加一条,其实大家可以看官方的教程更好些:http://mybatis.github.io/mybatis-3/,而且如果英文不是很好的那就看中文的:http://mybatis.github.io/mybatis-3/zh/sqlmap-xml.html) 写在这个系列前面的话: 以前曾经用过ibat

Mybatis学习记录(二)--Mybatis开发DAO方式

mybatis开发dao的方法通常用两种,一种是传统DAO的方法,一种是基于mapper代理的方法,下面学习这两种开发模式. 写dao之前应该要对SqlSession有一个更加细致的了解 一.mybatis的SqlSession使用范围 SqlSessionFactoryBuilder用于创建SqlSessionFacoty,SqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder了,因为SqlSession是通过SqlSessionFactory生产

mybatis学习记录------2

一  单条记录查询 上篇博客的例子便是单条记录查询 二 多条记录查询 1 在映射文件中加入如下sql查询,${}:表示拼接sql串,将接收到的参数不加任何修饰拼接在sql中,${value}:接收输入参数的内容,如果传入类型是简单类型,${}中只能使用value. <!--根据名称查找记录,可能返回多条记录 resultType:指定就是单条记录所映射的java对象类型 ${}:表示拼接sql串,将接收到的参数不加任何修饰拼接在sql中. 使用${}拼接sql,容易引起sql注入 ${value