一、mybatis框架运行流程
POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBean。
SqlSession就是会话,类似于jdbc里面的Connection,开启了这次会话,就可以发送增删改查的操作,
直到你关闭这个会话。
SqlSessionFactory:生产SqlSession的工厂,作用就是构造返回SqlSession。
1、mybatis配置
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编程中对结果的解析处理过程。
二、mybatis学习
1.lib
2.MyBatis框架的核心配置文件
3.
Log4j: 专门用来帮助我们打印日志信息
4.封装工具类
创建Session会话
public void testselectById1() 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",1);
System.out.println(student);
}
因为每次进行增删改查操作的时候都要创建SqlSessionFactory比较麻烦 所以封装一个工具类,每次调用
public class MyBatisUtil {
private static SqlSessionFactory sqlSessionFactory;
static {
String resource = "mybatis.xml";
InputStream inputStream;
try {
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;
}
}
5.typeAliases类型别名:alias
<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="mybatis.pojo"/>
</typeAliases>
6.增删改查
首先在StudentMapper.xml中写增删改查标签,再到测试类中创建会话
①查询
--通过id查找学生信息 ,需要传一个id,paramterType:参数 resultType:返回类型
--查询所有学生的信息,不需要传参,只要返回学生信息 所以只用resultType
<!-- 通过id查找学生 -->
<select id="selectById" parameterType="Integer" resultType="Student">
select id,name,age,gender,banji_id from student where id=#{id}
</select>
<select id="selectAll" resultType="Student">
select <include refid="studentColumns"/>
from student
</select>
在测试类测试
@Test
public void testselectById(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
Student student = sqlSession.selectOne("student.selectById",1);
System.out.println(student);
}
@Test
public void testselectAll(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
List<Student> list = sqlSession.selectList("student.selectAll");
for (Student student : list) {
System.out.println(student);
}
}
②删除
<delete id="deleteById" parameterType="Integer" >
delete from student where id=#{id}
</delete>
------------------------------------------------------
@Test
public void testdeleteById(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
int count = sqlSession.delete("student.deleteById",27);
sqlSession.commit();
sqlSession.close();
System.out.println(count);
}
③添加
<insert id="add" parameterType="Student">
insert into student(name,age,gender,banji_id) values(#{name},#{age},#{gender},#{banjiId})
</insert>
-----------------------------------------------------------------------------------
@Test
public void testadd(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
Student student = new Student();
student.setName("老谢");
student.setAge(21);
student.setGender("女");
student.setBanjiId(1);
int count = sqlSession.insert("student.add",student);
sqlSession.commit();
sqlSession.close();
System.out.println(count);
}
④更新
<update id="updateById" parameterType="Student">
update student set name=#{name},age=#{age},gender=#{gender},banji_id=#{banjiId} where id=#{id}
</update>
-------------------------------------------------------------------------------------------
@Test
public void testUpdate(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
Student student = new Student();
student.setId(28);
student.setName("小谢");
student.setAge(22);
student.setGender("女");
student.setBanjiId(2);
int count = sqlSession.update("student.updateById",student);
sqlSession.commit();
sqlSession.close();
System.out.println(count);
}
7.Sql片段
Sql中可以将重复代码提取出来,使用include引用,达到sql重用的目的。
将id,name,age,gender,banji_id 写为 studentColumns
<sql id="studentColums">
id,name,age,gender,banji_id
</sql>
在代码实现中
<!-- 通过id查找学生 refid reference-->
<select id="selectById" parameterType="Integer"
resultType="Student">
select <include refid="studentColums"/> from student where id=#{id}
</select>
8.输入映射和输出映射总结
输入映射:
parameterType(输入类型)
1、传递简单类型:selectById(Integer id)
使用时候#{id}
2、传递实体类:add(Student student)
使用时候#{age}括号中的值为实体类中属性的名字。
3、传递Map(传递过个参数)
<select id="selectByPage" parameterType="Map" resultType="Student">
SELECT <include refid="studentColumns"/> FROM `student` LIMIT #{offset},#{pageSize}
</select>
------------------------------------------------------------------------------------------
@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);
}
}
输出映射:
1、基本数据类型:
查找一共有多少学生
2、输出实体类:Student
3、输出集合:List<Student>
<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);
}
9.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>