java学习总结(四):MyBatis
一、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);
// 得到SqlSession
SqlSession 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() {
// 得到SqlSession
SqlSession 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 INTO
student(name,age,gender,banji_id)
VALUES
(#{name},#{age},#{gender},#{banjiId})
</insert>
<update id="update" parameterType="Student">
UPDATE
student
SET
name=#{name},
age=#{age},
gender=#{gender},
banji_id=#{banjiId}
WHERE
id=#{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 student
WHERE 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>