https://mybatis.org/mybatis-3/zh/getting-started.html
mybatis是一个优秀的持久层框架,也是一个半自动的ORM框架。
将内存中的数据持久化到数据库中,优化JDBC操作。
Hibernate是一个全自动ORM框架(对象关系映射)。
(以Maven项目的使用为例)
将下面的依赖代码置于 pom.xml 文件中:
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>x.x.xversion>// 版本号
dependency>
SQL的映射xml文件示例:
<mapper namespace="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
select>
mapper>
public class Test {
public static void main(String[] args) throws IOException {
// 获取输入流对象
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
// 获取会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获取会话
SqlSession session = sqlSessionFactory.openSession();
// 获取接口对象
UserMapper userMapper = session.getMapper(UserMapper.class);
// 使用接口
User user = new User();
// user.setUserName("zh");
user.setUserSex("女");
user.setUserAdd("中国");
List<User> list = userMapper.getDynamic(user);
for (User u:list) {
System.out.println(u);
}
// 提交会话
session.commit();
}
}
配置 | 说明 |
---|---|
properties | 属性,包括一些加载数据库的SQL语句 |
setting | 设置,极为重要的调整设置,它们会改变Mybatis的运行时行为 |
typeAliases | 类型别名,可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写 |
typeHandlers | 类型处理器,用来将从数据库取得的值转换成java类型 |
objectFactory | 对象工厂,用来在帮助完成结果对象的实例化 |
plugins | 插件,用来配置各种插件,而插件可用来完成各种不能的功能 |
environments | 环境配置,用来配置一种或多种环境,但只能使用其中一种 |
databaseldProvider | 数据库厂商标识,用来根据不同的数据库厂商执行不同的语句 |
mapper | 映射器,指定所使用的SQL映射xml文件 |
<select id="allUser" resultType="com.blb.beans.User">
select * from s_user
select>
<insert id="addUser" parameterType="com.blb.beans.User">
insert into s_user values (#{id},#{username},#{password});
insert>
<update id="updateUser" parameterType="com.blb.beans.User">
update s_user set username=#{username},password=#{password},nickname=#{nickname},sex=#{sex},tel=#{tel},email=#{email},head_img=#{headImg},create_time=#{createTime},create_user=#{createUser},update_time=#{updateTime},update_user=#{updateUser},status=#{status} where id=#{id}
update>
<delete id="delUser" parameterType="java.lang.String">
delete from s_user where id=#{deleteId}
delete>
$是字符串拼接,#是占位符引用,前者可能出现注入漏洞,后者不会。
注解 | 作用 |
---|---|
@Param | 在参数前使用,可指定参数在sql语句中的的别名 |
@Select | 在方法前使用,可直接在该注解里写查询语句 |
@Insert | 在方法前使用,可直接在该注解里写插入语句 |
@Update | 在方法前使用,可直接在该注解里写修改语句 |
@Delete | 在方法前使用,可直接在该注解里写删除语句 |
开启步骤:
<setting name="logImpl" value="LOG4J"/>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
# 全局日志配置
log4j.rootLogger=ERROR, stdout
# MyBatis 日志配置
log4j.logger.com.blb.mapper=TRACE
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
使用步骤:
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.16version>
dependency>
注解 | 说明 |
---|---|
@Data | 自动加上常用方法,包括所有set/get方法、toString方法、无参构造方法等 |
@AllArgsConstructor | 自动加上全参构造方法 |
@NoArgsConstructor | 自动加上无参构造(一般用来防止有参构造的覆盖) |
用来给sql语句动态添加内容。
SELECT * FROM BLOG
WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
if>
test里的条件可以是多个,用 and 连接即可。
用来从多个内容中选择一种添加到sql。
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<choose>
<when test="title != null">
AND title like #{title}
when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
when>
<otherwise>
AND featured = 1
otherwise>
choose>
类似Java中的 switch 语句。
用来从多个内容中选择任意个添加到sql。
SELECT * FROM BLOG
<where>
<if test="state != null">
state = #{state}
if>
<if test="title != null">
AND title like #{title}
if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
if>
where>
where 元素只会在子元素返回任何内容的情况下才会插入“where”语句,而且若子句的开头为“AND”或“OR”时,也会将他们消除。
当然你也可以使用 trim 元素来自定义要消除的词,如:
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
trim>
update Author
<set>
<if test="username != null">username=#{username},if>
<if test="password != null">password=#{password},if>
<if test="email != null">email=#{email},if>
<if test="bio != null">bio=#{bio}if>
set>
where id=#{id}
set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号。
当然你也可以使用 trim 元素来自定义要消除的符号,如:
<trim prefix="SET" suffixOverrides=",">
...
trim>
使用collection的select属性来实现:
<resultMap id="aaa" type="com.blb.entity.Customer">
<id property="id" column="id">id>
<result property="name" column="name">result>
<collection property="orders" select="getOrderByCId" column="id">collection>
resultMap>
<select id="getById" resultMap="aaa">
select * from t_customer where id = #{id}
select>
<select id="getOrderByCId" resultType="com.blb.entity.Order">
select * from t_order where c_id = #{id}
select>
使用collection的ofType属性来实现:
<resultMap id="aaa" type="com.blb.entity.Customer">
<id property="id" column="id">id>
<result property="name" column="name">result>
<collection property="orders" ofType="com.blb.entity.Order">
<id property="id" column="oid">id>
<result property="orderName" column="order_name">result>
collection>
resultMap>
<select id="getById" resultMap="aaa">
select c.*, o.id oid, o.order_name from t_customer c, t_order o where c.id = o.c_id and c.id=2
select>
使用association的select属性来实现:
<resultMap id="orderMap" type="com.blb.entity.Order">
<id property="id" column="id">id>
<result property="orderName" column="order_name">result>
<association property="customer" select="getCustomerByCid" column="c_id">
association>
resultMap>
<select id="getById" resultMap="orderMap">
select * from t_order where id = #{id}
select>
<select id="getCustomerByCid" resultType="com.blb.entity.Customer">
select * from t_customer where id = #{id}
select>
使用association的JavaType属性来实现:
<resultMap id="orderMap" type="com.blb.entity.Order">
<id property="id" column="id">id>
<result property="orderName" column="order_name">result>
<association property="customer" javaType="com.blb.entity.Customer">
<id property="id" column="c_id">id>
<result property="name" column="name">result>
association>
resultMap>
<select id="getById" resultMap="orderMap">
select * from t_order o, t_customer c
where c.id = o.c_id and o.id = #{id}
select>
默认开启,SqlSession级别,执行以前执行过的api时,且参数相同的情况下,会直接使用缓存中的数据。如果执行session.commit、session.update、session.clearCache等方法时,会造成一级缓存丢失。
默认不开启,全局缓存。
开启步骤:
<settings>
<setting name="cacheEnabled" value="true"/>
settings>
<cache>cache>
<cache type="org.apache.ibatis.cache.impl.PerpetualCache">cache>
PerpetualCache这个类是mybatis默认实现缓存功能的类,可以去实现 Cache 接口来自定义缓存。