mybatis
上半段
阶段一
简介:是一个持久层的框架,封装了JDBC
功能:连接数据库,操作数据库中的数据
特性:支持定制化SQL,屏蔽所有JDBC代码,使
用XML和注解配置,数据库映射到JAVA对象
其他持久层对比:JDBC硬编码,效率低,
Hibernate简单,效率高,但不易复杂化,
mybatis可以复杂定制,效率略低于Hibernate
实现
1.数据库中创建对应表
2.pom.xml依赖
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</
artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
3.创建com.xxx.pojo/User类、com.xxx.
mapper/UserMapper接口
4resources/mapper/UserMapper.xml,
resources/mapper/jdbc.properties文件
<?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="org.mybatis.example.
BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
</mapper>
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.username=root
jdbc.password=root
5.resources/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">
<configuration>
<!--引入properties文件后,可以使用${key}的
方式访问value-->
<properties resource="jdbc.properties"/>
<!--environments配置连接数据库的环境。
属性:default:设置默认使用的环境的id-->
<environments default="development">
<!-- environment设置一个具体的链接数
据库的环境。属性:id:设置环境的唯一标识,不
能重复-->
<environment id="development">
<!--transactionManager事务管理器。
属性:type:设置事务管理的方式,type="JDBC|
MANAGED"
JDBC:表示使用JDBC中原生的事务管理
方式,MANAGED:被管理,例如Spring-->
<transactionManager type="JDBC"/>
<!--dataSource设置数据源。属性type:
设置数据源类型,type="POOLED|UNPOOLED|
JNDI"。
POOLED:表示使用数据库连接池,
UNPOOLED:不使用连接池,JNDI:表示使用上
下文中的数据源-->
<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>
<!--引入mybatis的映射文件-->
<mappers>
<mapper resource="mapper\
UserMapper.xml"/>
<!--以包的方式引入映射文件,必须满足
1.mapper接口和映射文件所在的包必须一
致 2.mapper接口的名字和映射文件的名字必须
一致-->
<package name="com.atguigu.mybatis.
mapper"/>
</mappers>
</configuration>
在resources创建包的时候要注意,若直接用.的
方式创建包,会全部变成文件名,不会形成目
录。要以com/atguigu/mybatis/mapper,才能
形成目录层级
6.resources/log4j.xml配置文件
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "
log4j.dtd">
<log4j:configuration xmlns:log4j="http://
jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.
apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-
8"/>
<layout class="org.apache.log4j.
PatternLayout">
<param name="ConversionPattern"
value="[%p][%d{yyyy-MM-dd HH:mm:ss
SSS}][%c]-[%m]%n"/>
</layout>
</appender>
<logger name="java.sql">
<level value="debug"/>
</logger>
<logger name="org.apache.ibatis">
<level value="info"/>
</logger>
<root>
<level value="debug"/>
<appender-ref ref="STDOUT"/>
</root>
</log4j:configuration>
7.实现步骤
public static void main(String[] args)
throws IOException {
//获取核心配置文件的输入流-is
InputStream is = Resources.
getResourceAsStream("mybatis-config.xml");
//获取SqlSessionFactoryBuilder对象-
sqlSessionFactoryBuilder
SqlSessionFactoryBuilder
sqlSessionFactoryBuilder = new
SqlSessionFactoryBuilder();
//获取SqlSessionFactory对象-
SqlSessionFactory,传参:输入流is
SqlSessionFactory SqlSessionFactory =
sqlSessionFactoryBuilder.build(is);
//获取Sql的会话对象-SqlSession,是
Mybatis提供操作数据库的对象,参数设置为
true,自动提交事务
SqlSession sqlSession =
SqlSessionFactory.openSession(true);
//获取UserMapper的代理实现类对象,为接
口类创建一个实现类并返回
UserMapper mapper = sqlSession.
getMapper(UserMapper.class);
//调用mapper接口中的方法,实现功能
int i = mapper.insertUser();
System.out.println("插入条数i = " + i);
//提交事务,不提交,不会插入到数据库,或者
在SqlSessionFactory.openSession(true);
// sqlSession.commit();
//关闭会话
sqlSession.close();
}
xml文件
INSERT
<!--接口的全类名-->
<mapper namespace="com.atguigu.
mybatis.mapper.UserMapper">
<!--接口中方法名 //增加用户 int
insertUser();-->
<insert id="insertUser">
insert into t_user values(null,'admin','
123456','23','男','597@qq.com');
</insert>
</mapper>
SELECT
1.resultType
2.查询单条数据,resultType参数使用全类名
<select id="getUserById" resultType="com.
atguigu.mybatis.pojo.User">
select * from t_user where id = 1
</select>
3.查询多条数据,返回List<User>集合,
resultType参数仍然使用全类名
<select id="getAllUser" resultType="com.
atguigu.mybatis.pojo.User">
select * from t_user
</select>
IDEA中创建模板文件
阶段二
Mybatis获取参数值的两种方式:${}和#{}
${}本质是字符串拼接
若为字符串类型要手动加' '单引号 eg: '${
username}'
#{}本质是占位符赋值 若为字符串会自动添加单引号
传入单个或多个参数
(参数名作为KEY,在底层会放到一个MAP集合
中)
//通过单个参数查询整个User信息
User getUserByUsername(@Param("
username") String username);
<select id="getUserByUsername"
parameterType="String" resultType="com.
atguigu.mybatis.pojo.User">
select *from t_user WHERE
username = #{username}
</select>
//通过多个参数查询整个User信息
User getUserByUsername(@Param("
username") String username,@Param("
age") String age);
<select id="getUserByUsername"
parameterType="String" resultType="com.
atguigu.mybatis.pojo.User">
select *from t_user WHERE
username = '${username}' AND age=#{age}
</select>
//通过传入一个对象查询整个User信息
User getUserByUsername(User user);
<insert id="insertUser">
insert into t_user values(null,#{
username},#{password},#{age},#{gender},#{
email});
</insert>
通过Map的方式来接收返回数据,查询单个数据
通过List<Map<String,Object>>的方式来接收
返回数据,查询多条数据
也可以通过注解@MapKey("id"),将id作为大的
map键
特殊SQL执行,不能使用#{},只能使用${}
模糊查询
错误语句:select *from t_user WHERE
username LIKE '%#{likeSearch}%'
select *from t_user WHERE username
LIKE '%?%' 上一句会被解析成这样
由于?处于单引号之中,会被认为此句中只有字符
串,没有?占位符,预编译对象无法给占位符赋
值,故错误
正确语句:select *from t_user WHERE
username LIKE concat ('%',#{likeSearch},'%' )
正确语句:select *from t_user WHERE
username LIKE "%"#{likeSearch}"%" 最常用
批量删除
错误语句:delete from t_user where id in (#{
ids})
delete from t_user where id in ('1,2,3') 上一句
会被解析成这样,( )里不能加单引号
正确语句:delete from t_user where id in (${
ids})
动态设置表名
错误语句:select * from #{talbeName}
select *from 't_user' 上一句会被解析成这样,表
名后是不能加单引号的
正确语句:select * from $talbeName}
添加功能获取->自增的主键
<!--在插入的时候获取自增主键,
useGeneratedKeys:是否使用自增主键,设为
true
keyProperty:自增的主键赋值给哪个属
性,这里设为id
-->
<insert id="insertUser"
useGeneratedKeys="true" keyProperty="
id">
insert into t_user values(null,'admin','
123456','23','男','597@qq.com');
</insert>
阶段三
处理数据库字段名和java属性名不一致问题,
字段名一般是emp_name,属性名一般是
empName
可通过起别名方式映射对应:
<select id="getUserByUsername"
resultType="com.atguigu.mybatis.pojo.
Emp">
select emp_name empName from t_
user
</select>
可以在Mybatis核心配置文件mybatis-config.
xml中设置,自动将下划线映射为驼峰
<settings>
<!--将下划线映射为驼峰-->
<setting name="
mapUnderscoreToCamelCase" value="
true"/>
</settings>
可以用resultMap映射方式
一对一
一对多
1.级联方式
2.association多对一方式:处理实体类类型数据
分步查询:实现延时加载,提升效率,分步查询
步骤
全局启用延迟(按需)加载
在全局启用延迟加载情况下,若要某一个查询为
完全加载,
可设置为eager(立即加载),而不用lazy(延迟
加载)
第二步也要有对应接口 第二步也要有对应Mapper
第二步:实践
properties:返回值类型
select:mapper.xml文件中sql语句id
column:传参
当emp只需要getEmpName,无需dept数据
时,只执行第一步语句
当emp需要dept数据时,执行第一步语句后同时
需要执行第二步语句
3.collection一对多方式:处理集合类数据类型 类属性 分步查询
properties:返回值类型
select:mapper.xml文件中sql语句id
column:传参
下半段
阶段一 动态SQL语句
if:通过test属性中的表达式判断标签中的内容是
否有效(是否会拼接到sql中)
<if test="username != null and
username != '' ">
and username = #{username}
</if>
where:
a.若where标签中有if条件成立,会自动生成
where关键字
b.会自动将where标签中内容前多余and去掉,
内容后多余的and无法去掉
c.若where标签中没有条件成立,则where不会
生成
<where>
<if test="username != null and
username != '' ">
and username = #{username}
</if>
</where>
trim:
1.prefix、suffix:在标签中内容的前面、后面添
加指定内容
2.prefixOverrides、suffixOverrides:在标签中
内容前面后面去掉指定内容
<select id="getUserByUsername"
resultType="com.atguigu.mybatis.pojo.
Emp">
select emp_name empName from t_
user
<trim prefix="where" suffixOverrides="
and">
<if test="username != null and
username != '' ">
and username = #{username}
</if>
</trim>
</select>
choose、when、otherwise:
1.相当于if...else if( ) 语句,多个<when>语句,
执行其中一条后,
其他均不执行,<when>都不满足,则执行<
otherwise>
<where>
<choose>
<when test="username != null and
username != ''">
username = #{username}
</when>
<when test="age != null and
age != ''">
age = #{age}
</when>
<otherwise>
gender = #{gender}
</otherwise>
</choose>
</where>
foreach:
常用于批量添加、删除,注意values后面的( )的
位置
collection:要循环的数组或集合
item:集合或数组中的每一个数据
separator:循环间的分隔符
open:循环内容以什么开始
close:循环内容以什么结尾
<!--void insertUser(List<Users> users)-->
<insert id="insertUser">
insert into t_user values
<foreach collection="users" item="
user" separator=",">
(null,#(user.username),#(user.age),#(
user.gender))
</foreach>
</insert>
左边的语句等同于for语句,分隔符
separator=","逗号
for (User user : users) {
}
<!-- void DelUser(@Param("empIds)
Integer[] empIds) -->
<delete id="delUser">
delete from t_user where user_id in
(
<foreach collection="empIds" item="
empId" separator="or">
#{empId}
</foreach>
)
</delete>
sql片段:可以记录一段sql,在需要的地方引用
<sql id="empColumns">
emp_id,emp_name,age,gender
</sql>
<select id="emp">
select <include refid="empColumns"/>
from t_user
</select>
阶段二
MyBatis缓存(存入内存)
一级缓存(默认开启)
一级缓存是SqlSession级别的,通过同一个
SqlSession查询的数据会被缓存,下次查询相同
的数据,就会从缓存中直接获取,不会到数据库
中访问
一级缓存失效的情况
1.不同SqlSession对应不同的一级缓存
2.同一个SqlSession,查询条件不同
3.同一个SqlSession两次查询期间执行了增删改
操作
4.同一个SqlSession两次查询期间手动清空了缓
存
二级缓存
二级缓存是SqlSessionFactory级别的,通过同
一个,同一个,同一个SqlSessionFactory创建
的SqlSession对象查询的结果会被缓存;此后若
再次执行相同的查询语句,结果就会从缓存中获
取
二级缓存实践
a.默认是true,无需设置
b.在映射文件中设置标签<cache/>
c.SqlSession提交或关闭后,将一级缓存的数据
保存到二级缓存
d.实体类必须实现序列化接口
二级缓存失效的情况
两次查询之间执行了增删改,会使得一二级缓存
同时失效
整合第三方缓存EHCache,看尚硅谷SSM视频
阶段三 分页插件
添加依赖和配置分页插件
//执行SQL查询语句之前,开启分页功能,
查第一页,查10条数据
PageHelper.startPage(1,10);
List<User> userList = mapper.
selectAllUser();
//查询之后可以获取到分页相关的所有数据
PageInfo<User> data = new
PageInfo<>(userList);
PageInfo的参数
评论0