文章目录
前言
推荐详细内容:点击打开
文档地址:点击打开
源码地址:点击打开
MyBatis安装
方式一:jar包安装
只需将 mybatis-x.x.x.jar 文件置于类路径(classpath)中,Build
方式二:Maven安装
使用 Maven 来构建项目,则需将下面的依赖代码置于 pom.xml 文件中:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>x.x.x</version> //版本号
</dependency>
MyBatis XML 全局配置
1、属性properties
配置属性:
<properties resource="org/mybatis/example/MybatisConfig.properties">
<property name="username" value="张三"/>
<property name="password" value="123456"/>
</properties>
上面的代码示例中:
resource="org/mybatis/example/MybatisConfig.properties -------是使用外部属性资源全路径
property name=“username” value=“张三” ---------内部xml属性
在dataSource 元素中使用配置属性:
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
以上例子中的${},将会用配置数据properties中的属性元素来替换。
${driver} 与 ${url} 使用的是外部属性资源的属性
${username} 与 ${password} 使用的是XML全局配置的属性
2、设置 Settings
<settings>
<!-- 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 -->
<setting name="cacheEnabled" value="true"/>
<!-- 延迟加载的全局开关。 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 是否允许单个语句返回多结果集(需要数据库驱动支持)。-->
<setting name="multipleResultSetsEnabled" value="true"/>
<!-- 使用列标签代替列名。-->
<setting name="useColumnLabel" value="true"/>
<!-- 如果设置为 true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作(如 Derby)。-->
<setting name="useGeneratedKeys" value="false"/>
<!-- 指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示关闭自动映射;PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 FULL 会自动映射任何复杂的结果集(无论是否嵌套)-->
<setting name="autoMappingBehavior" value="PARTIAL"/>
<!-- 指定发现自动映射目标未知列(或未知属性类型)的行为。
NONE: 不做任何反应
WARNING: 输出警告日志('org.apache.ibatis.session.AutoMappingUnknownColumnBehavior' 的日志等级必须设置为 WARN)
FAILING: 映射失败 (抛出 SqlSessionException)-->
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<!-- 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(PreparedStatement); BATCH 执行器不仅重用语句还会执行批量更新。-->
<setting name="defaultExecutorType" value="SIMPLE"/>
<!-- 设置超时时间,它决定数据库驱动等待数据库响应的秒数。-->
<setting name="defaultStatementTimeout" value="25"/>
<!--为驱动的结果集获取数量(fetchSize)设置一个建议值。此参数只可以在查询设置中被覆盖。-->
<setting name="defaultFetchSize" value="100"/>
<!--是否允许在嵌套语句中使用分页(RowBounds)。如果允许使用则设置为 false。-->
<setting name="safeRowBoundsEnabled" value="false"/>
<!--是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。-->
<setting name="mapUnderscoreToCamelCase" value="false"/>
<!-- MyBatis 利用本地缓存机制(Local Cache)防止循环引用和加速重复的嵌套查询。 默认值为 SESSION,会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地缓存将仅用于执行语句,对相同 SqlSession 的不同查询将不会进行缓存。-->
<setting name="localCacheScope" value="SESSION"/>
<!-- 当没有为参数指定特定的 JDBC 类型时,空值的默认 JDBC 类型。 某些数据库驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。-->
<setting name="jdbcTypeForNull" value="OTHER"/>
<!-- 指定对象的哪些方法触发一次延迟加载。-->
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>
3、类型别名typeAliases
类型别名可为 Java 类型设置一个缩写名字,它仅用于 XML 配置。
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
<typeAlias alias="Comment" type="domain.blog.Comment"/>
<typeAlias alias="Post" type="domain.blog.Post"/>
<typeAlias alias="Section" type="domain.blog.Section"/>
<typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>
4、mappers 映射器
mapper文件名与mapperXML
<!-- 批量注册映射文件 -->
<mappers>
<!-- 方式一:resource 属性 -->
<!-- <mapper resource="com/servlet/demo/mapper/EmployeeMapper.xml"></mapper>-->
<!-- 方式二:class 属性 -->
<!-- <mapper class="com.servlet.demo.mapper.EmployeeMapper"></mapper>-->
<!-- 方式三:package 标签 -->
<package name="com.servlet.demo.mapper"/>
</mappers>
方式二、三 注意点:
- 必须处于同一级 package 下
- 必须与Mapper类同名
XML 映射元素
SQL 映射文件只有很少的几个顶级元素:
- cache – 该命名空间的缓存配置。
- cache-ref – 引用其它命名空间的缓存配置。
- resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。
- sql – 可被其它语句引用的可重用语句块。
- insert – 映射插入语句。
- update – 映射更新语句。
- delete – 映射删除语句。
- select – 映射查询语句。
select
这个语句名为 selectPerson(对应接口mapper文件名),接受一个 int(或 Integer)类型的参数,并返回一个 HashMap 类型的对象(其中的键是列名,值便是结果行中的对应值)。
<select id="selectPerson" parameterType="int" resultType="hashmap">
SELECT * FROM PERSON WHERE ID = #{id}
</select>
insert, update 和 delete
<insert id="insertAuthor">
insert into Author (id,username,password,email,bio)
values (#{id},#{username},#{password},#{email},#{bio})
</insert>
<update id="updateAuthor">
update Author set
username = #{username},
password = #{password},
email = #{email},
bio = #{bio}
where id = #{id}
</update>
<delete id="deleteAuthor">
delete from Author where id = #{id}
</delete>
主键自动递增 useGeneratedKeys=“true” keyProperty=“id”
<insert id="insertUser" parameterType="com.example.entity.User" useGeneratedKeys="true" keyProperty="id">
insert into user(name,email,gender,birth) values (#{name},#{email},#{gender},#{birth})
</insert>
${}字符串替换
<select id="selectByColumn" resultType="com.example.entity.User" parameterType="java.lang.String">
-- ${} 字符串替换, #{}参数占位符
select * from user where ${column}=#{value}
</select>
sql
这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用
association 与 collection
1、关联-association 集合-collection
2、所以association是用于一对一和多对一,而collection是用于一对多的关系
3、JavaType和ofType都是用来指定对象类型的
- JavaType是用来指定pojo中属性的类型
- ofType指定的是映射到list集合属性中pojo的类型。
<select id="selectUserAndDeptmet" resultMap="UserAndDeptmet">
select u.id as 用户ID,
u.name as 用户名,
gender,
email,
birth,
d.address ,
d.dp_Id ,
d.dp_name
from user u join dept_ment d on u.deptid=d.dp_id
</select>
<resultMap id="UserAndDeptmet" type="com.example.entity.User">
<id property="id" column="用户ID"></id>
<result property="name" column="用户名"></result>
<result property="gender" column="gender"></result>
<result property="email" column="email"></result>
<result property="birth" column="birth"></result>
<association property="deptMent" javaType="com.example.entity.DeptMent">
<id property="dpId" column="dp_id"></id>
<result property="dpName" column="dp_name"></result>
<result property="address" column="address"></result>
</association>
</resultMap>
动态SQL
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
if
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
choose、when、otherwise(类似switch)
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
以上,如果条件不成立会输出:
SELECT * FROM BLOG
WHERE
SELECT * FROM BLOG WHERE
AND title like ‘someTitle
解决where 条件全不成立的有效解决办法,where 1=1
JAVA API
SqlSession
使用 MyBatis 的主要 Java 接口就是 SqlSession。SqlSessions 是由 SqlSessionFactory 实例创建的。 SqlSessionFactory 是由 SqlSessionFactoryBuilder 创建的,它可以从 XML、注解或 Java 配置代码来创建 SqlSessionFactory
SqlSessionFactory 实例创建:
//------------------第一步:读取全局配置文件------------------------------
String resource = "org/mybatis/builder/mybatis-config.xml";
//读取mybatis-config.xml配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//通过SqlSessionFactoryBuilder 创建 SqlSessionFactory
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//初始化mybatis,创建SqlSessionFactory类的实例
SqlSessionFactory sqlSessionFactory = builder.build(inputStream);
//------------------第二步:创建session实例------------------------------
//创建session实例
SqlSession session = sqlSessionFactory.openSession();
/*
* 接下来在这里做很多事情,到目前为止,目的已经达到得到了SqlSession对象.通过调用SqlSession里面的方法,
* 可以测试MyBatis和Dao层接口方法之间的正确性,当然也可以做别的很多事情,在这里就不列举了
*/
//------------------第二步:使用session 使用操作数据库------------------------------
//插入数据
User user = new User();
user.setC_password("123");
user.setC_username("123");
user.setC_salt("123");
//第一个参数为方法的完全限定名:位置信息+映射文件当中的id
session.insert("com.cn.dao.UserMapping.insertUserInformation", user);
//提交事务
session.commit();
//关闭session
session.close();
测试
POJO 实体
//Teacher 类
public class Teacher {
private int id;
private String name;
}
//Student 类
public class Student {
private int id;
private String name;
//多个学生可以是同一个老师,即多对一
private Teacher teacher;
}
多对一的理解:
- 多个学生对应一个老师
- 如果对于学生这边,就是一个多对一的现象,即从学生这边关联一个老师!
** mapper 接口**
//获取所有学生及对应老师的信息
public List<Student> getStudents();
** xml 配置文件 **
<select id="getStudents2" resultMap="StudentTeacher2" >
select s.id sid, s.name sname , t.name tname
from student s,teacher t
where s.tid = t.id
</select>
<resultMap id="StudentTeacher2" type="Student">
<id property="id" column="sid"/>
<result property="name" column="sname"/>
<!--关联对象property 关联对象在Student实体类中的属性-->
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
测试
@Test
public void testGetStudents(){
SqlSession session = MybatisUtils.getSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
List<Student> students = mapper.getStudents();
for (Student student : students){
System.out.println(
"学生名:"+ student.getName()
+"\t老师:"+student.getTeacher().getName());
}
}
一对多的理解:
- 一个老师拥有多个学生
- 如果对于老师这边,就是一个一对多的现象。
** mapper 接口**
//获取指定老师,及老师下的所有学生
public Teacher getTeacher(int id);
** xml 配置文件 **
<mapper namespace="com.ttt.mapper.TeacherMapper">
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid, s.name sname , t.name tname, t.id tid
from student s,teacher t
where s.tid = t.id and t.id=#{id}
</select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="name" column="tname"/>
<collection property="students" ofType="Student">
<result property="id" column="sid" />
<result property="name" column="sname" />
<result property="tid" column="tid" />
</collection>
</resultMap>
</mapper>
测试
@Test
public void testGetTeacher2(){
SqlSession session = MybatisUtils.getSession();
TeacherMapper mapper = session.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher2(1);
System.out.println(teacher.getName());
System.out.println(teacher.getStudents());
}