这篇文章我们学习一下Mybatis,希望大家提出宝贵的建议。
一:什么是Mybatis?
MyBatis 是一个基于Java的持久层框架。它提供的持久层框架包括SQL Maps和Data Access Objects(DAO)。
MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJO(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder从一个xml配置文件或者一个预定义的配置类的实例获得配置信息。
二:Mybatis的运行流程与原理?
我更喜欢用自己的图来表达Mybatis的整个的执行流程。如下图所示:
a.流程图
b.原理详解:
MyBatis应用程序根据XML配置文件创建SqlSessionFactory,
SqlSessionFactory在根据配置,配置来源于两个地方,一处是配置文件,一处是Java代码的注解,获取一个SqlSession。SqlSession包含了执行sql所需要的所有方法,可以通过SqlSession实例直接运行映射的sql语句,完成对数据的增删改查和事务提交等,用完之后关闭SqlSession。
c.mybatis配置详解
1、SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
2、 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
3、 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
4、 mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
5、 Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
6、 Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过 Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
7、 Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过 Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。
8、Sqlsession:对应着一次数据库会话。由于数据库回话不是永久的,因此Sqlsession的生命周期也不应该是永久的,相反,在你每次访问数据库时都需要创建它(当然并不是说在Sqlsession里只能执行一次sql,你可以执行多次,当一旦关闭了Sqlsession就需要重新创建它)。创建Sqlsession的地方只有一个,那就是SqlsessionFactory的openSession方法。
三:案例演示
例1:
1、创建User.java
private Integer id;//主键
private String username;//用户名
private String password;//密码
private String email;//邮箱
private String mobile;//手机号
private Integer age;//年龄
private String birth;//出生日期
(set,get 方法省略...........)
2、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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/test" />
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="User.xml"/>
</mappers>
</configuration>
3、User.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="User">
<!-- 按id号查询用户信息 -->
<!--
id就是statement的id
parameterType:输入参数的数据类型
resultType:输出参数的类型
#{}写什么。。如果是基本类型,可以统一用value
-->
<select id="queryById" parameterType="int" resultType="com.aiyin.mybatis01.entity.User">
select * from user where id=#{value}
</select>
<!-- 查询名字有“五”字的用户信息 -->
<select id="queryByUserName" parameterType="java.lang.String" resultType="com.aiyin.mybatis01.entity.User">
SELECT * FROM USER WHERE username like '%${value}%'
</select>
</mapper>
4、Test.java
public class TestMyBatis {
@Test
public void queryById() {
// 使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)
InputStream is = TestMyBatis.class.getClassLoader()
.getResourceAsStream("SqlMapConfig.xml");
// 构建sqlSession的工厂SqlSessionFactory
SqlSessionFactoryBuilder sessionFactory = new SqlSessionFactoryBuilder();
SqlSessionFactory sf = sessionFactory.build(is);
// 先获取SqlSession
SqlSession session = sf.openSession();
// 执行查询返回一个唯一user对象的sql
/**
* 映射sql的标识字符串, User是User.xml文件中mapper标签的namespace属性的值,
* queryById是select标签的id属性值,通过select标签的id属性值就可以找到要执行的SQL
*/
User user = session.selectOne("User.queryById", 1);
System.out.println(user);
}
@Test
public void queryByUserName() {
// 使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)
InputStream is = TestMyBatis.class.getClassLoader()
.getResourceAsStream("SqlMapConfig.xml");
// 构建sqlSession的工厂
SqlSessionFactoryBuilder sessionFactory = new SqlSessionFactoryBuilder();
SqlSessionFactory sf = sessionFactory.build(is);
// 先获取SqlSession
SqlSession session = sf.openSession();
// 执行查询返回一个唯一user对象的sql
/**
* 映射sql的标识字符串, User是User.xml文件中mapper标签的namespace属性的值,
* queryById是select标签的id属性值,通过select标签的id属性值就可以找到要执行的SQL
*/
List<User> userList = session.selectList("User.queryByUserName","刘");
System.out.println(userList);
}
queryById()方法即可查询出数据库User表中Id为1 的用户信息。
queryByUserName()方法查询出User表中姓名含有“刘”字的所有用户信息。
一个小属性
typeAiases(类型别名)
<!--
批量定义别名
name是全路径名
别名必须是类名(可以首字母小写)
-->
<!--<typeAlias type="com.aiyin.mybatis01.entity.User" alias="user"/> -->
批量指定别名 <package name="com.aiyin.mybatis.entity"/>
</typeAliases>
resultType="com.aiyin.mybatis01.entity.User"------>resultType="user"
例二:拓展带入if where等标签
<sql id="queryAllInfo">
select id,username,password,email,mobile,age,birth from user
</sql>
<!-- 查询年龄大于20,名字有'强'字的用户信息
ongl找到对应的User类中的属性 -->
<select id="queryByAge" parameterType="user" resultType="user">
<include refid="queryAllInfo"></include>
where age>#{age} and username like '%${username}%'
</select>
@Test
public void queryByAge(){
SqlSession sqlSession=TestMyBatis2.newInstance();
User user=new User();
user.setAge(25);
user.setUsername("强");
List<Regist> list= sqlSession.selectList("User.queryByAge",user);
log.debug(list);
}
下次详解:基于Mapping映射的Dao开发