Mybatis
Mybatis的简介
原始jdbc操作的分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JkwE9uWB-1646468306665)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303113033630.png)]
什么是Mybatis
· mybatis是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建链接、创建statement
· mybatis通过xml或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句
· 最后mybatis框架执行sql并将结果映射为java对象并返回,采用ORM思想解决实体和数据库映射的问题,对jdbc进行了封装,屏蔽了jdbc api底层访问细节,使我们不用与jdbc api打交道,就可以完成对数据库的持久化操作
Mybatis的快速入门
Mybatis开发步骤
-
添加MyBatis的坐标 <dependencies>
<dependency>
<groupId>mysql</groupId>
<artifaceId>mysql-connector-java</artifaceId>
<version>5.1.32</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifaceId>mybatis</artifaceId>
<version>3.4.6</version>
</dependency>
</dependencies>
-
创建user数据表 -
编写User实体类 -
编写映射文件UserMapper.xml
<mapper namespace=" ">//命名空间
<select id=" " resultType="结果集封装到这个地方">
select *from user
</select>
</mapper>
-
编写核心文件SqlMapConfig.xml
<enviroments defult="">
<enviroment id=" ">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name=" " value=" "/>
<property name=" " value=" "/>
<property name=" " value=" "/>
</dataSource>
</enviroment>
</enviroments>
<mappers>
<mapper resource=" "></mapper>
</mappers>
- 编写测试类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OEszshwI-1646468306666)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303120345878.png)]
Mybatis官网
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ErnkofKi-1646468306667)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303114232479.png)]
Mybatis的映射文件概述
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HP2fn7FB-1646468306668)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303121914039.png)]
Mybatis的增删改查操作
Mybatis的插入操作
· 插入语句使用insert标签
· 在映射文件中使用parameterType属性指定要插入的数据类型
· Sql语句中使用#{实体属性名}方式引用实体中的属性值
· 插入操作使用的API是sqlSession.insert(“命名空间.id”, 实体对象)
· 插入操作涉及数据库数据变化,所以要使用sqlSession对象显示的提交事务,即sqlSession。commit()
<insert id=" " parameterType=" ">
insert into user values(#{id},#{username},#{password})
</insert>
Mybatis的修改操作
· 修改语句使用update标签
· 修改操作使用的API是sqlSession.update(“命名空间.id”, 实体对象);
<update id=" " parameterType=" ">
update user set username=#{username},password=#{password} where id=#{id}
</insert>
Mybatis的删除操作
· 删除语句使用delete标签
· Sql语句中使用#{任意字符串}方式引用传递的单个参数
· 删除操作使用的API是sqlSession.delete(“命名空间.id,Object”);
<delete id=" " parameterType=" ">
delete from user values id=#{id}
</insert>
Mybatis的查询操作
<select id=" " resultType=" ">
select *from user
</select>
Mybatis的核心配置文件概述
MyBatis核心配置文件层级关系
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n5uwTmbA-1646468306668)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303145844569.png)]
environments标签
· 数据库环境的配置,支持多环境配置
<enviroments defult=""> //指定默认的环境名称
<enviroment id=" "> //指定当前环境的名称
<transactionManager type="JDBC"/> //指定事务管理类型是JDBC
<dataSource type="POOLED"> //指定当前数据源类型是连接池
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name=" " value=" "/>
<property name=" " value=" "/>
<property name=" " value=" "/>
</dataSource>
</enviroment>
</enviroments>
事务管理器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G2WPSXEr-1646468306669)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303150828443.png)]
数据源
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vb8ybxXo-1646468306669)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303150834034.png)]
mapper标签
· 标签的作用是加载映射配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bcL6FvuW-1646468306670)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303151141264.png)]
Properties标签
· 实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SgTHwKrw-1646468306671)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303151706658.png)]
<properties resource="jdbc.properties"></properties>
typeAliases标签
· 设置类型别名
<typeAliases>
<typeAlias tpye="实体类地址" alias="自定义的别名"> </typeAlias>
</typeAliases>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eHgBv3M8-1646468306672)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303152355186.png)]
· 常用类型的别名
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZgCdkCZN-1646468306672)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303152434786.png)]
Mybatis的相应API
SqlSession工厂构建器SqlSessionFactoryBuilder
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0xZ56tHC-1646468306672)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303153921338.png)]
SqlSession工厂对象SqlSessionFactory
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-92boziO6-1646468306673)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303153958267.png)]
SqlSession会话对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LX7FHWtH-1646468306673)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303154022914.png)]
MyBatis的Dao层实现
代理开发方式
代理开发方式介绍
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wzM11Rse-1646468306674)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303160201870.png)]
编写UserMapper
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lOUNtgRS-1646468306675)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303160405897.png)]
测试代理方式
@Test
public void testProxyDao() throws IOException{
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession=sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findById(1);
System.out.println(user);
sqlSession.close();
}
<mapper namespace = "com.mhp.mapper.UserMapper">
<select id="findById" ParameterType="int" resultType="user">
select * from User where id=#{id}
</select>
</mapper>
知识小结
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4TfslgGh-1646468306675)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303161346248.png)]
MyBatis映射文件深入
动态sql语句
动态sql之<if>
· 根据实体类的不同取值,使用不用的SQL语句来进行查询。比如在id如果不为空时可以根据id查询,如果username不同空时还要加入用户名作为条件。
<select id="findByCondition" parameterType="user" resultType="user">
select * from User
<where>
<if test="id!=0">
and id=#{id}
</if>
<if test="username!=null">
and username=#{username}
</if>
<if test="password!=null">
and password=#{password}
</if>
</where>
</select>
动态SQL之<forEach>
· 循环执行sql的拼接操作,例如:SELECT * FROM USER WHERE id IN (1,2,5)
<select id="findByIds" parameterType="list" resultType="user">
select *from User
<where>
<foreach collection="array" open="id in (" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
SQL片段抽取
· Sql中可将重复的sql提出出来,使用时用include引用即可,最终达到sql重用的目的
<sql id="selectUser">select *from user</sql>
<include refid="selectUser"></include>
Mybatis核心配置深入
typeHandlers标签
· 无论时MyBatis在预处理语句(PreparedStatement) 中设置一个参数时,还是从结果集中取出一个值,都会用类型处理器将获取的值以合适的方法转换成Java类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JHEVAsT3-1646468306676)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303184538562.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qeMU1yv4-1646468306677)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303184556920.png)]
开发步骤
- 自定义转换类继承类BaseTypeHandler
public class DataTypeHandler extends BaseTypeHandler<Date>
- 覆盖4个未实现的方法,其中setNonNullParameter为java程序设置数据到数据库的回调方法,getNullableResult为查询时 mysql的字符串类型转换成java的Type类型的方法
public void setNonNullParameter(PreparedStatement preparedStatemen,int i,Date date,JdbcType jdbcType){
long time=date.getTime();
prepareStatement.setLong(i,time);
}
public Date getNullableResult(ResultSet resultSet,String s) throws SQLException{
long aLong=resultSet.getLong(s);
Date date=new Date(aLong);
return date
}
- 在MyBatis核心配置文件中进行注册
<typeHandlers>
<typeHandler handler="DateTypeHandler"></typeHandler>
</typeHandlers>
- 测试转换是否正确
plugins标签
· MyBatis可以使用第三方的插件来对功能进行拓展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即可获得分也的相关数据
开发步骤
- 导入通用PageHelper的坐标
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>3.7.5</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser<groupId>
<artifactId>jsqlparser</artifactId>
<version>0.9.1</version>
</dependency>
- 在mybatis核心配置文件中配置PageHelper插件
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"></property>
</plugin>
</plugins>
-
测试分页数据获取
PageHelper.startPage(pageNum: 2,PageSize: 3);
PageInfo<User> pageInfo=new PageInfo<User>(userList);
System.out.println("当前页:"+pageInfo.getPageNum());
MyBatis的多表操作
一对一查询
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D6b8DQQG-1646468306677)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220303222509888.png)]
一对一的配置实现
<resultMap id="orderMap" type="order">
<id column="oid" property="id"></id>
<result column="xxx",property="xxx"></result>
<result column="uid",property="user.id"></result>
<result column="username",property="user.username"></result>
<association property="user" javaType="user">
<result column="uid",property="id"></result>
<result column="username",property="username">
</association>
</resultMap>
一堆多查询
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TjT9Hydq-1646468306678)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220305095232223.png)]
一对多配置实现
<resultMap id="userMap" type="user">
<id column="uid" property="id"></id>
<result column="xxx",property="xxx"></result>
<collection property="orderList" javaType="order">
<result column="uid",property="id"></result>
<result column="xxx",property="xxx">
</collection>
</resultMap>
多对多查询
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8m3qijev-1646468306678)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220305095827765.png)]
多对多配置
<resultMap id="userRoleMap" type="user">
<id column="userId" property="id"></id>
<result column="xxx",property="xxx"></result>
<collection property="roleList ofType="role">
<id column="roleId",property="id"></id>
<result column="xxx",property="xxx"></result>
</collection>
</resultMap>
<selecr id="findUserAndRoleAll" resultMap="userRoleMap">
SELECT * FROM USER </select
知识小结
· 一对一配置:使用<resultMap>做配置
· 一对多配置:使用<resultMap>+<collection>做配置
· 多对多配置:使用<resultMap>+<collection>做配置
Mybatis的注解开发
Mybatis的常用注解
@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result一起使用,封装多个结果集
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
增删改查注解
public interface UserMapper{
@Insert("insert into user values(#{},#{},#{},#{})")
public void save(User user);
@Update("update user set xxx=#{xxx},xxx=#{xxx},xxx=#{xxx}")
public void update(User user);
@Delete("delete from user where id=#{id}")
public void delete(int id);
@Select("select *from user where id=#{id} ")
public void findByID(int id);
@Insert("select *from user")
public List<User> findAll;
}
<mappers>
<package name=""
</mappers>
Mybatis的注解实现复杂映射开发
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qPUI0EtQ-1646468306678)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220305104754279.png)]
一对一的注解开发
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jbtWMeCx-1646468306679)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220305104832011.png)]
public interface OrderMapper{
@Select("select * from orders")
@Results({
@Result(column="id".property="id"),
@Result(column="xxx".property="xxx"),
@Result(column="xxx".property="xxx"),
@Result(
property="user",
column="uid",
javaType=User.class,
one=@One(select="com.xxx.xxx.UserMapper.findById"),
)
})
}
一对多的注解开发
public interface UserMapper{
@Select("select * from user")
@Results({
@Result(id=true, column="id".property="id"),
@Result(column="xxx".property="xxx"),
@Result(column="xxx".property="xxx"),
@Result(
property="orderList",
column="id",
javaType=List.class,
many=@Many(select="com.xxx.xxx.OrderMapper.findByUid"),
)
})
public List<User> findUserAndOrderAll();
}
多对多注解开发
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ky6RTjeX-1646468306679)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220305113056279.png)]
public interface UserMapper{
@Select("select * from user")
@Results({
@Result(id=true, column="id".property="id"),
@Result(id=true, column="xxx".property="xxx"),
@Result(id=true, column="xxx".property="xxx"),
@Result(
property="roleList",
column="id",
javaType=List.class,
many=@Many(select="com.xxx.xxx.RoleMapper.findByUid"),
)
})
public List<User> findUserAndOrderAll();
}
|