Mybatis全面学习资料:
mybatis是什么:
更加简化jdbc代码,简化持久层,sql语句从代码中分离,利用反射,将表中数据与java bean 属性一一映射 即 ORM(Object Relational Mapping 对象关系映射)。
特点:
半自动化:
-
表需要手动进行设计
-
提供sql
-
依赖与数据库平台
-
优点:学习使用简单(基于原生jdbc封装),优化灵活,适合做互联网项目
mybatis环境搭建(导入jar包):(连接oracle数据库)
官网: https://mybatis.org/mybatis-3/zh/index.html
导包
需要导数据库驱动ojdbc6的包,mybatis的包,以及mybatis用到的包
核心配置文件:
<?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="myOracle">
<environment id="myOracle">
<transactionManager type="JDBC"/>
<!--数据库连接池-->
<dataSource type="POOLED">
<!--连接信息-->
<property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
<property name="username" value="SCOTT"/>
<property name="password" value="TIGER"/>
</dataSource>
</environment>
</environments>
<!--sql映射文件-->
<mappers>
<mapper resource="com/shsxt/mappers/user.xml"/>
</mappers>
</configuration>
mybatis sql映射文件:
<?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">
<mapper namespace="com.shsxt.mappers.user">
<select id="findAll" resultType="com.shsxt.pojo.User">
select * from usertest
</select>
</mapper>
测试:
public static void main(String[] args) throws IOException {
//加载主配置文件
InputStream in = Resources.getResourceAsStream("mybatis.xml");
//得到工厂对象
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//得到SqlSession对象
SqlSession session = factory.openSession();
//调用方法
List<String> list = session.selectList("com.shsxt.mappers.user.findUname");
list.forEach(System.out::println);
//关闭资源
session.close();
}
三种查询方式:
selectList("命名空间.id");
selectList("命名空间.id",Object obj);//Object obj为传入参数
selectOne("命名空间.id");
selectOne("命名空间.id",Object obj);//Object obj为传入参数
selectMap("命名空间.id",key的字段名);
selectMap("命名空间.id",key的字段名,Object obj);//Object obj为传入参数
主配置文件:
<!ELEMENT configuration (properties?,
settings?,
typeAliases?,
typeHandlers?,
objectFactory?,
objectWrapperFactory?,
reflectorFactory?,
plugins?,
environments?,
databaseIdProvider?,
mappers?)>
对连接数据库的操作进行软编码:
<properties resource="db.properties"></properties>//导入外部db.properties文件,实现软编码
<environments default="myOracle">
<environment id="myOracle">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
设置类的别名:
<typeAliases>
<!--com.shsxt.pojo下面的Emp类的别名为e,大小写不敏感-->
<typeAlias type="com.shsxt.pojo.Emp" alias="e"></typeAlias>
<!--没有给alias属性,默认别名为类名,大小写不敏感-->
<typeAlias type="com.shsxt.pojo.Emp"></typeAlias>
<!--整个pojo包下面的类都设置别名,别名为类名,大小写不敏感-->
<package name="com.shsxt.pojo"/>
</typeAliases>
Mybatis自带映射关系:
别名 | *映射的类型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
---|---|
long | Long |
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 |
<mapper namespace="com.shsxt.mappers.GoodsMapper">
sql映射文件xml利用根标签namespace的值进行标识,
DML语句分析:
例select语句:
<select id="find" resultType="" parameterType="" >
select * from tablename
</select>
id为方法的唯一标识
resultType返回结果类型
parameterType 传入参数类型
默认增删改返回值都是 影响行数
如果执行的是条件查询,DML,需要在调用方法的时候传递参数,此时, 可以在sql标签中通过parameterType属性指定参数的类型(别名|权限定名).在sql语句,通过#{}的方式获取参数。
parameterType入参类型:
parameterType: 基本数据类型(四类八种) 包装类 String, Date, Javabean,Map ,List ,数组 …
入参类型为List,数组是需用使用到foreach
foreach遍历参数list或者数组:
collection=“array” 参数类型 array | list
item : 指代每次循环从集合或者数组中拿出的数据(变量名)
separator: 每个数据之间额分隔符
open: 所有遍历输出的的数据之前以什么内容开始
close : 所有遍历输出的的数最后以什么结束
resultType结果类型:
基本数据类型(包装类) String, Date, JavaBean, List ,Map ,List-Map List
**接口绑定方案:
实现方式:
定义接口:
/*
* 接口定义了对用户的操作
*/
public interface UserMapper {
//查询所有用户
public List<User> queryAll();
}
映射文件:
1.xml文件名要与接口名保持一致
2.namespace属性值必须与接口的全限定名相同
3.语句的id属性必须要与抽象方法名保持一致
4.返回值类型和参数类型与方法的返回值和参数保持一致
<?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: 对应的接口的权限定名相同 -->
<mapper namespace ="com.shsxt.mapper.UserMapper">
<!-- id 与 方法名一致 -->
<select id="queryAll" resultType="User">
select * from t_user
</select>
</mapper>
在核心配置文件中扫描接口:
三种方式:
<!--sql映射文件-->
<mappers>
//扫描单个xml文件
<!-- <mapper class="com.shsxt.mappers.GoodsMapper"></mapper>-->
<!-- <mapper resource="com/shsxt/mappers/GoodsMapper.xml"/>-->
//扫描包下所有xml文件
<package name="com.shsxt.mappers"/>
</mappers>
使用:
/** 测试接口绑定 */
@Test
public void test(){
SqlSession session = MybatisUtils.getSession();
//getMapper()获取接口实现类对象,参数为接口的class对象,通 过参数指定接口
UserMapper mapper =session.getMapper(UserMapper.class);
//通过对象调用方法
List<User> list = mapper.queryAll();
System.out.println(list); session.close();
}
通过接口绑定解决多参数传递问题 :
方式一:
接口定义方法
User selByUP(String username, String password);
映射文件中提供对应的标签. 此时, SQL 语句中获取方式有两种, 通过#{arg+数字},从arg0开始,或#{param+数字},从param1开始,的方式.
<select id="selByUP" resultType="user">
select * from t_user where username=#{param1} and
password=#{param2}
</select>
方式二:
接口中定义方法, 参数中使用@Param 注解设定参数名用于在 SQL 语
句中使用。
接口中:
public List<Emp> findbyDeptno(@Param("deptno1") int deptno1,@Param("deptno2") int deptno2);
映射文件中提供对应的标签. 此时, SQL 语句中获取方式有两种, 通过
#{参数名称}或#{param+数字}的方式.
<select id="findbyDeptno" resultType="E">
select * from emp where deptno in (#{deptno1},#{deptno2})
</select>
批量操作:
批量新增:
插入时使用insert into table select 值1,值2 from dual union select 值1‘,值2’ from dual…
接口中:
public Integer insertDeptMore(List<Dept> depts);
xml文件中:
<!--批量插入-->
<insert id="insertDeptMore">
insert into dept
<foreach collection="list" item="item" separator="union">
select #{item.deptno},#{item.dname},#{item.loc} from dual
</foreach>
</insert>
批量修改:
update table set 字段1=? where 字段2=?…foreach循环操作
begin
end;
接口中:
public Integer updateDeptMore(List<Dept>depts);
xml文件中:
<!--批量更新-->
<update id="updateDeptMore">
<foreach collection="list" item="item" separator=";" open="begin" close=";end;">
update dept set loc=#{item.loc} where deptno=#{item.deptno}
</foreach>
</update>
批量删除:
delete table where 字段 in(foreach)
接口中:
public Integer deleteDeptMore(int[]deptno);
xml文件中:
<!--批量删除-->
<delete id="deleteDeptMore">
delete dept where deptno in(
<foreach collection="array" item="item" separator=",">
#{item}
</foreach>
)
</delete>
动态SQL:
if:
用于进行条件判断, test 属性用于指定判断条件. 为了拼接条件, 在 SQL 语句后强行添加 1=1 的恒成立条件。
<select id="sel" resultType="user">
select * from t_user where 1=1
<if test="username != null and username != ''">
and username=#{username} </if>
<if test="password != null and password != ''">
and password=#{password} </if>
</select>
select * from emp
<where>
<if test="ename!=null and ename !=''">
and ename=#{ename}
</if>
<if test="deptno!=0 and ename !=''">
and deptno=#{deptno}
</if>
</where>
where标签:
-
如果没有条件, 不会生成 where 关键字
-
如果有条件, 会自动添加 where 关键字
-
如果第一个条件中有 and, 去除之
select * from emp
<where>
<if test="ename!=null and ename !=''">
and ename=#{ename}
</if>
<if test="deptno!=0 and ename !=''">
and deptno=#{deptno}
</if>
</where>
choose…when…otherwise标签:
相当于java语言中的switch …case…default,when标签自带break
select * from emp
<where>
<choose>
<when test="ename!=null and deptno!=''" >
ename=#{ename}
</when>
<when test="deptno!=0 and deptno!=''">
deptno=#{deptno}
</when>
<otherwise></otherwise>
</choose>
</where>
set:
常用于更新语句中.
-
满足条件时, 会自动添加 set 关键字
-
会去除 set 子句中多余的逗号
-
不满足条件时, 不会生成 set 关键字
update emp
<set>
<if test="ename!=null and ename!=''" >
ename=#{ename},
</if>
<if test="deptno!=0 and deptno!=''">
deptno=#{deptno},
</if>
empno=#{empno}
</set>
where empno=#{empno}
trim:
-
prefix, 在前面添加内容
-
prefixOverrides, 从前面去除内容
-
suwix, 向后面添加内容
-
suwixOverrides, 从后面去除内容
<select id="findTrim" resultType="Student"> select * from student <trim prefix="where" prefixOverrides="jkl" suffix="and 1=1" suffixOverrides="opo"> jkl <if test="sname!=null and sname !=''"> and sanme=#{sname} </if> opo </trim> </select>
bind:
用来进行模糊查询。
<select id="findByName" parameterType="String" resultType="Student">
select * from student
<where>
<if test="sname!=null and sname!=''">
<bind name="sname" value="'%'+sname+'%'"/>
sname like #{sname}
</if>
</where>
</select>
foreach:
-
collection: 待遍历的集合
-
open: 设置开始符号
-
item: 迭代变量
-
separator: 项目分隔符
-
close: 设置结束符
select * from student where id in(
<foreach collection="list" item="item" separator="," >
#{item}
</foreach>
)
sql…include:
用于提取SQL语句的。
<sql id="haha">sid,sname,s.cid,cname</sql>
<select id="findAll" resultMap="student_map">
select <include refid="haha"/> from student s join clazz c on s.cid=c.cid
</select>
Mybatis缓存机制:
一级缓存:
在SqlSession生命周期中有效,
线程级别的缓存。
SqlSession关闭,缓存清空
在同一个 SqlSession 中, Mybatis 会把执行的方法和参数通过算法生成缓存的键值, 将键值和结果存放在一个 Map 中, 如果后续的键值一样, 直接从 Map中获取数据;
不同的 SqlSession 之间的缓存是相互隔离的;任何的 UPDATE, INSERT, DELETE 语句都会清空缓存。
用一个 SqlSession, 可以通过配置使得在查询前清空缓存flushCache=“true”
session.clearCache(); //session缓存刷新
<select id="testFind" resultType="com.shsxt.pojo.Emp" flushCache="true"> //缓存刷新
二级缓存:
进程级别的缓存,SqlSessionFactory的缓存
在一个SqlSession生命周期中有效,可以在多个SqlSession生命周期中共享
默认关闭的,需要在使用的时候为某个命名空间
在session第一次关闭的时候进行缓存
<!--主配置文件中-->
<!--默认开启项目下的二级缓存-->
<setting name="cacheEnabled" value="true"/>
mapper文件中:
<!--开启二级缓存,要求实体类进行序列化-->
<cache/>
列名和属性名不一致问题:
列别名:
select ename name from emp
使用resultMap:
<resultMap id="student_map" type="student">
<id column="sid" property="sid"/> <!--主键-->
<result column="sname" property="sname"/>
<result column="age" property="age"/>
<result column="cid" property="cid"/>
</resultMap>
关系映射查询:
一对一:
association:
<resultMap id="student_map" type="student">
<id column="sid" property="sid"/> <!--主键-->
<result column="sname" property="sname"/>
<result column="age" property="age"/>
<result column="cid" property="cid"/>
<association property="clazz" javaType="Clazz">
<id column="cid" property="cid"/> <!--主键-->
<result column="cname" property="cname"/>
</association>
</resultMap>
一对多:
collection :
<resultMap id="clazz_map" type="Clazz">
<id property="cid" column="cid"/>
<result property="cname" column="cname"/>
<collection property="list" javaType="list" ofType="Student">
<id property="sid" column="sid"/>
<result property="sname" column="sname"/>
<result property="age" column="age"/>
<result property="cid" column="cid"/>
</collection>
</resultMap>
注解开发:
@select
查询语句
@Select("select * from emp")
List<Emp>testfind2();
@Insert
插入语句
@Insert("insert into student values(#{sid},#{sname},#{age})")
public int register(Student student);
@Update
更新语句
@Update("Update student set sname=#{sname} where sid=#{sid}")
public int update(@Param("sname") String sname,@Param("sid") int sid);
@Delete
删除语句
@Delete("Delete student where sid=#{sid}")
public int delete(Student student);
@results
相对于xml中resultMap标签
@result
相当于xml中resultMap的子标签id或result
@One:
一对一映射
@Select("select * from clazz")
@Results(value = {
@Result(property = "cid",column = "cid",id = true),
@Result(property = "cname",column = "cname"),
@Result(property = "studentList", many = @Many(select = "com.shsxt.mappers.StudentMapper.findByCid"),column = "cid")
})
public List<Clazz>findAll();
@Many:
一对多映射
@Select("select sid,sname,cid from student ")
@Results(value = {
@Result(column = "sid", property = "sid",id = true),
@Result(column = "sname",property = "sname"),
@Result(column = "cid", property = "cid"),
@Result(property = "clazz",one = @One(select = "com.shsxt.mappers.ClazzMapper.findById"), column="cid")
})
List<Student>findAll();
逆向工程:
mybatis-generator是一款mybatis自动代码生成工具,可以
通过配置,快速生成pojo,mapper和xml文件.
官方网址:http://mybatis.org/generator/configreference/ xmlconfig.html
@Result(property = "cname",column = "cname"),
@Result(property = "studentList", many = @Many(select = "com.shsxt.mappers.StudentMapper.findByCid"),column = "cid")
})
public List<Clazz>findAll();
@Many:
一对多映射
```java
@Select("select sid,sname,cid from student ")
@Results(value = {
@Result(column = "sid", property = "sid",id = true),
@Result(column = "sname",property = "sname"),
@Result(column = "cid", property = "cid"),
@Result(property = "clazz",one = @One(select = "com.shsxt.mappers.ClazzMapper.findById"), column="cid")
})
List<Student>findAll();
逆向工程:
mybatis-generator是一款mybatis自动代码生成工具,可以
通过配置,快速生成pojo,mapper和xml文件.
官方网址:http://mybatis.org/generator/configreference/ xmlconfig.html