mybatis 的十分详细的入门教程第二弹
步骤(复习)
导包
核心包
mybatis-3.2.1.jar
依赖包
asm-3.3.1.jar
cglib-2.2.2.jar
commons-logging-1.1.1.jar
javassist-3.17.1-GA.jar
log4j-1.2.17.jar
slf4j-api-1.7.2.jar
slf4j-log4j12-1.7.2.jar
数据库依赖包
mysql-connector-java-5.1.26-bin.jar
domain
数据库建表
domain映射
getset
tostring
配置文件
拷贝文档
修改为自己的数据库配置
引用数据库四大金刚properties文件
dao
新建接口
mapper.xml拷贝文档
写入sql查询或其他操作
mybatis配置文件引入mapper.xml
log4j
拷贝log4j.properties文件
测试
映射
(mapperdaorepostory)
mapper层
不需要实现类
mapper.xml文件放入mapper包
名字跟接口一致==类名+“mapper”
命名空间 === mapper接口全限定名
方法名 === sql 的 Id
引入mapper.xml
session.getMapper()
自动获取实现类
sql写到类里
接口查询方法头加注解@select(sql)
其他操作注解与sql一致
高级||模糊查询
写一个query类写入查询条件
sql传入query对象
sql里拼接字符串的放方法 concat(可变参数,列名随意放,可变参数)
damo
mybatis可以进行if判断
demo
特殊符号
< <
> >
<![CDATA[数据]]> cdata中的数据不会被识别为语法
where查询问题
demo
[外链图片转存失败(img-QEkuVrdp-1564823219925)(1564712967398.png)]
批处理
批添加
<!--这里写集合 批量添加-->
<insert id="bitchSave" parameterType="list">
insert into employee (name, age, sex) values
<foreach collection="list" item="emp" separator=",">
( #{emp.name},#{emp.age},#{emp.sex})
</foreach>
</insert>
两种批删除
<!--批删除list-->
<delete id="bitchDelete" parameterType="list">
delete from employee where id in
<foreach collection="list" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
<!--批删除arr-->
<delete id="bitchDeleteByArr" parameterType="long[]">
delete from employee where id in
<foreach collection="array" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
动态修改
<!--动态修改,<set>可以自动加set关键字去逗号-->
<update id="dynamicUpdate" parameterType="cn.itsource.domain.Employee" >
update employee
<set>
<if test="name!=null and name!=''">
name = #{name},
</if>
<if test="age!=null">
age = #{age},
</if>
<if test="sex!=null">
sex = #{sex},
</if>
</set>
where id = #{id}
</update>
映射关系
多对一(many to One)
== 一对一
新建两个表
多方添加一方的外键
创建?domain
多方持有一方对象
创建mapper
创建mapper.xml
核心配置文件引入mapper.xml
写保存方法
多方sql里#{dir.id}点出一方id
多方中保存一方
先保存一方,再保存多方
一方保存后获取id才能添加外键
<!--添加多方方法,使用#{dir.id}类中的分类点出id存入数据库-->
<insert id="save" parameterType="cn.itsource._02many2one.Product">
insert into t_product (name, dir_id)
values (#{name}, #{dir.id})
</insert>
查询所有
方法与mapper.xml对应
join on
以下三种方式都使用这条sql
select p.id pid, p.name pname, dir.id dirid, dir.name dirname
from T_product p
join productdir dir on dir.id = p.dir_id
<!--查询所有的sql 引入下面三条ProductResultmap返回-->
<select id="findAll" resultMap="ProductResultmap">
select p.id pid, p.name pname, dir.id dirid, dir.name dirname
from T_product p
join productdir dir on dir.id = p.dir_id
</select>
三种方法从多方查询出一方
第一种官方推荐
<!--查询所有的resultMap 官方推荐的写法-->
<!--id为标识符 type是多方类型-->
<resultMap id="ProductResultmap" type="cn.itsource._02many2one.Product">
<!--分别是属性和列中的名字 id使用<id> 其他属性使用<result>-->
<id property="id" column="pid"/>
<result column="pname" property="name"/>
<!--关联 association javaType一方的类型 property 一方在多方类里的属性名-->
<association property="dir" javaType="cn.itsource._02many2one.ProductDir">
<!--分别是属性和列中的名字 id使用<id> 其他属性使用<result>-->
<id property="id" column="dirid"/>
<result property="name" column="dirname"/>
</association>
</resultMap>
第二种野路子省事
<!--查询所有的resultMap 省事的野路子-->
<resultMap id="ProductResultmap2" type="cn.itsource._02many2one.Product">
<id column="dirid" property="dir.id"/>
<result column="dirname" property="dir.name"/>
</resultMap>
第三种性能最差发送多条sql能不用则不用
<!--查询所有的resultMap 嵌套映射 -->
<resultMap id="ProductResultmap3" type="cn.itsource._02many2one.Product">
<!--分别是属性和列中的名字 id使用<id> 其他属性使用<result>-->
<id property="id" column="pid"/>
<result column="pname" property="name"/>
<!--性能较差,能不用就不要用 select="cn.itsource._02many2one.ProductDirMapper.findOne"是另一条sql column="dirid"是传递过去的参数-->
<association property="dir" javaType="cn.itsource._02many2one.ProductDir"
column="dirid" select="cn.itsource._02many2one.ProductDirMapper.findOne"/>
</resultMap>
一对多
== 多对多
关联集合使用collection而不是association
官方推荐方法 一条sql性能比较好 返回
<!--第一种方法-->
<select id="findAll" resultMap="findAllresultMap2">
select p.id pid, p.name pname, dir.id dirid, dir.name dirname
from productdir dir
join t_product p on p.dir_id = dir.id
</select>
<!--返回格式map-->
<!--第一种方法的resultMap-->
<resultMap id="findAllresultMap" type="cn.itsource._03one2many.ProductDir">
<id property="id" column="dirid"/>
<result property="name" column="dirname"/>
<!--property="products"是一方里的多方属性-->
<!--ofType="cn.itsource._03one2many.Product"是多方属性-->
<!--一对多里使用conlection标签-->
<collection property="products" ofType="cn.itsource._03one2many.Product">
<id column="pid" property="id"/>
<result column="pname" property="name"/>
</collection>
</resultMap>
第二种方式性能差
<!--第二种方法,先查一方,再用多方查询一方发送多条sql-->
<select id="findAll" resultMap="findAllresultMap2">
select dir.id dirid, dir.name dirname
from productdir dir
</select>
<!--返回格式map-->
<!--惯例还有第二种方法 性能最差发送多条sql能不用则不用 column="dirid"是传递过去的参数
select="cn.itsource._03one2many.ProductMapper.findAllBydirId"是sql的路径
-->
<resultMap id="findAllresultMap2" type="cn.itsource._03one2many.ProductDir">
<id property="id" column="dirid"/>
<result property="name" column="dirname"/>
<collection property="products" ofType="cn.itsource._03one2many.Product" select="cn.itsource._03one2many.ProductMapper.findAllBydirId" column="dirid" >
<id column="pid" property="id"/>
<result column="pname" property="name"></result>
</collection>
</resultMap>
<!--调用的sql 用一方id查询多方-->
<select id="findAllBydirId" parameterType="Long" resultType="cn.itsource._03one2many.Product">
select * from t_product where dir_id = #{dirid}
</select>
缓存
自带一级缓存
二级缓存
核心配置中加入标签即可
然后domain必须序列化
实现Serializable