整合
引入依赖
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
配置文件增加mybatis配置
- 设置数据源相关配置 地址,端口,库,用户名,密码等
- 设置mybatis相关配置
# 数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://118.89.196.179:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
#mybatis配置
# 扫描的mapper.xml文件路径
mybatis.mapper-locations=classpath:mapper/*.xml
# 开启驼峰转下划线
mybatis.configuration.map-underscore-to-camel-case=true
定义实体类
- 实体类就是普通的类,不用像JPA那样标注一些数据库相关的注解
- 如果使用mybatisplus 是需要在类上标注注解
编写对应的mapper接口
- 然后利用idea的mybatisx插件自动生成对应的xml文件,如果没有插件自己在对应的位置写也可以
//mapper接口的示例
public interface UserMapper {
User getUserById(@Param("id") Integer id);
}
<?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接口的全类名-->
<mapper namespace="com.example.demo.mappers.UserMapper">
<select id="getUserById" resultType="com.example.demo.beans.User">
select * from test.user where id = #{id}
</select>
</mapper>
在启动类上标注@mapperScan注解
- 在springBoot的主程序上标注@mapperScan注解来告知spring自动扫描mapper接口
@MapperScan(basePackages = "com.example.demo.mappers")
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
mapper.XML文件详细使用
<?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">
<!-- 在xml中的配置 -->
<mapper namespace="com.study.dao.studentDao">
<!-- 开启二级缓存 -->
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" >
<!-- type="自己写的缓存类的全类名" type 属性指定的类必须实现 org.apache.ibatis.cache.Cache 接口 ,对缓存的配置(如清除策略、可读或可读写等),不能应用于自定义缓存。 -->
<!-- <property name="myfile" value="D:/1.txt"/> 来配置自己写的缓存类中的属性值-->
<!-- 如果只想开启缓存就写个<cache></cache>就行 使用默认配置 -->
<!-- eviction="更新缓存的方式 默认为最近最少未使用 还有先进先出 等其他"-->
<!-- flushInterval="60000"刷新间隔 单位毫秒 默认不配置 也就是无刷新间隔 只用在执行插入,更新,删除操作时进行更新 -->
<!-- size="512" 缓存空间大小 默认时1024kb -->
<!-- readOnly="true" 是否只读 -->
<!-- 二级缓存是事务性的。这意味着,当 SqlSession 完成并提交时,或是完成并回滚,但没有执行 flushCache=true 的 insert/delete/update 语句时,缓存会获得更新。 -->
</cache>
<!-- <cache-ref namespace="缓存引用 可以引用其他命名空间的缓存,即和其他命名空间使用同一个二级缓存"/> -->
<resultMap type="com.study.dao.studentDao" id="myfirstrm12">
<id column="" property=""/>
<result column="" property=""/>
</resultMap> <!-- 测试单独的别名是否好用 -->
<!-- flushCache="true" useCache="true" 执行语句是否刷新缓存,是否使用缓存 -->
<!--默认配置
<select ... flushCache="false" useCache="true"/> <insert ... flushCache="true"/> <update ... flushCache="true"/> <delete ... flushCache="true"/> -->
<select id="QueryStudentByid" resultType="student" flushCache="true" useCache="true" >
select * from student where userid = #{id}
</select>
<!-- 测试package别名是否好用 -->
<select id="queryUserById" resultType="uSers" useCache="false">
select * from userinfo where userid=#{id}
</select>
<!-- 测试mybaits定义的 map --> <select id="queryUsers" resultType="map">
select * from userinfo where userid=#{id}
</select>
<insert id="addstudent" parameterType="map" useGeneratedKeys="true" keyProperty="userid2">
insert into student(username,password) values(#{username},#{password})
</insert>
<!-- 他会取到你自增的主键然后放到你的传进来的map中,或者JAVA bean中对应的属性中 keyProperty="id" 就是指定map key的值或者bean德属性名称 -->
<!-- 即使你传入到不是map或者bean 也不会报错 只是无法取到这个值 -->
<insert id="addautokey" parameterType="java.lang.String" useGeneratedKeys="false" keyProperty="id">
<!-- insert into autokeyt(username)values(#{username,javaType=String,jdbcType=varchar,typeHandler=可以指定自己写的类型处理器}) -->
<!-- JDBC 要求,如果一个列允许使用 null 值,并且会使用值为 null 的参数,就必须要指定 JDBC 类型(jdbcType)。
阅读 PreparedStatement.setNull()的 JavaDoc 来获取更多信息
mysql能够处理null值 但是oracle不能处理,所以数据库字段允许为null时 oracle必须使用之歌指定jdbcType 否则会报错
-->
<!-- #{}与${}的区别 以格式parperedstament 一个就是普通的stament #{}有引号,而 ${ }没有引号
可以用来处理一些不能拼装的地方 -->
insert into autokeyt(username)values(#{username,javaType=String})
</insert>
<insert id="addautokeys" parameterType="list">
insert into autokeyt(username) values
<foreach collection="list" item="username" separator=",">
(#{username})
</foreach>
</insert>
<!-- 剩下的就是结果映射了以及高级结果映射 resultmap 用于当java bean中的字段与数据库中的字段不符时进行转换 一般用不到-->
<!-- 可以在Sql使用列别名 来处理列名与POJO对象中的属性名不一样的问题 -->
<!-- 这玩意虽然好用,但还是多次查询或者直接封装在MAP中香 简单的使用一个association 就是级联操作 -->
<!-- resultMap做复杂映射我就先不写了,先练习一下最基本的映射 -->
<resultMap type="com.student.bean.MyEmployee" id="myfirstrm">
<!-- 配置主键 -->
<id column="id" property="myid"/>
<!--配置其他列 -->
<result property="myname" column="name"/>
<result property="mysex" column="sex"/>
<result property="mydepartmentid" column="departmentid"/>
</resultMap> <select id="queryemployeebyid" resultMap="myfirstrm">
select * from employee where id=#{id}
</select>
<select id="queryemployeebyid2" resultMap="mysecondrm">
select e.id eid,e.name ename,e.sex esex,e.departmentid edpid,d.departmentid deid,d.departmentname dename
from employee e left join department d on e.departmentid=d.departmentid where e.id=#{id} </select>
<resultMap type="com.student.bean.MyEmployee" id="mysecondrm">
<!-- 配置主键 -->
<id column="eid" property="myid"/>
<!--配置其他列 -->
<result property="myname" column="ename"/>
<result property="mysex" column="esex"/>
<result property="mydepartmentid" column="edpid"/>
<association property="dp" javaType="com.student.bean.Department">
<!-- <association property="dp" javaType="com.student.bean.Department" resultMap="">也可以引用其他的resultmap进行转换 -->
<id column="deid" property="did"/>
<!-- successful -->
<result property="dname" column="dename"/>
</association> </resultMap>
<!-- 缓存的执行过程
1.默认mybait只开启一级缓存就是session级别的缓存,只缓存一次会话期间所有的查询语句,insert/update/delete 会刷新缓存,会使用最近最少未使用清除不需要的缓存
2.在xml添加<catch/> 会开启二级缓存,该级缓存该xml文件里的所有查询,增删改会清除缓存
3.在开启一级二级缓存后的缓存执行过程(我没整上log4j看不出来)根据视频的印象总结,
-->
</mapper>