一、mybatis基础
1、mybatis实现步骤
①、创建实体类
package com.lagou.domain;
import java.util.Date;
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
②、编写接口文件
package com.lagou.mapper;
import com.lagou.domain.User;
import java.util.List;
public interface UserMapper {
public List<User> findAll() throws Exception;
}
③、编写映射配置文件
<?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="com.lagou.mapper.UserMapper">
<!--查询所有-->
<select id="findAll" resultType="user">
select * from user
</select>
</mapper>
④、编写SqlMapConfig.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">
<configuration>
<!-- 取别名 -->
<typeAliases>
<typeAlias type="com.lagou.domain.User" alias="user"></typeAlias>
</typeAliases>
<!--环境配置-->
<environments default="mysql">
<!--使用MySQL环境-->
<environment id="mysql">
<!--使用JDBC类型事务管理器-->
<transactionManager type="JDBC"></transactionManager>
<!--使用连接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis_db?characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--加载映射配置-->
<mappers>
<mapper resource="com.lagou.mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
⑤、编写测试代码
package com.lagou.test;
import com.lagou.domain.User;
import com.lagou.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
public class MybatisTest {
/*
快速入门测试方法
*/
@Test
public void mybatisQuickStart() throws Exception {
//1.加载核心配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//2. 获取sqlSessionFactory工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//3. 获取sqlSession会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = userMapper.findAll();
//4. 执行sql 参数:statementid : namespace.id
//List<User> users = sqlSession.selectList("UserMapper.findAll");
//5. 遍历打印结果
for (User user : userList) {
System.out.println(user);
}
//6. 关闭资源
sqlSession.close();
}
}
2、核心配置文件
①、environments标签
<!--environments: 运行环境-->
<environments default="development"> <!-- 指定默认的环境名称 -->
<environment id="development"> <!-- 指定当前环境名称 -->
<!--当前的事务事务管理器是JDBC-->
<transactionManager type="JDBC"></transactionManager>
<!--数据源信息 POOLED:使用mybatis的连接池-->
<dataSource type="POOLED">
<!-- 数据源配置的基本参数 -->
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
其中,事务管理器(transactionManager)类型有两种:
JDBC:这个配置就是直接使用了JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。
MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。例如:mybatis与spring整合后,事务交给spring容器管理。
其中,数据源(dataSource)常用类型有三种:
UNPOOLED:这个数据源的实现只是每次被请求时打开和关闭连接。
POOLED:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来。
JNDI :这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的数据源引用
②、properties标签
<!--加载properties文件-->
<properties resource="jdbc.properties"></properties>
开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///springbootdata
jdbc.username=root
jdbc.password=root
③、typeAliases标签
<!--设置别名-->
<typeAliases>
<package name="com.lagou.domain"/>
</typeAliases>
用于给实体类设置别名
④、mappers标签
<!--引入映射配置文件-->
<mappers>
<package name="com.lagou.mapper"/>
</mappers>
用于引入映射配置文件
二、配置文件深入
1、ResutlMap
<resultMap id="CommentResultMap" type="com.lagou.domain.Comment">
<id property="id" column="id"/>
<result property="content" column="content"/>
<result property="author" column="author"/>
<result property="a_id" column="a_id"/>
</resultMap>
id属性:此标签唯一标识
type:封装后的实体类型
id标签:表中主键字段封装
result标签:表中普通字段封装
property:实体的属性名
colum:表中字段名
2、${} 与 #{} 区别
#{} :表示一个占位符号
通过 #{} 可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。#{} 可以接收简单类型值或pojo属性值。如果parameterType传输单个简单类型值, #{} 括号中可以是value或其它名称。
${} :表示拼接sql串
通过 ${} 可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换,会出现sql注入问题。${} 可以接收简单类型值或pojo属性值。如果parameterType传输单个简单类型值, ${} 括号中只能是value。
3、selectKey
<!--
selectKey 适用范围广,支持所有类型数据库
keyColumn="id" 指定主键列名
keyProperty="id" 指定主键封装到实体的id属性中
resultType="int" 指定主键类型
order="AFTER" 设置在sql语句执行前(后),执行此语句
-->
<insert id="save" parameterType="user">
<selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID();
</selectKey>
INSERT INTO `user`(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address})
</insert>
用于返回操作数据的主键
4、多表查询
①、多对一
<resultMap id="orderMap" type="com.lagou.domain.Order">
<id column="id" property="id"></id>
<result column="ordertime" property="ordertime"></result>
<result column="money" property="money"></result>
<!--
一对一(多对一)使用association标签关联
property="user" 封装实体的属性名
javaType="user" 封装实体的属性类型
-->
<association property="user" javaType="com.lagou.domain.User">
<id column="uid" property="id"></id>
<result column="username" property="username"></result>
<result column="birthday" property="birthday"></result>
<result column="sex" property="sex"></result>
<result column="address" property="address"></result>
</association>
</resultMap
②、一对多
<resultMap id="userMap" type="com.lagou.domain.User">
<id column="id" property="id"></id>
<result column="username" property="username"></result>
<result column="birthday" property="birthday"></result>
<result column="sex" property="sex"></result>
<result column="address" property="address"></result>
<!--
一对多使用collection标签关联
property="orderList" 封装到集合的属性名
ofType="order" 封装集合的泛型类型
-->
<collection property="orderList" ofType="com.lagou.domain.Order">
<id column="oid" property="id"></id>
<result column="ordertime" property="ordertime"></result>
<result column="money" property="money"></result>
</collection>
</resultMap>
<select id="findAllWithOrder" resultMap="userMap">
SELECT *,o.id oid FROM USER u LEFT JOIN orders o ON u.`id`=o.`uid`;
</select>
三、加载策略
1、延迟加载
①、在核心配置文件中开启延迟加载功能
<!--开启全局延迟加载功能-->
<setting name="lazyLoadingEnabled" value="true"/>
②、在核心配置文件中设置延迟加载方法
<!--设置延时加载方法-->
<setting name="lazyLoadTriggerMethods" value="toString()"/>
③、在映射文件中设置延迟加载属性
<collection property="commentList" column="id" ofType="comment" select="com.lagou.mapper.CommentMapper.findCommentByAid" fetchType="lazy">
</collection>
2、缓存
①、一级缓存:一级缓存是SqlSession级别的缓存,是默认开启的 所以在参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用一个Mapper方法,往往 只执行一次SQL,因为使用SelSession第一次查询后,MyBatis会将其放在缓存中,以后再查询的时 候,如果没有声明需要刷新,并且缓存没有超时的情况下,SqlSession都会取出当前缓存的数据,而不 会再次发送SQL到数据库。
②、二级缓存:二级缓存是namspace级别(跨sqlSession)的缓存,是默认不开启的 二级缓存的开启需要进行配置,实现二级缓存的时候,MyBatis要求返回的POJO必须是可序列化的。 也就是要求实现Serializable接口,配置方法很简单,只需要在映射XML文件配置
<cache/>
就可以开启 二级缓存了。