Mybatis学习笔记
三层架构
- 界面层:和用户打交道,接受用户请求参数,显示处理结果(jsp,HTML,servlet)
- 业务逻辑层:接收了界面层传递的数据,计算逻辑,调用数据库,获取数据
- 数据访问层:就是访问数据库,执行对数据的查询,修改,删除等等
三层对应的包
- controller包(servlet)
- service包(xxxService类)
- dao包(xxxDao类)
三层中类的交互
用户使用界面层–>业务逻辑层–>数据访问层(持久层)–>数据库
三层中对应的处理框架
- 界面层:servlet—springMVC
- 业务逻辑层:service类—spring
- 数据访问层:dao类—mybatis
运行的基本流程
-
加入maven依赖
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.21</version> </dependency>
-
创建Dao接口:里面需要定义你操作数据的方法
-
创建mapper文件,即sql映射文件:写sql语句的
-
创建mybatis一个主配置文件:1)连接数据库 2)指定mapper文件的位置
-
使用mybatis的SqlSession,通过它的方法执行sql语句
xml配置规范
sql映射(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="Dao.ProvinceDao">
<select id="selectProvinces" resultType="databaseClass.Province">
select id,name from province;
</select>
<update></update>
<insert id="insertProvince">
insert into province(id, name) values(#{id},#{name});
</insert>
<delete></delete>
</mapper>
-
要把这个xml文件compile到target/classes文件夹中需要在pom文件下<build>下加上<resources>标签
<resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources>
主配置文件
<?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">
<!--
mybatis的主要配置文件:主要定义了数据库的配置信息,sql映射文件的位置
configuration:根标签
-->
<configuration>
<!--设置mybatis输出日志,value值表示要输出到控制台上-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--环境配置:数据库的连接信息-->
<environments default="mydev">
<!--id:一个唯一值,自定义,表示环境的名称-->
<environment id="mydev">
<!--mybatis的事务类型
type:JDBC表示使用jdbc中的Connection对象的commit,rollback做事务处理
-->
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/liucheng?useUnicode=true;characterEncoding=utf8;serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="1727894442"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--连接一个mapper配置文件-->
<mapper resource="Dao/ProvinceDao.xml"/>
<!--连接一个包下的所有mapper配置文件-->
<!--
使用条件:
1)mapper文件要与接口名称相同(区分大小写)
2)mapper文件要与接口放在同一个包下
-->
<package name="com.liucheng" />
</mappers>
</configuration>
通过SqlSession执行sql
String config="mybatis.xml";
InputStream in = Resources.getResourceAsStream(config);
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession sqlSession = factory.openSession();
String sqlId="Dao.ProvinceDao"+"."+"selectProvinces";
List<Province> provinces= sqlSession.selectList(sqlId);
provinces.forEach(System.out::println);
sqlSession.close();
动态代理
//得到SqlSession后
//使用了动态代理,dao的类名是com.sun.proxy.$Proxy2
ProvinceDao dao=session.getMapper(ProvinceDao.class);
//这里使用的是ProvinceDao接口中的方法,返回值就是对应方法的返回值
List<Province> provinces=dao.selectProvinces();
传入参数
- 参数传入时可以使用#{}或者${}
- #{}就是使用PreparedStatement,传入参数时是先编译后传参
- ${}是使用Statement,先传入参数再编译,会有sql注入问题或者变成多个语句
一个参数
//加入parameterType属性表示传入属性类型
//parameterType可以不写
<select id="selectProvinceId" parameterType="java.lang.Integer" resultType="com.liucheng.Province">
select * from province where id=#{id}
</select>
//在接口中定义方法
public Province selectProvinceId(Integer id);
//使用
Province province=dao.selectProvinceId(1003);
多个参数-使用@Param
<select id="selectProvinceId" resultType="com.liucheng.databaseClass.Province">
select id,name from province where id=#{myId}
</select>
//接口中
public Province selectProvinceId(@Param("myId") Integer id);+-
多个参数-使用对象
<!--
使用对象作为参数的时候
使用对象语法#{对象属性名,javaType=类型名称,jdbcType=类型名称}
javaType:在java中的数据类型名称
jdbcType:在数据库中的类型名称
例如#{paraName,javaType=java.lang.String,jdbcType=VAECHAR}
简化方法#{对象属性名}
-->
<select id="selectProvinceId" resultType="com.liucheng.databaseClass.Province">
select id,name from province where id=#{myId,javaType=java.lang.Integer,jdbcType=int}
</select>
多个参数-使用Map
#{Map的key名}
类型取别名
- resultType中填返回类型全限定名或者mybatis给我们准备好的别名,或者我们自己定义的别名
//在主配置文件中加入
<typeAliases>
<typeAlias type="com.liucheng.databaseClass.Province" alias="cldp" />
<typeAlias type="" alias="" />
<!--或者指定包名,包中所有的类可以不写包名-->
<package name="com.liucheng.databaseClass" />
</typeAliases>
取出参数
返回Map
Map={column_name=value,column_name=value}
自定义赋值
在mapper配置文件
动态sql
- 写在select、update这些标签中
if
<if test="使用java对象的属性值作为判断条件">
想要添加的内容
</if>
<select id="" resultType="">
select * from table where
<if test="name!=null and name!='' ">
name=#{name}
</if>
<if test="">
or value=#{value}
</if>
</select>
- 如果第一个没成立,第二个成立就会出现语法错误
- 所以我们可以用where标签
where
//用来包含多个if标签,当有一个或多个if成立,就会添加where关键字,并去掉多余的or,and关键字
select * from table
<where>
<if test="name!=null and name!='' ">
name=#{name}
</if>
<if test="">
or value=#{value}
</if>
</where>
foreach
- 用来循环java中的数组,list集合
- 主要用于sql的新语句中
//想要的效果
select * from table where id in (1001,1002,1003)
//接口方法
public List<Province> selectForeach(List<Integer>);
//用foreach解决
<select id="" resultType="">
select * from table where id in
<!--
collection:表示接口中的方法参数的类型,数组使用array,list集合用list
item:自定义的,表示数组和集合成员的变量
open:开始的字符
close:循环结束的字符
separator:集合成员之间的分隔符
-->
<foreach collection="list" item="id" open=“(” close=")" separator=",">
#{id}
</foreach>
<!--如果传入的是非基本类型集合-->
<foreach collection="list" item="item" open="(" close=")" separator=",">
#{item.id}
</foreach>
</select>
代码片段
<sql id="id">
select * from table
</sql>
<include refid="id" />
属性配置文件
- 在resources文件夹中创建properties文件
- 在主配置文件中前使用
<properties resource="jdbc.properties" />
//文件中
jdbc.drive=xxxxx
//在主配置文件中使用
value="${jdbc.drive}"
mybatis分页插件pagehelper
<!--maven依赖-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
<!--在主配置文件中加入-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor" />
</plugins>
Province Dao=SqlSession.getMapper(com.liucheng.ProvinceDao.class);
PageHelper.startPage(x,y);
Dao.select();
//相当于在select语句后面加上了 limit y*(x-1),y (每页y个数据,查看第x页)