Mybatis
一、mybatis介绍
mybatis是一个优秀的持久层框架,对jdbc操作数据库的过程进行封装,开发人员
只需要关注sql本身。mybatis支持普通sql查询,存储过程和高级映射。可以使用简单
的xml或注解配置,将java对象和sql映射生成最终执行的sql语句,最后由mybatis框架
执行sql并将结果映射成java对象返回。
①mybatis配置
SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
② 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
③ 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
④ mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,
一个是基本执行器、一个是缓存执行器。
⑤ Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。
mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
⑥ Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过
Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对
preparedStatement设置参数。
⑦ Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过
Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编
程中对结果的解析处理过程。
二、mybatis使用
1、简单使用
导入jar包
--mybatis--**jar
--mybatis-connector--**jar
2、编写配置文件mybatis-config.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">
<!-- 使用JDBC事物管理 -->
<transactionMannager type="JDBC"/>
<!-- 使用连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///数据库名?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property naem="password" value="123"/>
</dataSource>
</environment>
</environments>
</configuration>
3、 建表并创建对应的实体类
public class User {
private Integer id;
private String account;
private String username;
//getter/setter方法
}
4、定义sys_users表所对应的sql映射文件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">
<!-- namespace:命名空间,用于隔离sql -->
<mapper namespace="com.ztd.mybatisdemo.mapper.UserMapper">
<!-- id:sql的id -->
<!-- parameterType:声明输入参数 的类型-->
<!-- resultType:声明输出结果的类型 -->
<!-- #{}:输入参数的占位符,相当于jdbc的 ? -->
<select id="findUserById" parameterType="int" resultType="com.ztd.mybatisdemo.entity.User">
SELECT id,account,username FROM sys_users WHERE id=#{id}
</select>
</mapper>
5、在mybatis-config.xml中注册UserMapper.xml
<mappers>
<mapper resource="com/ztd/mybatisdemo/mapper/xml/UserMapper.xml"/>
</mappers>
6、测试
@Test
public void testQuery() throws IOException{
String conf = "mybatis-config.xml";
//加载mybatis的配置文件
Reader reader = Resources.getResourceAsReader(conf);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
//得到sqlSession
Sqlsession session = sqlSessionFactory.openSession();
//执行查询得到返回值
//namespace + .id
String statement = "com.ztd.mybatisdemo.mapper.UserMapper"+".findUserById";
User user = session.selectOne(statement, 2);
System.out.println(user);
session.close();
}
三、CRUD操作
Mapper文件映射接口
1、编写接口
public interface UserMapper {
void create(User user);
void update(User user);
void delete(Integer id);
User findUserById(Integer id);
}
UserMapper.xml中的namespace为接口的全路径
接口中的方法名和id必须一致
2、返回数据库生成的主键
<insert id="create" parameterType="com.ztd.mybatisdemo.entity.User">
<!-- selectKey 将数据库生成的主键返回 -->
<!-- keyColumn: 数据库表中主键对应的那一列 -->
<!-- keyProperty: 实体类中主键对应的属性 -->
<!-- order: 指定何时执行查询id的sql,
BEFORE 在执行insert语句前执行查询id的sql
AFTER 在执行insert语句后执行查询id的sql
-->
<selectKey keyColumn="id" keyProperty="id" order="AFTER" resultType="int">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO sys_users(account,username,email,create_time)
VALUES(#{account},#{username},#{email},#{createTime})
</insert>
3、 typeAlises标签
为java类型命名的一个简写名字,方便使用
<typeAliases>
<typeAlias type="com.ztd.mybatisdemo.entity.User" alias="_user"/>
</typeAliases>
对于普通的java类型,有一些内建类型别名
别名 映射的类型
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
object Object
map Map
hashmap HashMap
list List
arraylist ArrayList
collection Collection
iterator Iterator
4、sql标签
用来定义可以重用的sql代码片段,可以包含在其他语句中。
<sql id="userColumns">id,account,username,email,create_time AS createTime</sql>
<select id="findUserById" parameterType="int" resultType="_user">
SELECT <include refid="userColumns"/>
FROM sys_users WHERE id=#{id}
</select>
四、 一对一查询
1.1 嵌套查询,通过执行另外一个sql映射语句来返回预期的复杂类型
<!-- 嵌套查询:通过执行另外一个sql映射语句 -->
<select id="findTeacherById" parameterType="int" resultType="_teacher">
SELECT teacher_id AS teacherId,name FROM teachers WHERE teacher_id=#{id}
</select>
<resultMap type="_grade" id="_gradeResultMap">
<id property="gradeId" column="grade_id"/>
<result property="name" column="name"/>
<association property="teacher" column="teacher_id" javaType="_teacher"
select="findTeacherById"/>
</resultMap>
<select id="findGradeById" parameterType="int" resultMap="_gradeResultMap">
SELECT grade_id,name,teacher_id FROM grades WHERE grade_id=#{id}
</select>
1.2 嵌套结果,使用嵌套结果映射来处理复杂的联合结果的子集
<!-- 嵌套结果 -->
<resultMap type="_grade" id="_gradeResultMap">
<id property="gradeId" column="g_id"/>
<result property="name" column="g_name"/>
<association property="teacher" column="teacher_id" javaType="_teacher">
<id property="teacherId" column="teacher_id"/>
<result property="name" column="t_name"/>
</association>
</resultMap>
<select id="findGradeById" parameterType="int" resultMap="_gradeResultMap">
SELECT g.grade_id AS g_id, g.name AS g_name, g.teacher_id AS teacher_id, t.name AS t_name
FROM grades g,teachers t
WHERE g.teacher_id = t.teacher_id AND g.grade_id=#{id}
</select>
一对多查询
1.3 嵌套查询
<select id="findScoreByStudentId" parameterType="Integer" resultType="_score">
SELECT id,student_id AS studentId,subject,score,exam_date AS examDate
FROM scores WHERE student_id=#{id}
</select>
<resultMap id="_studentResultMap" type="_student">
<id property="studentId" column="student_Id"/>
<collection property="scores" javaType="ArrayList" column="student_id" ofType="_score" select="findScoreByStudentId"/>
</resultMap>
<select id="findById" parameterType="Integer" resultMap="_studentResultMap">
SELECT student_id,num,name,sex,grade
FROM students
WHERE student_id=#{id}
</select>
1.4 嵌套结果
<!-- 嵌套结果 -->
<resultMap type="_student" id="_studentResultMap">
<id property="studentId" column="st_id"/>
<result property="num" column="st_num"/>
<result property="name" column="st_name"/>
<result property="sex" column="st_sex"/>
<result property="grade" column="st_grade"/>
<collection property="scores" ofType="_score">
<id property="studentId" column="st_id"/>
<result property="id" column="sc_id"/>
<result property="subject" column="sc_subject"/>
<result property="score" column="sc_score"/>
<result property="examDate" column="sc_exam_date"/>
</collection>
</resultMap>
<select id="findById" parameterType="int" resultMap="_studentResultMap">
SELECT st.student_id AS st_id,st.num AS st_num,st.name AS st_name,st.sex AS st_sex,st.grade AS st_grade,
sc.id AS sc_id,sc.subject AS sc_subject,sc.score AS sc_score,sc.exam_date AS sc_exam_date
FROM students st,scores sc
WHERE st.student_id = sc.student_id AND sc.student_id=#{id}
</select>