Mybatis浅析
Author | ychhh_ |
---|
文章目录
Mybatis基本介绍
原生JDBC问题
- 数据库在连接释放频繁造成系统资源的浪费
- sql语句硬编码实现不便于维护
- 查询操作中,需要手动封装到实体中
解决方案
- 使用数据库连接池初始化连接资源
- 将sql语句抽取到xml文件中
- 使用反射,内省等底层技术,自动将实体和表进行映射
- 综上使用mybatis进行dao的框架简化
Mybatis开发步骤
-
添加Myabtis坐标
-
在数据库中创建数据表
-
在项目中编写相应的java类
-
编写对应的mapper.xml和mapper的接口文件
- 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">
-
编写核心文件mybatis-config.xml文件
- (mybatis-config.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">
- 数据源配置
<?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> <!-- 配置数据源环境 --> <environments default="development"> <!-- 在内部的环境中进行选择一个 --> <environment id="development"> <!-- 在使用mybatis进行连接时会从指定的数据源中进行数据的获取 --> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///mybatistest"/> <property name="username" value="root"/> <property name="password" value="ych3362632"/> </dataSource> </environment> </environments> </configuration>
-
加载映射文件
<mappers>
<!-- 包扫描 -->
<package name="mapper/"/>
<!-- 指定加载 -->
<mapper resource="mapper/UserMapper.xml"></mapper>
</mappers>
Myabtis常用配置解析
-
需注意在mybatis的配置文件中,有标签的顺序限制必须按照指定的顺序进行编写
-
enviroments标签
-
transactionManager类型有两种
- JDBC:直接使用了JDBC的提交和事物回滚,依赖于从数据源得到的连接来进行事物管理
- MANAGED:相当于什么都不做。从来不提交或回滚事物,让容器来管理事物的声明周期。默认情况下关闭连接,然而一些容器并不希望这样做,因此需要讲closeConnection属性设置为false来进行阻止
-
数据源dataSource类型有三种
- UNPOOLED:每次请求时打开和关闭连接
- POOLED:利用池的概念将JDBC和对象连接起来
- JNDI:为了能在EJB或应用服务器的容器中使用,容器可以集中或在外部配置数据源,然后放在一个JNDI上下文引用
-
-
mapper标签
-
加载映射文件
-
使用相对类路径的资源引用
<mapper resource="mapper.UserMapper.xml"></mapper>
-
使用完全限定资源定位符
<mapper url=""></mapper>
-
使用映射器接口实现类的完全限定类名
<mapper class=""></mapper>
-
将包内所有接口实现全部注册为映射器
<mapper package=""></mapper>
-
-
-
properties标签
-
将数据源信息抽取成一个properties文件
<properties resource="jdbc.properties"></properties> <!-- 配置数据源环境 --> <environments default="development"> <!-- 在内部的环境中进行选择一个 --> <environment id="development"> <!-- 在使用mybatis进行连接时会从指定的数据源中进行数据的获取 --> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments>
-
-
typeAliases标签
-
类型别名为java的类名(全路径)设置一个别名
<typeAliases> <typeAlias type="pojo.User" alias="user"></typeAlias> </typeAliases>
<select id="selectAll" resultType="user"> select * from user; </select>
-
typeAliases对于基本数据类型已经内置了别名即将数据类型即小写的数据类型
-
Mybatis相关API
-
```java
String resource = “mybatis-config.xml”;
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);```java SqlSession session = factory.openSession(); SqlSession session = factory.openSession(true); // 自动开启事物提交
-
动态sql
<select id="selectSingle" parameterType="user" resultType="user"> select * from user <where> <if test="name!=null"> and name = #{name} </if> <if test="id!=0"> and id = #{id} </if> </where> </select>
-
where标签
自动生成where语句,每一个子if标签都可以使用and进行开头,默认where标签第一个位置生成一个true判断来保证语法正确
-
if标签
test属性进行条件判断,若成功则执行if内的语句
<select id="selectForeach" parameterType="list" resultType="user"> select * from user <where> <foreach collection="list" open="(" close=")" separator="," item="id" > #{id} </foreach> </where> </select>
-
foreach标签
- collection:遍历集合
- open:开始标志
- close:结束标志
- separator:分隔符
- item:比较属性
等价于 where item in(?,?,?)
-
-
sql语句抽取
-
抽取重复部分,简化后续操作
<sql id="selectUser">select * from user</sql> <select id="selectSingle" parameterType="user" resultType="user"> <include refid="selectUser"></include> <where> <if test="name!=null"> and name = #{name} </if> <if test="id!=0"> and id = #{id} </if> </where> </select>
-
Mybatis核心配置文件深入
-
typeHandlers标签
-
类型转换器,负责java实体到JDBC的类型的转换
-
其对默认数据类型已经进行了转换
-
自定义类型转换器
Step:
- 定义转换类继承类BaseTypeHandler
-
覆盖四个未实现的方法,其中serNonNullParameter为java程序设置到数据库的回调方法,getNullResult为查询时mysql的字符串类型转换成java的type类型方法
package typeHandlers; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; /** * @author ychhh * @ClassName DateTypeHandler.java * @Description TODO * @createTime 2022年04月13日 14:01:00 */ public class DateTypeHandler extends BaseTypeHandler<Date> { @Override public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException { long time = date.getTime(); preparedStatement.setLong(i,time); } @Override public Date getNullableResult(ResultSet resultSet, String s) throws SQLException { long aLong = resultSet.getLong(s); Date date = new Date(aLong); return date; } @Override public Date getNullableResult(ResultSet resultSet, int i) throws SQLException { return null; } @Override public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException { return null; } }
-
在mybatis的核心配置文件进行注册
<typeHandlers> <typeHandler handler="typeHandlers.DateTypeHandler"></typeHandler> </typeHandlers>
-
-
plugins标签
-
mybatis可以使用第三方插件进行扩展
-
开发步骤
- 导入第三方坐标
- 在mybatis的配置文件中配置第三方插件
- 测试
-
第三方插件 – 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>
<plugins> <plugin interceptor="com.github.pagehelper.PageHelper"> <property name="dialect" value="mysql"/> </plugin> </plugins>
PageHelper.startPage(1,2);
- 获得分页数据
PageInfo<User> pageInfo = new PageInfo<User>(list); System.out.println(pageInfo.getPageNum()); System.out.println(pageInfo.getPageSize());
-
Mybatis多表操作
-
通过在javas实体类中嵌套别的实体类,从而完成多表的操作
public class Order { private int oid; private String ordername; private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } public int getOid() { return oid; } public void setOid(int oid) { this.oid = oid; } public String getOrdername() { return ordername; } public void setOrdername(String ordername) { this.ordername = ordername; } @Override public String toString() { return "Order{" + "oid=" + oid + ", ordername='" + ordername + '\'' + ", user=" + user + '}'; } }
-
配置方法1:
<resultMap id="orderMap" type="order"> <result property="user.username" column="username"></result> <result property="user.id" column="id"></result> <result property="user.password" column="PASSWORD"></result> </resultMap> <select id="selectOrder" resultMap="orderMap"> select * from user u,`order` o where u.id = o.oid </select>
-
配置方法2【assocation关键词】:
<resultMap id="orderMap2" type="order"> <result property="oid" column="oid"></result> <result property="ordername" column="ordername"></result> <association property="user" javaType="user"> <result property="username" column="username"></result> <result property="password" column="PASSWORD"></result> <result property="id" column="id"></result> </association> </resultMap> <select id="selectOrder" resultMap="orderMap2"> select * from user u,`order` o where u.id = o.oid </select>
-
-
mybatis一对多体映射
- 通过collection标签
<resultMap id="userMap" type="user"> <collection property="userlist" javaType="order"> <result property="ordername" column="ordername"></result> <result property="oid" column="oid"></result> </collection> </resultMap> <select id="selectUserByOrder" resultType="user"> </select>