Spring+SpringMVC+Mybatis入门(二)+https://developer.aliyun.com/article/1390528?spm=a2c6h.13148508.setting.15.350a4f0ePTOXQB
三、MyBatis
1、MyBatis的特点
属于持久层ORM框架
- 持久层:将内存中的对象数据转移到数据库中的过程
- MyBatis、Hibernate、Spring-jpa
- ORM(Object Relational Mapping):对象关系映射框架
- 类<=>表
- 属性<=>字段
- MyBatis半自动化
- 表需要手动设计
- 需要提供sql
- 依赖于数据库平台
- 优点:使用灵活,学习成本低(基于原生jdbc封装),优化灵活,适合做互联网项目
2、Mapper接口开发
遵循以下规范:
1.Mapper.xml文件中的namespace与mapper接口的全限定名一致
2.Mapper接口方法名与Mapper.xml中定义的每个Statement的id一致
3.Mapper接口方法的输入参数类型与Mapper.xml中定义的每个sql的parameterType类型相同
4.Mapper接口方法的输出参数类型与Mapper.xml中定义的每个sql的resultType类型相同
3、动态SQL
<?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="cn.ken.dao.UserDao"> <!-- sql语句的抽取 --> <sql id="selectUser">select * from user</sql> <select id="selectByConditions" parameterType="cn.ken.pojo.User" resultType="cn.ken.pojo.User"> <include refid="selectUser"></include> <where> <if test="username!=null"> and username = #{username} </if> <if test="id!=0"> and id = #{id} </if> <if test="password!=null"> and password = #{password} </if> </where> </select> <select id="selectByIds" parameterType="list" resultType="User"> <include refid="selectUser"></include> <where> <foreach collection="list" item="id" open="id in(" close=")" separator=","> #{id} </foreach> </where> </select> </mapper>
4、Mybatis核心配置文件深入
TypeHandlers标签(类型处理器)
你可以重写类型处理器或创建你自己的类型处理器(如把java的Date类型转换为毫秒值存储到数据库的BIGINT类型),具体做法为:实现TypeHandler接口或继承BaseTaypeHandler类,然后可以选择性地将它映射到一个JDBC类型。
开发步骤:
1.定义转换类继承类BaseTypeHandler
覆盖4个未实现的方法,其中setNonNullParameter为java程序设置数据到数据库的回调方法,2..getNullableResult为查询时mysql的字符串类型java的Type类型的方法
3.在Mybatis核心配置文件中注册
4.测试转换是否正确
<!--mybatis.xml--> <!--注册类型处理器--> <typeHandlers> <typeHandler handler="cn.ken.handler.DateTypeHandler"/> </typeHandlers>
public class DateTypeHandler extends BaseTypeHandler<Date> { //将java类型转换为数据库类型 @Override public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException { long time = date.getTime(); preparedStatement.setLong(i, time); } //根据名称将数据库中的类型转换java类型 @Override public Date getNullableResult(ResultSet resultSet, String s) throws SQLException { long aLong = resultSet.getLong(s); return new Date(aLong); } //根据列数 @Override public Date getNullableResult(ResultSet resultSet, int i) throws SQLException { long along = resultSet.getLong(i); return new Date(along); } //存储过程 @Override public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException { long along = callableStatement.getLong(i); return new Date(along); } }
plugins标签
MyBatis可以使用第三方插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即可获得分页的相关数据
开发步骤:
- 导入通用的PageHelper的坐标
- 在mybatis核心配置文件中配置PageHelper插件
- 测试分页数据获取
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.2.0</version> </dependency> <dependency> <groupId>com.github.jsqlparser</groupId> <artifactId>jsqlparser</artifactId> <version>3.2</version> </dependency>
<plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <property name="helperDialect" value="mysql"/> </plugin> </plugins>
//设置分页相关参数,当前页+每页显示条数 PageHelper.startPage(2,3); List<User> userList = mapper.findAll(); //获得与分页相关参数 PageInfo<User> pageInfo = new PageInfo<User>(userList); pageInfo.getPageNum(); pageInfo.getPageSize(); pageInfo.getTotal(); pageInfo.getPages(); pageInfo.isFirstPage(); pageInfo.isLastPage();
5、多表操作
一对一
<mapper namespace="cn.ken.dao.OrderDao"> <resultMap id="orderMap" type="cn.ken.pojo.Order"> <!-- 手动指定字段与实体属性的映射关系 column:数据表的字段名字 property:实体的属性名称 --> <id column="oid" property="id"/> <result column="name" property="name"/> <!-- <result column="uid" property="user.id"/>--> <!-- <result column="username" property="user.username"/>--> <!-- <result column="password" property="user.password"/>--> <!-- property:当前实体(order)中的属性名(private User user) javaType:当前实体(order)中的属性类型 --> <association property="user" javaType="cn.ken.pojo.User"> <id column="uid" property="id"/> <result column="username" property="username"/> <result column="passwird" property="password"/> </association> </resultMap> <select id="selectAll" resultMap="orderMap"> SELECT *, o.id oid FROM `orders` o,`user` u WHERE o.uid = u.id </select>
public class Order { private Long id; private String name; //连接通过对象而不是uid private User user; }
一对多
<mapper namespace="cn.ken.dao.UserDao"> <!-- sql语句的抽取 --> <resultMap id="userMap" type="cn.ken.pojo.User"> <id column="uid" property="id"/> <result column="username" property="username"/> <result column="password" property="password"/> <!-- property:集合名称 ofType:集合类型 --> <collection property="orderList" ofType="cn.ken.pojo.Order"> <id column="oid" property="id"/> <result column="name" property="name"/> </collection> </resultMap> <select id="selectAll" resultMap="userMap"> select *, o.id oid from user u, orders o where u.id = o.uid </select>
public class User { private Long id; private String username; private String password; private List<Order> orderList; }
多对多(建立中间表)
<resultMap id="roleMap" type="cn.ken.pojo.User"> <id column="uid" property="id"/> <result column="username" property="username"/> <result column="password" property="password"/> <collection property="orderList" ofType="cn.ken.pojo.Role"> <id column="roleId" property="id"/> <result column="roleName" property="roleName"/> <result column="roleDesc" property="roleDesc"/> </collection> </resultMap> <select id="selectAllRole" resultMap="roleMap"> select * from user u, role r, user_role ur, where u.id = ur.userId and r.id = ur.roleId </select>
6、注解开发
- @Insert(“sql语句”)
- @Update(“sql语句”)
- @Delete(“sql语句”)
- @Select(“sql语句”)
r` u WHERE o.uid = u.id
```java public class Order { private Long id; private String name; //连接通过对象而不是uid private User user; }
一对多
<mapper namespace="cn.ken.dao.UserDao"> <!-- sql语句的抽取 --> <resultMap id="userMap" type="cn.ken.pojo.User"> <id column="uid" property="id"/> <result column="username" property="username"/> <result column="password" property="password"/> <!-- property:集合名称 ofType:集合类型 --> <collection property="orderList" ofType="cn.ken.pojo.Order"> <id column="oid" property="id"/> <result column="name" property="name"/> </collection> </resultMap> <select id="selectAll" resultMap="userMap"> select *, o.id oid from user u, orders o where u.id = o.uid </select>
public class User { private Long id; private String username; private String password; private List<Order> orderList; }
多对多(建立中间表)
<resultMap id="roleMap" type="cn.ken.pojo.User"> <id column="uid" property="id"/> <result column="username" property="username"/> <result column="password" property="password"/> <collection property="orderList" ofType="cn.ken.pojo.Role"> <id column="roleId" property="id"/> <result column="roleName" property="roleName"/> <result column="roleDesc" property="roleDesc"/> </collection> </resultMap> <select id="selectAllRole" resultMap="roleMap"> select * from user u, role r, user_role ur, where u.id = ur.userId and r.id = ur.roleId </select>
6、注解开发
- @Insert(“sql语句”)
- @Update(“sql语句”)
- @Delete(“sql语句”)
- @Select(“sql语句”)