MyBatis的各种简单操作——增删查改不过砍瓜切菜
文章目录
MyBatis的意义在于降低sql与java代码的耦合度。
MyBatis是通过接口和mapper.xml文件来实现对数据库的操作,类似于方法,接口定义了方法名、返回值类型和参数类型,mapper.xml中按照接口的方法名确定id,根据接口的返回值类型确定返回值类型。换句话说,mapper.xml文件就是用xml的格式书写一个个操作数据库的方法,但是使用的不再是java代码实现,达到sql与java代码的 降耦。
MyBatis环境的最终搭建
首先搭建包体系,包含实体包、mapper文件包和test包。
mybatis.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>
<!-- 读取属性文件,使用绝对路径即可 -->
<properties resource="jdbc.properties"></properties>
<settings>
<!-- 设置日志类型 -->
<setting name="logImpl" value="LOG4J"/>
</settings>
<!-- 给实体类设置别名 -->
<typeAliases>
<!-- 包下所有类的别名就是类名 首字母小写 -->
<package name="com.zouzou.entity"/>
</typeAliases>
<environments default="mysql">
<environment id="mysql">
<!-- MyBatis中的事务管理 目前的事务管理和JDBC中的事务保持一致 -->
<transactionManager type="JDBC"/>
<!-- 底层使用数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${m_driver}"/>
<property name="url" value="${m_url}"/>
<property name="username" value="${m_name}"/>
<property name="password" value="${m_pwd}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 首先会找mapper包下所有的接口,然后去找和接口的名字相同的xml -->
<package name="com.zouzou.mapper"/>
</mappers>
</configuration>
mapper文件下放置接口和mapper的xml文件,名字一一对应。
java代码(每次操作变化的只有执行方法的部分,所以空出):
//[A]解析MyBatis.xml文件
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
//[B]获得sqlsession工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//[C]获得session对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//[D]执行方法
//[E]关闭资源
sqlSession.close();
MyBatis三种基本查询方式
查询方式一:查询所有数据
java代码:
List<Flower> list = sqlSession.selectList("com.zouzou.mapper.FlowerMapper1.selectAll");
mapper文件:
<select id="selectAll" resultType="flower">
SELECT * from flower
</select>
查询方式二:查询某一条数据
java代码:
Flower flower = sqlSession.selectOne("com.zouzou.mapper.FlowerMapper1.selectOne");
mapper文件:
<select id="selectOne" resultType="flower">
select * from flower where id = 1
</select>
查询方式三:可以通过数据库某一列快速的找到这一列对应的结果集
扫描二维码关注公众号,回复:
13376251 查看本文章
java代码:
Map<Object, Object> map = sqlSession.selectMap("com.zouzou.mapper.FlowerMapper1.selectMap", "id");
Object flower = map.get(3);
mapper文件:
<select id="selectMap" resultType="map">
select * from flower
</select>
MyBatis三种传参方式
传参方式一:传递单个参数
java代码:
Flower flower = sqlSession.selectOne("com.zouzou.mapper.FlowerMapper2.selectOne", 1);
mapper文件:
<select id="selectOne" resultType="flower" parameterType="int">
SELECT * from flower where id = #{param1}
</select>
传参方式二:传递对象
java代码:
Flower flower = new Flower();
flower.setId(1);
flower.setName("玫瑰花");
Flower f = sqlSession.selectOne("com.zouzou.mapper.FlowerMapper2.selectOne2", flower);
mapper文件:
<select id="selectOne2" resultType="flower" parameterType="flower">
select * from flower where id=#{id} and name=#{name}
</select>
传参方式三:通过Map集合传递参数
java代码:
Map<String,Object> map = new HashMap<>();
map.put("a",1);
map.put("b","玫瑰花");
Flower flower = sqlSession.selectOne("com.zouzou.mapper.FlowerMapper2.selectOne3", map);
mapper文件:
<select id="selectOne3" resultType="flower" parameterType="map">
select * from flower where id=#{a} and name=#{b}
</select>
mapper.xml中常用的标签
- if标签:与普通的if语句相同。
<select id="selectMore" resultType="flower">
select * from flower where 1=1
<!-- OGNL表达式 -->
<if test="param1!=null and param1!=''">
and name=#{param1}
</if>
<if test="param2!=null and param2!=''">
and production=#{param2}
</if>
</select>
- where标签:会自动的增加where关键字,并且会把多余的第一个and去掉
<select id="selectMore2" resultType="flower">
select * from flower
<where>
<if test="param1!=null and param1!=''">
and name=#{param1}
</if>
<if test="param2!=null and param2!=''">
and production=#{param2}
</if>
</where>
</select>
- choose、when标签:choose与when标签连用,当前一个数据传输正确时,后一个when被短路。
<select id="selectMore4" resultType="flower">
select * from flower
<where>
<choose>
<when test="param1!=null and param1!=''">
name = #{param1}
</when>
<when test="param2!=null and param2!=''">
and production = #{param2}
</when>
<otherwise>1=1</otherwise>
</choose>
</where>
</select>
- Set标签:会自动增加set关键字,并且去除最后个‘,’
<update id="update">
update flower
<set>
<if test="name!=null and name!=''"> name = #{name},</if>
<if test="production!=null and production!=''">production=#{production},</if>
</set>
where id=#{id}
</update>
- trim标签: 添加前/后缀,去掉前/后缀
<update id="update2">
update flower
<trim prefix="set" suffixOverrides=",">
<if test="name!=null and name!=''"> name = #{name},</if>
<if test="production!=null and production!=''">production=#{production},</if>
</trim>
</update>
- sql和include标签:sql定义公共字段,include标签用于引入
<select id="seelectMore3" resultType="flower">
select <include refid="sql1"></include> from flower
</select>
<!-- 定义公共的sql代码片段 -->
<sql id="sql1">
id,name,price
</sql>
- bind标签: 用于字符串拼接,如模糊搜索
<select id="selectMore2" resultType="flower">
select * from flower
<where>
<if test="param1!=null and param1!=''">
<bind name="pa1" value="'%'+param1+'%'"></bind>
name like #{pa1}
</if>
<if test="param2!=null and param2!=''">
<bind name="pa2" value="'%'+param2+'%'"/>
and production like #{pa2}
</if>
</where>
</select>
- foreach标签: 遍历
<select id="selectMore" resultType="flower">
select * from flower where id in
<foreach collection="list" open="(" separator="," close=")" item="it">
#{it}
</foreach>
</select>
多表查询的三种方式
- 业务代码方式:通过java代码来表现逻辑。如根据学生查询班级信息,输出学生信息中包含班级信息,此为一对一关系,先查询学生信息中的班级代码,再通过班级代码查找班级。将多表查询改为两个单表查询。根据班级查询学生信息,输出班级包含的学生信息,此为一对多关系,先查询班级代码,再通过班级代码查找学生。
java代码:
//查询所有学生所在班级的信息
//[1]查询所有学生 --> clazzno
List<Student> list = stuMapper.selectAll();
//[2]拿着clazzno去班级表中查询班级信息
for (Student s : list){
Integer clazzno = s.getClazzno();
Clazz clazz = claMapper.selectOne(clazzno);
s.setCla(clazz);
System.out.println(s);
}
//查询所有班级中学生的信息
//[1]查询所有班级信息
List<Clazz> claList = claMapper.selectAll();
//[2]查询班级对应的学生信息
for(Clazz cla : claList){
//班级编号
Integer clazzno = cla.getClazzno();
//指定班级中所有学生的集合
List<Student> list1 = stuMapper.selectMore(clazzno);
cla.setList(list1);
System.out.println(cla);
}
StudentMapper.xml
<!-- 启动MyBatis中的二级缓存 -->
<cache readOnly="true"></cache>
<select id="selectOne" resultType="clazz">
select * from clazz where clazzno=#{param1}
</select>
<resultMap id="rm2" type="clazz">
<id column="clazzno" property="clazzno"></id>
<result column="cname" property="cname"></result>
<!--
select:调用哪一个xml方法
column:希望哪一列作为参数进行传递
ofType:集合的泛型
property:把返回的数据整体赋值给哪一个属性
-->
<collection select="com.zouzou.mapper.StudentMapper.selectMore" column="clazzno" ofType="student" property="list"></collection>
</resultMap>
<select id="selectAll" resultMap="rm2">
select * from clazz
</select>
<select id="selectAll2" resultMap="rm3">
select * from student s join clazz c on s.clazzno = c.clazzno
</select>
<resultMap id="rm3" type="clazz">
<id column="clazzno" property="clazzno"></id>
<result column="cname" property="cname"></result>
<collection property="list" ofType="student">
<id column="sid" property="sid"></id>
<result column="sname" property="sname"></result>
<result column="clazzno" property="clazzno"></result>
</collection>
</resultMap>
</mapper>
ClazzMapper.xml
<mapper namespace="com.zouzou.mapper.ClazzMapper">
<!-- 启动MyBatis中的二级缓存 -->
<cache readOnly="true"></cache>
<select id="selectOne" resultType="clazz">
select * from clazz where clazzno=#{param1}
</select>
<resultMap id="rm2" type="clazz">
<id column="clazzno" property="clazzno"></id>
<result column="cname" property="cname"></result>
<!--
select:调用哪一个xml方法
column:希望哪一列作为参数进行传递
ofType:集合的泛型
property:把返回的数据整体赋值给哪一个属性
-->
<collection select="com.zouzou.mapper.StudentMapper.selectMore" column="clazzno" ofType="student" property="list"></collection>
</resultMap>
<select id="selectAll" resultMap="rm2">
select * from clazz
</select>
<select id="selectAll2" resultMap="rm3">
select * from student s join clazz c on s.clazzno = c.clazzno
</select>
<resultMap id="rm3" type="clazz">
<id column="clazzno" property="clazzno"></id>
<result column="cname" property="cname"></result>
<collection property="list" ofType="student">
<id column="sid" property="sid"></id>
<result column="sname" property="sname"></result>
<result column="clazzno" property="clazzno"></result>
</collection>
</resultMap>
</mapper>
- N+1模式:通过MyBatis来实现业务代码的逻辑。其中resultMap标签内的association标签和collection标签调用“xml方法”。因为这种方式会调用N+1次sql语句,故称为N+1模式。
- 多表查询sql语句:可以直接通过多表查询的方式来查询,问题的难点在于无法为类中对象属性赋值,但是通过association标签和collection标签可以完美解决,具体请看mapper.xml文件。
这三种方式逐级递增,逐渐方便和简化,大大体现了MyBatis降低了java代码和sql语句的耦合性。
注:文中只写了查询的方法,增删改与查询语句的区别不过于sql语句和传值数量不同,请举一反三。