一、MyBatis介绍
像MyBatis、Hibernate都是属于ORM框架
对象关系映射(英语:(Object Relational Mapping,简称ORM)
MySql、Oracle、SqlServer都是关系型数据库
1、O->R add/insert/save
studentDao.insert(student)
把一个java对象保存到数据库中的一行记录
2、R->O selectById/findById/listById
Student student = sudentDao.findById(id)
把数据库里面的一行记录封装成一个java对象
二、MyBatis执行流程
MappedStatement是MyBatis框架中的一个重要类,用于表示映射配置文件(Mapper XML文件)中的SQL语句。在MyBatis中,每个SQL语句都会被解析成一个MappedStatement对象,它包含了SQL语句的相关信息,如ID、参数映射、结果映射、SQL语句类型等。
<select id="selectAll" resultType="Student">SELECT id, name, age, gender, banji_id FROM student
</select>
、读取MyBatis配置文件:mybatis-config.xml加载运行环境和映射文件
2、构造会话工厂SqlSessionFactory
3、会话工厂创建SqlSession对象(包含了执行SQL语句的所有方法)
4、操作数据库的接口,Executor执行器,同时负责查询缓存的维护
5、Executor接口的执行方法中有一个MappedStatement类型的参数,封装了映射信息
6、输入参数映射(Java类型转换为数据库支持的类型)
7、输出结果映射(数据库类型转化为Java类型)
三、MyBatis快速入门
@Test
public void testSelectById() throws IOException {String resource = "mybatis.xml";InputStream inputStream = Resources.getResourceAsStream(resource);// 创建 SqlSessionFactory Session:会话 (连接数据库后就建立了一次会话,有了会话就可以操作数据库)SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 得到SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 执行sql语句Student student = sqlSession.selectOne("student.selectById", 59);System.out.println(student);
}
四、封装工具类
public class MyBatisUtil {private static SqlSessionFactory sqlSessionFactory;//静态代码块中的代码只会执行一次static {try {String resource = "mybatis.xml";InputStream inputStream;inputStream = Resources.getResourceAsStream(resource);// 创建 SqlSessionFactory Session:会话 (连接数据库后就建立了一次会话,有了会话就可以操作数据库)sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);} catch (IOException e) {e.printStackTrace();}}public static SqlSession getSqlSession() {// 得到SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();return sqlSession;}
}@Test
public void testSelectById1() throws IOException {SqlSession sqlSession = MyBatisUtil.getSqlSession();// 执行sql语句Student student = sqlSession.selectOne("student.selectById", 66);System.out.println(student);
}
五、typeAliases类型别名
上图是mybatis3.3.0官方文档上提供的别名和java类型的映射关系
int/Integer/ineger
在配置int时通过上表可以看出,即可以是java中的基本类型int,也可以是java中的包装类型Integer,不过在配置为包装类型是必须是java.lang.Integer,所以在配置为int是我们的java接口中的参数类型最好是Integer的。
string/String :对应java中的java.lang.String
map :对应java.util.Map
hashmap :对应java.util.HashMap
list :对应java.util.List
arraylist :对应java.util.ArrayList
<settings><!-- 下划线字段对应实体类驼峰命名 数据库表:banji_id 映射到类里面:banjiId --><setting name="mapUnderscoreToCamelCase" value="true"/>
</settings><typeAliases><!--<typeAlias alias="Student" type="com.situ.mybatis.pojo.Student"/><typeAlias alias="Banji" type="com.situ.mybatis.pojo.Banji"/> --><!-- 扫描包里面的类,批量起别名,别名即类名,不区分大小写 --><package name="com.situ.mybatis.pojo"/>
</typeAliases>
六、基本增删改查的操作
<mapper namespace="student"><!-- public Student selectById(Integer id) {}parameterType="java.lang.Integer"resultType="com.situ.mybatis.pojo.Student"--><select id="selectById" parameterType="Integer" resultType="Student">SELECT id,name,age,gender,banji_id FROM student where id=#{id}</select><!--public List<Student> selectAll();--><select id="selectAll" resultType="Student">SELECT id,name,age,gender,banji_id FROM student</select><!-- 对于更新类的操作返回的是影响的行数,但是resultType不需要写public int deleteById(Integer id)更新类返回影响的行数,在这里不用写返回值类型--><delete id="deleteById" parameterType="Integer">DELETE FROM student WHERE id=#{id}</delete><!--public int add(Student student)--><insert id="add" parameterType="Student" useGeneratedKeys="true" keyProperty="id">INSERT INTOstudent(name,age,gender,banji_id)VALUES(#{name},#{age},#{gender},#{banjiId})</insert><update id="update" parameterType="Student">UPDATEstudentSETname=#{name},age=#{age},gender=#{gender},banji_id=#{banjiId}WHEREid=#{id}</update>
</mapper>
@Test
public void testDeleteById() throws IOException {// Setting autocommit to false on JDBC Connection// JDBC默认autocommit值是true,MyBatis把JDBC的autocommit设置为false,// 当执行delete的时候并没有真正提交到数据库,对于更新类的操作需要手动提交。// 在JDBC里面默认不需要用户手动提交因为autocommit 默认就是true,执行executeUpdate// 的时候直接修改了数据库SqlSession sqlSession = MyBatisUtil.getSqlSession();int count = sqlSession.delete("student.deleteById", 59);System.out.println("count: " + count);// 对于更新类的操作需要手动提交sqlSession.commit();sqlSession.close();
}
七、Sql片段
<sql id="studentColumns">id,name,age,gender,banji_id
</sql><!-- 通过id查找学生 refid reference-->
<select id="selectById" parameterType="Integer" resultType="Student">SELECT <include refid="studentColumns"/>FROM studentWHERE id = #{id}
</select>
八、输入映射
- 传递简单类型:selectById(Integer id)
- 传递实体类:add(Student student)
- 传递Map(传递过个参数)
@Test
public void testSelectByPage() throws IOException {SqlSession sqlSession = MyBatisUtil.getSqlSession();int pageNo = 2;int pageSize = 3;int offset = (pageNo - 1) * pageSize;Map<String, Integer> map = new HashMap<String, Integer>();map.put("offset", offset);map.put("pageSize", pageSize);List<Student> list = sqlSession.selectList("student.selectByPage", map);for (Student student : list) {System.out.println(student);}
}
<select id="selectByPage" parameterType="Map" resultType="Student">SELECT <include refid="studentColumns"/> FROM student LIMIT #{offset},#{pageSize}
</select>
九、输出映射
1、基本数据类型:
查找一共有多少学生
<select id="selectTotalCount" resultType="Integer">SELECT count(*) FROM student
</select>@Test
public void testSelectTotalCount() throws IOException {SqlSession sqlSession = MyBatisUtil.getSqlSession();int count = sqlSession.selectOne("student.selectTotalCount");System.out.println("count: " + count);
}
2、输出实体类:Student
3、输出集合:List
resultMap
如果查询出来的列名和实体类的属性不一致,通过定义一个resultMap对列名和实体类属性名做一个映射关系。
resultMap 元素是 MyBatis 中最重要最强大的元素。
结果集的映射是 MyBatis 最强大的特性,对其有一个很好的理解的话,许多复杂映射的情形都能迎刃而解。使用 resultMap 或 resultType,但不能同时使用。
<!-- resultMap最终是要将结果映射到Student上
当实体类的属性名和表的字段名不一致的时候,必须要写这个映射 -->
<resultMap type="Student" id="studentMap"><!-- 映射主键属性:如果有多个主键字段,则定义多个id --><!-- property:类的属性名 --><!-- column:表的字段名 --><id column="id" property="id" /><!-- result定义普通属性 --><result column="student_name" property="name" /><result column="age" property="age" /><result column="gender" property="gender" />
</resultMap><select id="selectAll" resultMap="studentMap">select id,student_name,age,gender from student
</select>