目录
Mybatis
1.谈谈MyBatis
2.Mybatis分为三层
3.Mybatis和jdbc的区别
4.映射文件
5.模糊查询:LIKE
6.$和#的区别
7.主键自增
8.API
9.SqlSession不是线程安全的
10.调用sqlSession.selectOne()还是SQLSession.selectList()是由mapper接口的返回值决定的
11.Mapper接口的参数:简单类型,pojo类型包装类型,Map,List集合等
12.指定别名
13.隐射文件的加载
14.输入参数
15.只写map的
16.动态sql的编写
17.缓存
18.Mybatis的编程步骤
19.主键自增问题
21.如何获取自动生成的(主)键值
22.使用MyBatis的mapper接口调用有哪些要求?
23.Statement和PrepareStatement的区别
Mybatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使得开发者只需要专注于SQL语句本身,而不用去关心注册驱动,创建connection等,Mybatis通过xml文件配置或者注解的方式将要执行的各种statement配置起来,并通过java对象和statement中的sql进行映射成最终执行的sql语句,最后由Mybatis框架执行sql并将结果映射成java对象并返回。
(1)API接口层:提供给外部使用的接口API
(2)数据处理层:负责具体的SQL
(3)基础支撑层:负责最基础的功能支撑,如连接管理,事务管理,配置加载和缓存处理
相比与jdbc,Mybatis具有以下优点
(1)数据库链接创建,释放频繁造成系统资源浪费会影响系统性能,使用数据库可以解决
解决:在核心配置文件SqlMapConfig.xml中配置数据链接池,使用数据链接池管理数据库链接
(2)Sql写在代码中不易于维护,修改需要变动java代码
在映射文件XXXMapper.xml文件中配置sql语句与Java代码分离
(3)向Sql语句传输参数麻烦,因为Sql语句的WHERE条件不一定,可能多也可能少,占位符需要和参数一一对应
Mybatis可以自动将Java对象映射到sql语句
(4)对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,将数据库记录封装成pojo对象解析更加方便
Mybatis可以自动将sql执行结果映射到Java对象
-
<mapper name="text">
-
-
<select id="FindByID" paramenterType="int" resultType="com.guigu.User">
-
-
select * from user where id=#{id}
-
-
select>
-
-
mapper>
namespace:名称空间 id:根据id执行sql parameterType:入参 resultType:出参 #{id} 接收的参数
-
<selectid="findByName2"
-
-
parameterType=
"java.lang.String"
resultType=
"com.gugiu.model.User">
-
-
select * from user where name like '%${value}%'
-
-
select>
修改
-
<update id="updateUserById" parameterType="com.gugiu.model.User">
-
-
update user set name = #{name},age =#{age},address=#{address}
-
-
where id =#{id}
-
-
update>
(1)#把传入的参数当做字符串处理 $表示直接显示
(2)#很大程度防止Sql注入(语句拼接)
(3)能用#尽量用#
(1)SqlSessionFactoryBuilder
通过加载MyBatisde 核心配置文件,创建SqlSessionFactory
(2)SqlSessionFactory
定义了openSession的不同重载方法
(3)sqlSession
定义了数据库的操作,增删改查
-
List
findUserByName(String name) ; selectList()
-
-
User findUserByName(String name); selectOne()
单个文件
-
<typeAliases>
-
-
<typeAlias type="com.gugiu.model.User" alias="user"/>
-
-
typeAliases>
批量
-
<typeAliases>
-
-
<package name="com.guigu.model1"/>
-
-
<package name="com.guigu.model2"/>
-
-
typeAliases>
单个文件
-
<mappers>
-
-
<!—加载单个映射文件-->
-
-
<mapper resource="com/guigu/mapper/UserMapper.xml"/>
-
mappers>
批量
-
<mappers>
-
-
<package name="com.guigu.mapper"/>
-
-
mappers>
(1)简单类型
-
<select id="findById" parameterType="int" resultType="user" >
-
-
select * from User where id = #{id} ;
-
-
select>
(2)pojo类型
-
<insert id="addUser" parameterType="com.guigu.model.User">
-
-
<selectKey keyColumn="id" order="AFTER" resultType="int">
-
-
SELECT LAST_INSERT_ID()
-
-
selectKey>
-
-
INSERT INTO user (name,age,address)
-
-
VALUE(#{name},#{age},#{address})
-
-
insert>
(3)pojo的包装类型
-
<select id="findById" parameterType="com.guigu.model.UserVo" resultType="user">
-
-
select * from User where id = #{user.id} ;
-
-
select>
(4)Map
-
<insert id="addUserMap" parameterType="hashmap">
-
-
INSERT INTO my_user(NAME,age,address) VALUE(#{name},#{age},#{address})
-
-
insert>
-
<selectid="findById" parameterType="int" resultMap="userMap">
-
-
SELECT id ,name user_name FROM my_user WHERE id = #{id}
-
-
select>
(1)if
-
<insert id="addUserVo" parameterType="com.guigu.mybatis.pojo.UserVo">
-
-
<if test="user != null">
-
-
insert into my_user (name,age,address)
-
-
value(#{user.name},#{user.age},#{user.address})
-
-
if>
-
-
insert>
(2)where
-
<select id="findByUserVo" parameterType="UserVo"resultType="User">
-
-
select * from my_user
-
-
<where>
-
-
<iftest="user!= null">
-
-
<if test="user.id != null and user.id !='' ">
-
-
and id = #{user.id}
-
-
if>
-
-
<if test="user.name != null and user.name !='' ">
-
-
and name like '%#{user.name}%'
-
-
if>
-
-
if>
-
-
where>
-
-
select>
(3)sql代码片段
-
<sql id="find_user_byId">
-
-
<if test="user.id != null and user.id !='' ">
-
-
and id = #{user.id}
-
-
if>
-
-
sql>
-
-
<sql id="find_user_byAge">
-
-
<if test="user.age != null and user.age !='' ">
-
-
and age = #{user.age}
-
-
if>
-
-
sql>
-
-
<select id="findByUserVo" parameterType="UserVo" resultType="User">
-
-
select * from my_user
-
-
<where>
-
-
<if test="user!= null">
-
-
<include ref id="find_user_byId">
include>
-
-
<include ref id="find_user_byAge">
include>
-
-
if>
-
-
where>
-
-
select>
(4)foreach
-
<insert id="addUsers" parameterType="map">
-
-
insert into my_user (name,age,address)
-
-
<if test="users != null">
-
-
values
-
-
<foreach collection="users" item="user" separator=",">
-
-
(#{user.name},#{user.age},#{user.address})
-
-
foreach>
-
-
if>
-
-
insert>
-
-
-
-
<select id="findByIds" parameterType="map" resultType="User">
-
-
<if test="userIds != null">
-
-
select * from my_user
-
-
<where>
-
-
<foreach collection="userIds" item="userId" separator="or">
-
-
id = #{userId}
-
-
foreach>
-
-
where>
-
-
if>
-
-
select>
(1)一级缓存(SqlSession级别)
MyBatis一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行
相同的sql语句,第一次执行后会将查询到的数据存储到缓存当中,第二次会从缓
存中进行查找,从而提高查询效率,当一个SqlSession结束之后,一级缓存也将不
存在,Mybatis默认开启一级缓存。
(2)二级缓存(Mapper级别)
二级缓存的作用域是mapper的同一个namespace,执行两次相同的SQL语句,第一次执行后会将查询到的数据存储到缓存当中,第二次会从缓存中进行查找,从而提高查询效率,默认不开启。
(0)创建SqlSessionFactoryBuilder
(1)通过SqlsesionFactoryBuilder创建sqlSessionFactory
(2)通过SqlSessionFactory创建sqlSession
(3)通过sqlSession执行数据库操作
(4)调用session.commit()提交事务
(5)调用session.close()关闭会话
-
publicclass MyBatisUtil {
-
-
privatestatic SqlSessionFactory factory =
null;
-
-
static {
-
-
try {
-
-
SqlSessionFactoryBuilder builder = newSqlSessionFactoryBuilder();
-
-
InputStream inputStream = Resources.getResourceAsStream(
"MyBatisConfig.xml");
-
-
//创建Session工厂
-
-
factory = builder.build(inputStream);
-
-
}
catch (Exception e) {
-
-
e.printStackTrace();
-
-
}
-
-
}
-
-
-
-
publicstatic SqlSession getSqlSession(){
-
-
//获得session会话
-
-
return factory.openSession();
-
-
}
-
-
}
20.实体类中的属性名和数据表中的列名不一致
(1)在sql语句中使用别名
(2)事先指定映射关系,这样Mybatis也能自动完成映射。Mybatis提供了resultMap标签
-
-
<resultMap type="User" id="UserResultMap">
-
-
<id column="id" property="id"/>
-
-
<result column="user_name" property="userName"/>
-
-
<result column="user_password" property="userPassword"/>
-
-
resultMap>
-
<settings>
-
-
<setting name="mapUnderscoreToCamelCase" value="true"/>
-
-
settings>
解决思路:通过LAST_INSERT_ID()获取刚插入记录的自增主键值,在insert语句执行后,执行select LAST_INSERT_ID()就可以获取自增主键。
-
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
-
-
<selectKey keyProperty="id" order="AFTER" resultType="int">
-
-
select LAST_INSERT_ID()
-
-
selectKey>
-
-
INSERT INTO USER(username,birthday,sex,address)
-
-
VALUES(#{username},#{birthday},#{sex},#{address)
-
-
insert>
(1)Mapper接口方法名和mapper.xml中定义的每个sql的id相同
(2)Mapper接口中输入的参数类型和mapper.xml中定义的每个sql的ParameterType相同
(3)Mapper接口中输出的参数类型和mapper.xml中定义的每个sql的resultType相同
(4)Mapper.xml文件中的namespace即是接口的类路径
PreparedStatement:表示预编译的 SQL 语句的对象。
(1)PrepareStatement可以使用占位符,是预编译的,批处理比Statement效率高
(2)在对数据库只执行一次性存取的时侯,用 Statement 对象进行处理。
(3)PreparedStatement的第一次执行消耗是很高的. 它的性能体现在后面的重复执行