mybatis简介
MyBatis是一个数据持久层(ORM)框架。把实体类和SQL语句之间建立了映射关系,是一种半自动化的ORM实现。
MyBatis的优点:1.基于SQL语法,简单易学。2.能了解底层组装过程。 3.SQL语句封装在配置文件中,便于统一管理与维护,降低了程序的耦合度。4.程序调试方便。
mybatis基础搭建
一、configuration.xml 全局配置文件
用于配置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="development">
<environment id="development">
<!-- 使用jdbc的事务,mybatis进行管理 -->
<transactionManager type="JDBC" />
<!-- 使用jdbc的连接池连接数据库 -->
<!-- 如果配置了<properties resource="db.properties"/> -->
<!-- value可以使用value="${driver}"的形式进行书写 /> -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mydb" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<!-- 映射文件的配置-->
<mappers>
<mapper resource="mapper/UserMapper.xml" />
<mapper resource="mapper/UserMapper1.xml" />
</mappers>
</configuration>
environments:连接数据库相关配置(可以在其中书写多个id不同的environment配置)通过default进行选择
mappers:用于加载存储sql的mapper.xml
基本配置文件可以修改的位置:
1、environments的default属性的值可以修改为指定id(要与environment的id属性相同)
2、数据库连接的四个属性值
3、mapper 的resource属性指向的加载xml配置的文件地址(mapper名字为自定义的配置文件)
二、mapper.xml 核心映射文件
用于存储相应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">
<!--
namespace唯一表示此名字下的crud语句
-->
<mapper namespace="user">
<!--
id:在此命名空间下唯一标识
resultType:查询结果的返回类型或者集合的泛型
-->
<select id="selectAllUser" resultType="cn.com.bochy.entity.User">
select * from t_user
</select>
</mapper>
需要在核心配置文件中进行配置,在项目启动进行加载
namespace:用于对当前mapper进行标识,多个mapper不能拥有相同的值(一般使用表名)
sql语句id:用于标识执行sql语句不能重复(一般使用功能名)
resultType:返回数据映射对象类型(书写存储数据对象的全路径)
mapper配置可以修改的位置:
1、namespace属性值
2、id属性值
3、resultType:属性值
三、SqlSession接口
用于加载配置文件执行相应sql
package com.yunhe.util;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUitl {
private MyBatisUitl() {
}
private static SqlSessionFactory sqlSessionFactory;
static {
try {
sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(Resources.getResourceAsStream("mybatis-config.xml"));
} catch (Exception e) {
e.printStackTrace();
}
}
public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
}
加载指定配置文件,单例模式避免重复加载,默认加载src下
测试类
package com.yunhe.test;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import com.yunhe.util.MyBatisUitl;
public class Test {
public static void main(String[] args) {
//1、获取sqlsession对象
SqlSessionFactory sqlSessionFactory = MyBatisUitl.getSqlSessionFactory();
SqlSession session = sqlSessionFactory.openSession();
//2、根据配置调用相应方法 namespace.id
List<Object> selectList = session.selectList("user.selectAllUser");
for (Object object : selectList) {
System.out.println(object);
}
}
}
事务处理
在mycatis执行sql时如果使用jdbc可以进行事务的处理,需要在获取sqlsession会话对象是开启事务提交(默认不开启事务自动提交)
//1、获取sqlsession对象
SqlSessionFactory sqlSessionFactory = MyBatisUitl.getSqlSessionFactory();
SqlSession session = sqlSessionFactory.openSession(true);//开启事务的自动提交(默认手动)
//2、根据配置调用相应方法
List<Object> selectList = session.selectList("user.selectAllUser");
session.commit();//手动提交
//session.rollback();
mybatis核心配置文件
configuration标签
全局配置根标签
作用:保存配置标签
properties标签
作用:用于配置全局配置的配置文件在进行一些属性的配置是可以直接从指定配置文件中获取已经书写好的值
例如在properties中属性数据库连接属性
可以在下面的配置中直接使用${key}的形式获取对应数据并填写
<property name="driver" value="${driver}" />
setting标签
修改 MyBatis 在运行时的行为方式(通常使用默认值或只修改制定数据值)
<settings>
<!-- 缓冲配置 -->
<setting name="cacheEnabled" value="true"/>
<!-- 懒加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
<!-- 缓冲区配置 -->
<setting name="localCacheScope" value="SESSION"/>
</settings>
typeAliases 标签
为指定类起别名,简化类名的书写
(1)使用package标签起别名,将需要起别名的类放在同一个包,默认使用类名当做包中类的别名
<typeAliases>
<package name="com.yunhe.pojo" />
</typeAliases>
会将指定包名下的所有类例如:com.yunhe.pojo.User 起别名为User
(2)使用typeAlias标签起别名,需要type标识起别名的类与alias标识别名
<typeAliases>
<typeAlias type="com.yunhe.pojo.User" alias="user"/>
</typeAliases>
typeHandlers 标签
不使用,类型处理器 ,MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型。默认已经提供了默认的类型处理器,可以通过这个属性进行自定义类型处理器的使用 ,就是数据库数据类型与java数据类型的转换
objectFactory 标签
不使用,对象工厂, 每次 MyBatis 创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成实例化工作。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认无参构造方法,要么通过存在的参数映射来调用带有参数的构造方法。
plugins 标签
一般不使用,使用mybatis获取其他插件, 这些都是更底层的类和方法,所以使用插件的时候要特别当心。
environments标签
用于配置数据库相关环境的根标签
1)MyBatis可以配置多种环境,比如开发、测试和生产环境需要有不同的配置
2)每种环境使用一个environment标签进行配置并指定唯一id标识符
3)可以通过environments标签中的default属性指定一个环境的id标识符来快速的切换环境
environment标签
数据环境相关配置,书写在environments标签中可以配置多个,但id唯一
transactionManager 标签
事务管理器,书写在相应的environment标签中,用于指定数据库事务的管理
type属性值可以进行选择
1)JDBC - 这个类型直接全部使用 JDBC 的提交和回滚功能。它依靠使用连接的数据源来管理事务的作用域。
2)MANAGED - 这个类型什么不做 , 它从不提交 、 回滚和关闭连接 。 而是让窗口来管理事务的全部生命周期 。
3)自定义 - 实现TransactionFactory接口,type=全类名/别名
dataSource 标签
数据源(连接),书写在environment标签中,用于指定连接获取方式
type属性值可以进行选择
1)UNPOOLED:不使用连接池, UnpooledDataSourceFactory
2)POOLED:使用连接池, PooledDataSourceFactory
3)JNDI: 在EJB 或应用服务器这类容器中查找指定的数据源
4)自定义:实现DataSourceFactory接口,定义数据源的获取方式。
mappers 标签
映射器,用于保存所有sql相关的mapper.xml配置文件
1)用来在mybatis初始化的时候,告诉mybatis需要引入哪些Mapper映射文件
- mapper逐个注册SQL映射文件
mapper标签
指定映射位置,书写在mappers标签中,指定xml具体位置
resource属性:单独引入相应xml配置(可以通过mapper配置中的namespace与id动态执行)
<mapper resource="mapper/b.xml" />
class属性:单独引入mapper接口对象(可以自动扫描与mapper接口名字相同的xml,class与xml同一目录)
<mapper class="mapper.b"/>
package标签:引入指定包下接口对象(可以自动扫描与mapper接口名字相同的xml,class与xml同一目录)
<package name="mapper"/>
b mapper = session.getMapper(b.class);//通过mapper接口形式执行
ArrayList<User> selectAllUser = mapper.selectAllUser();
总结:mybatis核心配置文件其实在配置时往往更多的使用的默认配置,大多数只需要修改数据库相关以及映射文件位置即可
注意:使用mapper接口由mybatis生成实现类的配置中要求:mapper接口与对应xml配置在同一包下且文件名相同,在相应xml配置文件中namespace值为对应的接口路径,在mapper接口中书写的抽象方法个数必须在相应xml中可以找到对应id的标签
mapper配置文件简单书写
<?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="mapper.StudentDao">
<!-- 增 -->
<insert id="insert" >
insert into student values('zhagnsan',18,'男','13xxxxxxxxxxxxx','河南')
</insert>
<!-- 删 -->
<delete id="delete">
delete from student where `name` = #{s}
</delete>
<!-- 改 -->
<update id="update">
update student set age=19
</update>
<!-- 查 -->
<select id="select" resultType="com.yunhe.test.Student">
select * from student
</select>
</mapper>
mapper核心映射文件
<?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.yunhe.pojo.User">
<!--select-->
<!--insert-->
<!--update-->
<!--delete-->
<!--sql-->
<!--resultMap-->
</mapper>
mapper配置文件由(1)xml标签(2)mapper头标签(3)mapper根标签组成
mapper标签
是mapper配置文件的根标签,用于在标签中书写指定语法完成sql定义等操作。
拥有属性namespace用于标识当前mapper(唯一)
namespace的值有两种书写方式
(1)短名称
直接使用自定义字符串作为namespace值,可以与其他配置文件相同,但如果多个配置文件namespace相同那么其中的语句id不能重复,在进行使用时通过namespace.id执行相应的sql语句
(2)接口完全限定名
通过配置相应接口的形式使其自动加载相应接口对应的配置文件,namespace直接书写成相应的接口的全路径,通过自动生成的接口实现类进行方法的调用,也可以使用namespace.id执行相应的sql语句
参数传递
mybatis会自动进行参数的映射,mybatis传递的参数只有一个对象,多个参数会被识别为数组或集合.
${}:以拼接的形式将数据拼入sql语句,不能防止sql注入,不能自动识别传入参数
#{}:以占位符的形式将数据插入sql语句。可以防止sql注入
- #方式能够很大程度防止sql注入。
- $方式无法防止Sql注入。
- $方式一般用于传入数据库对象,例如传入表名.列名等
- 一般能用#的就别用$
常用标签
mybatis进行sql书写常用的标签以及属性
select标签
用于书写查询语句
常用属性:
id: 在命名空间中唯一的标识符,可以被用来引用这条语句。
resultType:返回值类型,如果返回多条数据自动分装为集合
parameterType:设置参数类型,通常为查询对象,mybatis会自动进行参数的映射
<!--无参数-->
<select id="selectAllUser" resultType="com.yunhe.pojo.User" >
select * from user
</select>
<!--唯一参数-->
<select id="selectByUsername1" resultType="com.yunhe.pojo.User" >
select * from user where username = #{asd}/*无需考虑传入参数的值,因为只有一个参数自动解析传入*/
</select>
<!--以对象作为参数-->
<select id="selectByUsername2" resultType="com.yunhe.pojo.User" parameterType="com.yunhe.pojo.User">
select * from user where username = #{username} and password= #{password}
</select>
<!--多个不同参数 mybatis将传入的多个参数以集合或数组的形式获取 传入时使用下标 -->
<select id="selectByUsername3" resultType="com.yunhe.pojo.User" >
select * from user where username = #{0} or username= #{1}
</select>
<!-- 注解参数绑定 在接口将指定数据与变量名绑定 可以直接使用变量名传递参数 -->
<select id="selectByUsername4" resultType="com.yunhe.pojo.User" >
select * from user where username = #{n1} or username= #{n2}
</select>
<select id="selectLikeUsername" resultType="com.yunhe.pojo.User" >
select * from user where username like concat('%',#{sa},'%')
</select>
insert标签
用于书写添加语句
常用属性:
id: 在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType:设置参数类型,通常为查询对象,mybatis会自动进行参数的映射
<insert id="insertUser" parameterType="com.yunhe.pojo.User">
insert into user (`username`,`password`) values (#{username},#{password})
</insert>
update标签
用于书写更新语句
常用属性:
id: 在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType:设置参数类型,通常为查询对象,mybatis会自动进行参数的映射
<update id="updateUser" parameterType="com.yunhe.pojo.User">
update user set `password`=#{password} where `username` =#{username}
</update>
delete标签
用于书写删除语句
常用属性:
id: 在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType:设置参数类型,通常为查询对象,mybatis会自动进行参数的映射
<delete id="deleteByUser" >
delete from user where username=#{asd}
</delete>
sql标签
可以被用来定义可重用的 SQL 代码段,可以包含在其他语句中。它可以被静态地(在加载参数) 参数化. 不同的属性值通过包含的实例变化
<!--用于定义共用的属性与sql-->
<sql id="user">
username,password
</sql>
<sql id="select">
select <include refid="user"/> from user
</sql>
include标签
用于引用定义在sql标签重用的sql代码段可以在正常的sql中直接拼接使用
<!--无参数-->
<select id="selectAllUser" resultType="com.yunhe.pojo.User" >
<include refid="select"/>/*select username,password from user */
</select>
<!--唯一参数-->
<select id="selectByUsername1" resultType="com.yunhe.pojo.User" >
<include refid="select"/> where username = #{asd}
/* select username,password from user where username = ? */
</select>
cache缓存标签
<cache/>
缓存技术是一种“以空间换时间”的设计理念,利用内存空间资源来提高数据检索速度的有效手段之一。 MyBatis默认情况下是开启缓存的,除了局部的 session 缓存。要开启二级缓存,你需要在你的 SQL映射文件中添加一行:
最好在setting中手动设置一下开启二级缓存
<!-- 二级缓存配置 -->
<setting name="cacheEnabled" value="true"/>
mybatis默认开启1级缓存,针对于session对话,存储会话中,当前会话查询相同数据时会直接从缓存中进行查询
2级缓存,针对与mapper,多个会话只要使用的是相同的mapper,那么可以共享,不支持分布式应用,所以现在一般使用第三方支持分布式应用的插件(程序)
针对于开启二级缓存后基本sql标签可以额外添加属性
useCache:属性,对于开启二级缓存的查询,每次会先去缓存进行查找之后才会执行,如果不想让当前执行查询使用缓存需要将值设置为false
<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false"> sql…</select>
flushCache: 属性在mapper的同一个namespace中,如果有其它insert、update、delete操作数据后需要刷新缓存,如果不执行刷新缓存会出现脏读。 设置statement配置中的flushCache=“true” 属性,默认情况下为true即刷新缓存,如果改成false则不会刷新。使用缓存时如果手动修改数据库表中的查询数据会出现脏读。
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true"> sql…
动态sql
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。
if标签
使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分,经常用于对象的多条件查询,例如,根据传入对象不为空的属性进行查询。
<select id="selectUser" parameterType="com.yunhe.pojo.User" resultType="com.yunhe.pojo.User">
<include refid="select"/> where 1=1
<if test="username !=null">
and username =#{username}
</if>
<if test="password !=null">
and password =#{password}
</if>
</select>
choose、when、otherwise 标签
有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句
<!-- 根据传入对象参数动态查询 查询传入对象值不为空的第一个条件 -->
<select id="selectUser2" parameterType="com.yunhe.pojo.User" resultType="com.yunhe.pojo.User">
<include refid="select"/> where
<choose>
<when test="username !=null">
username =#{username}
</when>
<when test="password !=null">
password =#{password}
</when>
<otherwise>
2=2
</otherwise>
</choose>
</select>
where标签
where元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where元素也会将它们去除。
<select id="selectUser3" parameterType="com.yunhe.pojo.User" resultType="com.yunhe.pojo.User">
<include refid="select"/>
<where>
<if test="username !=null">
and username =#{username}
</if>
<if test="password !=null">
and password =#{password}
</if>
</where>
</select>
set标签
set标签只有在其中返回语句有内容的情况下才会插入 set 语句,如果插入的语句以,结尾set会自动将其删除
<!--动态进行指定数据的修改 -->
<update id="updateUser1" parameterType="com.yunhe.pojo.User">
update user
<set>
<if test="username!=null"> username=#{username},</if>
<if test="password!=null"> password=#{password},</if>
</set>
</update>
foreach遍历标签
可以将传入的数组或者集合进行动态遍历,与其他标签相结合使用完成sql的循环动态拼写,例如批量添加、批量删除等操作
item:遍历取出的数据
index:遍历数据的索引
colleaction:遍历的数据集合
open:开始拼接时添加的字符串
separator:每次遍历中间的字符串
close:结束后最后添加的字符串
foreach标签的使用往往伴随着数组、集合参数的使用,如果使用数组作为参数,那么需要使用@param进行参数绑定,集合可以直接识别类型并使用
如果集合中存储数据为对象形式,那么在遍历使用时使用itm对象。属性名进行使用(注意调用的其getter方法)
<--传入user对象集合批量添加-->
<insert id="insertUser2" >
insert into user values
<foreach collection="list" index="i" item="u" separator=",">
(#{u.username}, #{u.password})
</foreach>
</insert>
<--传入批量修改字符串集合批量修改-->
<update id="updateList">
update user set password='1' where username in
<foreach collection="list" item="a" separator="," open="(" close=")">
#{a}
</foreach>
</update>
resultMap标签
用来描述数据库字段与java实体类的映射关系,默认数据库字段与实体类属性相同,但也存在不相同的情况,所以如果没有一一对应,那么返回类型则不能使用resultType应使用自定义的resultMap标签
type属性:用于保存数据的对象类型
id属性:用于标识当前resultMap标签的唯一值
autoMapping属性:存在相同属性自动映射默认true(使用resultmap最好设置为false)
id标签
type属性代表类型的对象的id列(数据库中查询字段主键)
<id column="uid" property="id"/>
column属性:代表查询结果列名
property属性:代表存储数据对应属性名
result标签
除主键外值映射存储对应关系标签
<mapper namespace="com.yunhe.dao.UserDao">
<resultMap type="com.yunhe.pojo.User2" id="MyUser" autoMapping="false">
<id column="uid" property="id" />
<result column="uname" property="name"/>
<result column="upwd" property="pwd"/>
<result column="rid" property="rid"/>
</resultMap>
column属性:代表查询结果列名
property属性:代表存储数据对应属性名
association 标签
在进行查询时,经常使用多表查询,在进行多表查询后可能出现两表数据一一连接并返回的情况,这个时候返回擦查询的字段如果在一个实体类中通过属性全部定义,那么违反了orm映射关系(一张表对应一个实体类,属性列名相对应),所有在实体类中一般使用类的形式去保存,这个使用就需要使用相应标签在resultMap进行标识
使用 association 标签解决数据一对一关系
association 标签可以理解为在resultMap中又定义了一个resultMap标签用于标识当前类实体类属性
<resultMap type="com.yunhe.pojo.User3" id="MyUser3">
<id column="uid" property="id" />
<result column="uname" property="name" />
<result column="upwd" property="pwd" />
<association property="r" javaType="com.yunhe.pojo.Role">
<id column="rid" property="rid" />
<result column="rname" property="rname"/>
<result column="rdesc" property="rdesc"/>
</association>
</resultMap>
property属性:用于标识类属性名
javaType属性:用于标识属性对应的具体类路径
使用 colleaction标签解决数据一对多关系
<resultMap type="com.yunhe.pojo.Role2" id="myRole">
<id property="rid" column="rid" />
<result property="rname" column="rname"/>
<result property="rdesc" column="rdesc"/>
<collection property="list" ofType="com.yunhe.pojo.User">
<id property="uid" column="uid"/>
<result property="uname" column="uname"/>
<result property="upwd" column="upwd"/>
<result property="rid" column="rid"/>
</collection>
</resultMap>
property属性:用于标识类属性名
ofType属性:用于标识集合中存储数据类型
懒加载
在应用进行查询时,往往很多时候需要进行关联查询,但是进行展示时可能只是展示一小部分,但是执行的sql语句会将全部数据直接查询,懒加载就是将sql分开执行,先查询主要数据之后进行查询次要数据
mybatis数据加载的分类
(1)直接执行查询(sql直接书写在一个标签中全部执行)
(2)侵入式懒加载(不同sql书写在不同标签,进行层级依次加载)
(3)深入式懒加载(不同sql书写在不同标签,进行层级依次加载,关联数据只有在被使用时才会执行)
mybatis中懒加载开启通常使用两种方式:
(1)在setting配置文件中设置(全局)
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
(2)在相应resultMap中通过属性进行设置(当前查询)
fetchType="lazy"深入式 eager侵入式
mysql-connector-java-5.1.0-bin.jar
使用深入式懒加载完成一对一查询
1、书写一对一数据对象
要求包含指定对应对象(User对象存在Role对象属性)
User.java
public class User implements Serializable {
private int id;
private String name;
private String pwd;
private Role r;
...getter/setter 构造
}
Role.java
public class Role implements Serializable{
private int rid;
private String rname;
private String rdesc;
...getter/setter 构造
}
2、在相应的mapper.xml中书写查询语句(分别的查询语句)
userMapper.xml(默认查询的数据)
<select id="selectAll" resultMap="自定义的resultMap">
select * from user
</select>
roleMapper.xml(根据关联条件查询指定数据)
<select id="selectRoleById" resultType="com.yunhe.pojo.Role">
select * from role where rid=#{rid}
</select>
3、为查询书写相应的自定义的resultMap并设置懒加载属性为fetchType="lazy"
<resultMap type="com.yunhe.pojo.User" id="mylazyU">
<id column="uid" property="id" />
<result column="uname" property="name" />
<result column="upwd" property="pwd" />
<association property="r" column="rid" select="com.yunhe.dao.RoleDao.selectRoleById" fetchType="lazy" />
</resultMap>
property属性:用于标识返回对象指定属性名
column属性:用于标识查询数据列(会获取对应列数据传入相应的查询语句)
select属性:懒加载执行时调用获取数据的方法(可以调用其他mapper中的方法,通过namespace.id使用)
fetchType属性:懒加载属性可以修改局部懒加载配置
使用深入式懒加载完成一对多查询
1、书写一对一数据对象
要求包含指定对应对象集合(Role对象包含User对象集合)
Role.java
public class Role implements Serializable{
private int rid;
private String rname;
private String rdesc;
private ArrayList<User> list;
...getter/setter 构造
}
User.java
public class User implements Serializable {
private int id;
private String name;
private String pwd;
private int rid;
...getter/setter 构造
}
2、在相应的mapper.xml中书写查询语句(分别的查询语句)
RoleDao.xml
<select id="selectAll" resultMap="自定义的resultMap">
select * from role
</select>
UserDao.xml
<select id="selectByRid" resultType="com.yunhe.pojo.User">
select * from user where rid=#{rid}
</select>
3、为查询书写相应的自定义的resultMap并设置懒加载属性为fetchType="lazy"
<resultMap type="com.yunhe.pojo.Role" id="lazyRole">
<id column="rid" property="rid" />
<result column="rname" property="rname" />
<result column="rdesc" property="rdesc" />
<collection property="list" ofType="com.yunhe.pojo.User" column="rid"
select="com.yunhe.dao.UserDao.selectByRid" fetchType="lazy"/>
</resultMap>
property属性:用于标识返回对象指定属性名
column属性:用于标识查询数据列(会获取对应列数据传入相应的查询语句)
select属性:懒加载执行时调用获取数据的方法(可以调用其他mapper中的方法,通过namespace.id使用)
fetchType属性:懒加载属性可以修改局部懒加载配置
ofType属性:用于标识集合存储数据类型(要求select语句返回结果与之对应)
mybatis注解开发
在进行程序开发中,对于开发代码的书写往往除了逻辑上导致的代码不同外,对于配置也存在多种配置方式,例如servlet2.5以及3.0以上版本的注解开发,通过使用注解标识的样式将程序的配置进行简化,mybatis同样存在这样的功能,但是虽然mybatis提供了注解形式的开发,但使用率不是很高,归结与这样会将配置书写在java代码中导致修改需要去指定的java代码中,这会造成运行程序修改时必须停止运行。
常用注解
@Param()注解
语法:@Param(value=“绑定值”)可以简写为@Param(“绑定值”)
用于接口方法存在多个参数进行绑定传值
public int selectByNameAndJob(@Param("name")int name,@Param("job")int job);
@Select()注解
语法:@Select(value=“查询语句”)可以简写为@Select(“查询语句”)
等价于mapper.xml中的
@Select("select * from emp") List<Emp> allEmp();
@Insert()注解
语法:@Insert(value=“添加语句”)可以简写为@Insert(“添加语句”)
等价于mapper.xml中的
@Insert("insert into emp (ename,job,deptno,sal,hiredate) value(#{ename},#{job},#{deptno},#{sal},#{hiredate})")
int insertEmp(Emp emp);
@Update()注解
语法:@Update(value=“修改语句”)可以简写为@Update(“修改语句”)
等价于mapper.xml中的
@Update("update emp set ename=#{ename} where empno=#{empno}")
int updateEmp(Emp emp);
@Delete()注解
语法:@Delete(value=“删除语句”)可以简写为@Select(“删除语句”)
等价于mapper.xml中的
@Delete("delete from emp where empno=#{empno}")
int deleteEmp(int empno);
@Results()注解
语法:@Results(id=“唯一标识”,value={result标签数组})
等价于mapper.xml中的
@Result()注解
语法:@Result(id=“true/false是否为主键”,column=“数据库列”,property=“属性名”)
等价于mapper.xml中的与
@resultMap()注解
语法:@resultMap(value=“返回结果集映射id”)可以简写为@resultMap(“返回结果集映射id”)
等价于mapper.xml中的resultMap属性
@Results(id = "userMap",value = {
@Result(id = true,column = "id",property = "id"),
@Result(column = "name",property = "name"),
@Result(column = "sal",property = "sal"),
@Result(column = "birthday",property = "birthday")
})
@Results()注解与@Result()注解、@resultMap()一同使用
@Results负责定义相应的数据属性与列的映射
@Result()负责定义单独的一列映射
@resultMap()负责重复使用定义好的映射返回
@Results()默认对第一个方法生效
使用注解完成一对一sql的书写
@One()注解
语法:@One(select=“执行方法”,fetchType=“加载方式(FetchType.LAZY深入懒加载)”)
one是@Result标签的一个属性,添加后相当于将result标签转换为mapper.xml中的
@Results(id = "empMap", value = {
@Result(id = true, column = "eid", property = "eid"),
@Result(column = "ename", property = "ename"),
@Result(column = "ejob", property = "ejob") ,
@Result(column = "dId", property = "dept",one=@One(select="selectById",fetchType=FetchType.LAZY)) }) @Select("select * from emp")
public ArrayList<Emp> selectEmp();
@Select("select * from dept where did=#{did}")
public Dept selectById(int did);
使用注解完成一对多sql的书写
@Many()注解
语法:@Many(select=“执行方法”,fetchType=“加载方式(FetchType.LAZY深入懒加载)”)
Many是@Result标签的一个属性,添加后相当于将result标签转换为mapper.xml中的
@Results(id = "empMap", value = {
@Result(id = true, column = "eid", property = "eid"),
@Result(column = "ename", property = "ename"),
@Result(column = "ejob", property = "ejob") ,
@Result(column = "dId", property = "dept",many=@Many(select="selectById",fetchType=FetchType.LAZY)) }) @Select("select * from emp")
public ArrayList<Emp> selectEmp();
@Select("select * from dept where did=#{did}")
public ArrayList<Dept> selectById(int did);
注意:在进行sql书写时常常将不同表sql书写在不同的位置,所以在进行一对一、一对多书写是select对应的值可以书写为接口全路径.方法名
使用注解完成动态sql的书写
使用Mybatis注解实现sql语句,但是有些时候有些字段是空的,这时候这个空的字段就要从条件查询语句中删除,这个时候就需要用到动态Sql。
使用方式很简单在原有的基础上使用{}进行包裹即可
@Select({"<script>select * from t_user <where><if test='id!=0'> id=#{id} </if></where></script>"})
public ArrayList<User> selectUser(@Param("id") int id);
mybatis逆向工程
1、导入jar包
mybatis-generator-core-1.3.7.jar
mysql-connector-java-5.1.0-bin.jar
2、书写逆向工程配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="testTables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="false" />
</commentGenerator>
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/test" userId="root"
password="root">
</jdbcConnection>
<!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="com.yunhe.pojo"
targetProject="./src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="com.yunhe.mapper"
targetProject="./src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.yunhe.mapper"
targetProject="./src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 指定数据库表 -->
<table tableName="class"></table>
<table tableName="computer"></table>
<table tableName="role"></table>
<table tableName="student"></table>
<table tableName="user"></table>
</context>
</generatorConfiguration>
3、书写工具类执行逆向生成
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
public class TT {
public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
//加载逆向生成配置文件信息
File configFile = new File(配置文件路径);
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}
}
逆向工程pojoExample类的使用
https://blog.csdn.net/biandous/article/details/65630783?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase