一、Mybatis的核心对象
1,SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder对象的构造方法如下图所示,我们可以分为以下三类
第一类构造方法build(Reader reader,String environment,Properties properties)
由上述build()方法可知,第一种形式的build()方法参数作用与第二种形式大体一致,唯一不同的是,第二种形式的build()方法使用InputStream字节流封装了XML文件形式的配置信息,而第一种形式的build()方法使用Reader字符流封装了xml文件形式的配置信息。
第二类构造方法build(InputStream inputStream,String environment,Properties properties)
上述build()方法中,参数inputStream是字节流,它封装了XML文件形式的配置信息;参数environment和参数properties为可选参数。其中,参数environment决定将要加载的环境,包括数据源和事务管理器;参数properties决定将要加载的properties文件。
第三类构造方法bulid(Configuration config)
通过类Configuration提供给SqlSessionFactoryBuilder的构造方法
tips:SqlSessionFactory对象是线程安全的,它一旦被创建在整个应用程序执行期间都会存在。如果我们多次创建同一个数据库的SqlSessionFactory对象,那么该数据库的资源将很容易被耗尽。通常每一个数据库都只创建一个SqlSessionFactory对象,所以在构建SqlSessionFactory对象时,建议使用单例模式。
2,SqlSessionFactory
工厂对象,创建SqlSession对象相关
1,sqlSession openSession()需手动提交事物
2,sqlSession openSession(True)会自动提交事物,sqlSession openSession(False)=sqlSession openSession()
3,Connection可提供自定义链接
4,参数execType有三个可选值
ExecutorType.SIMPLE:表示为每条语句创建一条新的预处理语句。
ExecutorType.REUSE:表示会复用预处理语句。
ExecutorType.BATCH:表示会批量执行所有更新语句。
3,SqlSession
可以操作数据库
SqlSession是MyBatis框架中另一个重要的对象,它是应用程序与持久层之间执行交互操作的一个单线程对象,主要作用是执行持久化操作,类似于JDBC中Connection。SqlSession对象包含了执行SQL操作的方法,由于其底层封装了JDBC连接,所以可以直接使用SqlSession对象来执行已映射的SQL语句。
二、Mybatis核心配置文件及其元素
(1)Mybatis核心配置文件的主要元素
:红框为学习重点
其他:<configuration>元素是整个核心配置文件的根元素,核心配置就是通过<configuration>下的子元素完成的。需要注意的是,在核心配置文件中,<configuration>下的子元素必须按上图由上到下的顺序进行配置!不然会报错
(2)<properties>元素
作用:读取外部文件的配置信息
假设现有一个配置文件jdbc.properties,该文件配置了数据库的连接信息,具体如下:
mysql.driver=com.mysql.jdbc.Driver
mysql.username=root
mysql.password=123456
mysql.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false
在Mybatis的核心配置文件中引入
<!--引入外部jdbc.properties-->
<properties resource="jdbc.properties"></properties>
动态获取jdbc.properties文件中的数据库连接信息(运用:${})
<property name="driver" value="${mysql.driver}"/>
${mysql.driver}=com.mysql.jdbc.Driver
(3)<settings>元素
常见的配置参数
应用背景1:在数据库中命名规范为user_name,java中为驼峰命名userName,由于两者的名称不一致,会导致查询结果中,userName的结果为空(其他还是都有的)
<settings>
<!--开启全局缓存 默认true-->
<setting name="cacheEnabled" value="true"/>
<!--开启全局懒加载 默认false-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--开启 关联属性的懒加载,默认false-->
<setting name="aggressiveLazyLoading" value="true"/>
<!--开启驼峰映射-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
配置<setting name="mapUnderscoreToCamelCase" value="true"/>后userName就可以正常拿到
(4)<typeAliases>元素
为全路径起别名
(5)<environments>元素
可以配置多套运行环境,但不管配置几个环境,都需要根据当前情况选出一个唯一的运行环境
实例:
<transactionManager>元素
:在Spring+Mybatis时,MyBatis不需要配置事物管理器,而使用Spring的事物管理器
<dataSource>元素
Mybatis提供了UNPOOLED、POOLED和JNDI三种数据源类型
UNPOOLED:无连接池类型,程序每次被请求都会打开、关闭数据库连接。适用于对性能要求不高的简单应用程序,使用UNPOOLED类型的数据源需配置5种属性。
POOLED:连接池类型,利用“池”的概念将JDBC连接对象组织起来,节省了在创建新的连接对象时需要初始化和认证的时间。POOLED数据源使得并发Web应用可以快速的响应请求,是当前比较流行的数据源配置类型。
JNDI:数据源可在EJB或者应用服务器等容器中使用
在测试类中确认唯一环境
//默认的环境
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//指定的环境,假设指定的id=test
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is,test);
(6)<mappers>元素
<mappers>元素引入Mybatis映射文件的四种方法:
:使用本地路径引入不常见
使用前提:1,mapper映射文件的路径=位置+映射包文件名
2,映射文件的位置必须放在接口的同包目录下
3,映射文件必须与接口同名
使用前提:和方式三一致
适用于引入多个100个映射文件
三、MyBatis映射文件及其元素
1,映射文件中的常见元素
2,<mapper>元素
(1)namespace属性
在不同的映射文件中<mapper>元素的子元素id可以相同,Mybatis会通过mapper元素的namespace属性值去区分同id的.xml文件
3,<select>元素
作用:映射查询语句,可以从数据库中查询数据并返回
常见属性:
实例:
<!--
select:查询的statement(声明),用来编写查询语句
id:语句的唯一标识
resultType:配置返回的结果集类型,和resultMap必须要有一个,必须要有返回值
parameterType:传递的参数类型,看看需不需要传递参数,不需要可以省略
-->
<select id="findById" parameterType="int" resultType="homework4.dao.User">
select * from users where uid = #{id}
</select>
4,<insert>元素
(1)插入代码
(2)获取主键值
i.自增长的主键
useGeneratedKeys="true"开启主键回写
keyProperty="uid"要回写列
配置后调用user.getUid()函数就会返回对应的值,而不是默认的0.
ii.非自增长的主键
5,<delete>元素
执行删除操作
6,<update>元素
执行更新操作
7,<sql>元素
8,<resultMap>元素
四、完整测试内容
1,UserDao接口
public interface UserDao {
public User findById(int id);
public void addUser(User u);
public void updateUser(User u);
public void deleteUser(int id);
}
2,mybatis-config核心配置文件
<?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>
<!--引入外部jdbc.properties-->
<properties resource="jdbc.properties"></properties>
<settings>
<!--开启全局缓存 默认true-->
<setting name="cacheEnabled" value="true"/>
<!--开启全局懒加载 默认false-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--开启 关联属性的懒加载,默认false-->
<setting name="aggressiveLazyLoading" value="true"/>
<!--开启驼峰映射-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--配置xxxMapper.xml的文件位置-->
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
附jdbc.properties
mysql.driver=com.mysql.jdbc.Driver
mysql.username=root
mysql.password=mima
mysql.url=jdbc:mysql://localhost:3307/mybatis?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false
3,UserMapper.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:名称空间,由于映射文件可能有多个,为了防止crud语句的唯一标识被重复,需要设置空间名称
* 接口式开发
* 1,方法的名称需要保证和映射文件中的sql语句的statmentId一致
* 2,namespace的值必须是接口的全路径
*
-->
<mapper namespace="homework4.dao.UserDao">
<!--
select:查询的statement(声明),用来编写查询语句
id:语句的唯一标识
resultType:配置返回的结果集类型
parameterType:传递的参数类型,可以省略
-->
<select id="findById" parameterType="int" resultType="homework4.dao.User">
select * from users where uid = #{id}
</select>
<insert id="addUser" parameterType="homework4.dao.User">
INSERT into users(uid,uname,uage) values (#{uid},#{uname},#{uage})
</insert>
<update id="updateUser" parameterType="homework4.dao.User">
UPDATE users set uname=#{uname},uage=#{uage} where uid=#{uid}
</update>
<delete id="deleteUser" parameterType="int">
DELETE FROM users where uid=#{uid}
</delete>
</mapper>
4,UserDaoTest测试类
public class UserDaoTest extends TestCase {
UserDao userDao=null;
SqlSession sqlSession=null;
@Before
public void setUp() throws Exception {
//1,获取核心文件
//这有很多个Resources,我们选择org.apache.ibatis.io下的
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//2,创建sqlSessionFactory工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3,创建sqlSession对象
sqlSession = sqlSessionFactory.openSession();
//4,获取接口的动态代理对象
userDao = sqlSession.getMapper(UserDao.class);
//userDao = sqlSession.getMapper(UserDao.class);
}
@Test
public void testFindById() {
User user=userDao.findById(1);
System.out.println(user);
sqlSession.close();
}
@Test
public void testAddUser() {
User user=new User(3,"王五",20);
userDao.addUser(user);
//手动提交事务
sqlSession.commit();
sqlSession.close();
}
@Test
public void testUpdateUser() {
User user=new User(3,"王五",25);
userDao.updateUser(user);
sqlSession.commit();
sqlSession.close();
}
@Test
public void testDeleteUser() {
userDao.deleteUser(3);
sqlSession.commit();
sqlSession.close();
}
}