MyBatis01

MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc复杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由Mybatis框架执行sql并将结果映射成java对象并返回。
MyBatis架构
在这里插入图片描述
配置MyBatis
在classpath下创建SqlMapConfig.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>  
	<!-- 和spring整合后 environments配置将废除-->
	<environments default="development">
		<environment id="development">
		<!-- 使用jdbc事务管理-->
			<transactionManager type="JDBC" />
		<!-- 数据库连接池-->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
				<property name="username" value="root" />
				<property name="password" value="123" />
			</dataSource>
		</environment>
	</environments>
</configuration>

在classpath下的sqlmap目录下创建sql映射文件users.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="test">
</mapper>

namespace:命名空间,用于隔离sql语句。
1.必须是接口的全限定名
2.Statementid必须和接口的方法名称一致
3.接口方法的参数类型要和parameterType要一致
4.接口方法的返回值类型要和resultType一致

映射文件:

<!-- 根据id获取用户信息 -->
	<select id="findUserById" parameterType="int" resultType="com.baidu.mybatis.po.User">
		select * from user where id = #{id}
	</select>

#{}作用就是占位符,相当于jdbc的“?”;
parameterType:查询的参数类型。
resultType:查询结果的数据类型,如果是pojo应该给全路径

mybatis框架需要加载映射文件,将Users.xml添加在SqlMapConfig.xml

<mappers>
		<mapper resource="sqlmap/User.xml"/>
</mappers>
private SqlSessionFactory sqlSessionFactory=null;
	@Before
	public void init() throws Exception{
		//第一步:创建一个SQLSessionFactoryBuilder对象。
		SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder();
		//第二部:加载配置文件
		InputStream inputStream=Resources.getResourceAsStream("SqlMapConfig.xml");
		//第三步:创建SQLSessionFactory对象
	   sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
	}

	@Test
	public void getUserById() throws Exception {
		// 第四步:创建SQLSession对象
		SqlSession sqlSession = sqlSessionFactory.openSession();
		// 第五步:使用SQLSession对象执行查询,得到User
		// 第一个参数:执行查询statementId
		User user = sqlSession.selectOne("getUserById", 10);
		// 第六步:打印结果
		System.out.println(user);
		// 第七步:释放资源
		sqlSession.close();
	}

根据用户名查询用户信息
在user.xml中添加

<!-- 如果查询结果返回list。resultType设置为list中一个元素对的数据类型 
      ${}字符串拼接指令
    -->
    <select id="getUserByName" parameterType="string" resultType="java.lang.String">
    SELECT * FROM USER WHERE username LIKE '%${value}%';
    </select>

parameterType:定义输入到sql中的映射类型, v a l u e 使 {value}表示使用参数将 {value}替换,做字符串的拼接。
注意:如果是取简单数量类型的参数,括号中的值必须为value
resultType:定义结果映射类型。

代码测试

@Test
	public void getUserByName()throws Exception{
		//创建一个SQLSession对象
		SqlSession session = sqlSessionFactory.openSession();
		//执行查询
		List<User>list=session.selectList("getUserByName","%张%");
		for (User user : list) {
			System.out.println(user);
		}
		//释放资源
		session.close();
	}

#{}和$ {}
#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符设置,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。#{}可以接收简单类型值或pojo属性值。如果parameterType传输单个类型值,#{}括号中可以是value或其它名称。
$ {}表示拼接sql串,通过$ {}可以将parameterType传入的内容拼接在sql中且不进行jdbc类型转换,$ {}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,$ {}括号中只能是value
parameterType和resultType
parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。
resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象
selectOne和selectList
selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常
selectList可以查询一条或多条记录。

添加用户
在SqlMapConfig.xml中添加

<insert id="insertUser" parameterType="com.baidu.mybatis.po.User">
		<!-- selectKey将主键返回,需要再返回 -->
		<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
			select LAST_INSERT_ID()
		</selectKey>
	   insert into user(username,birthday,sex,address)
	    values(#{username},#{birthday},#{sex},#{address});
	</insert>

添加selectKey实现将主键返回
keyProperty:返回的主键存储在pojo中的哪个属性
order:selectKey的执行顺序,是相对与insert语句来说,由于mysql的自增原理执行完insert语句之后才将主键生成,所以这里selectKey的执行顺序为after
resultType:返回的主键是什么类型
LAST_INSERT_ID():是mysql的函数,返回auto_increment自增列新记录id值。

@Test
	public void addUser()throws Exception{
		//创建一个SQLSession对象
		SqlSession session = sqlSessionFactory.openSession();
		//创建User对象
		User user=new User();
		user.setUsername("赵四");
		user.setSex("男");
		user.setBirthday(new Date());
		user.setAddress("北京");
		session.insert("insertUser",user);
		//提交
		session.commit();
		session.close();	
	}

删除用户
映射文件

<!-- 删除用户 -->
	<delete id="deleteUserById" parameterType="int">
		delete from user where id=#{id}
	</delete>
@Test
	public void deleteUser()throws Exception{
		SqlSession session = sqlSessionFactory.openSession();
		session.delete("deleteUser",27);
		session.commit();
		session.close();
	}

修改用户

<!-- 修改用户 -->
    <update id="updateUser" parameterType="com.baidu.mybatis.po.User">
    update user set username=#{username} where id=#{id}
    </update>
@Test
	public void updateUser()throws Exception{
		SqlSession sqlSession = sqlSessionFactory.openSession();
		User user=new User();
		user.setUsername("王六");
		user.setId(26);
		sqlSession.update("updateUser",user);
		sqlSession.commit();
		sqlSession.close();
	}

一.SqlSession的使用范围
SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等。
通过SqlSessionFactory创建SqlSession,而SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建。
(1).SqlSessionFactoryBuilder
SqlSessionFactoryBuilder用于创建SqlSessionFacoty,SqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder了,因为SqlSession是通过SqlSessionFactory产生,所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是方法范围即方法体内局部变量。
(2).SqlSessionFactory
SqlSessionFactory是一个接口,接口中定义了openSession的不同重载方法,SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory.
(3).6.2.3 SqlSession
SqlSession是一个面向用户的接口, sqlSession中定义了数据库操作方法。
每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是请求或方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。
SqlMapConfig.xml配置文件
1.配置内容
SqlMapConfig.xml中配置的内容和顺序:
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
evironments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)

2.properties(属性)
SqlMapConfig.xml可以引用java属性文件中的配置信息
在classpath下定义db.properties文件,

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

SqlMapConfig.xml

<properties resource="db.properties"/>
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC"/>
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}"/>
				<property name="url" value="${jdbc.url}"/>
				<property name="username" value="${jdbc.username}"/>
				<property name="password" value="${jdbc.password}"/>
			</dataSource>
		</environment>
	</environments>

注意: MyBatis 将按照下面的顺序来加载属性:
(1): 在 properties 元素体内定义的属性首先被读取。
(2): 然后会读取properties 元素中resource或 url 加载的属性,它会覆盖已读取的同名属性。

3.自定义别名
在这里插入图片描述
在这里插入图片描述
简单用法
在这里插入图片描述 4.7.4.3 < package name=""/> < mappers> 基于classPath查询 根据接口名称加载mapper文件 要求:1.mapper映射文件和接口在同一个目录下 2.mapper映射文件的名称和接口名称一致 3.class就是接口的权限定名 < /mappers>