Mybatis学习总结
mybatis
为什么学习mybatis介绍
1.目前最主流的持久层框架为hibernate与mybatis,而且国内目前情况使用Mybatis的公司比hibernate要多。
2.Hibernate学习门槛不低,要精通门槛更高。门槛高在怎么设计O/R映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好Hibernate缓存与数据加载策略方面需要你的经验和能力都很强才行。国内目前前的情况精通hibernate技术大牛非常少。
3.sql优化方面,Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。当然了,Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。说得更深入一些,如果有个查询要关联多张表,比如5张表,10张表时,而且,我们要取的字段只是其中几张表的部分字段。这时用hibernate时就会显得非常力不从心。就算用hibernate的sqlquery,后续的维护工作也会让人发狂。
JDBC回顾
- 加载数据库驱动
- 创建数据库连接
- 创建statement
- 设置sql语句
- 设置查询参数
- 执行查询,得到ResultSet
- 解析结果集ResultSet
- 释放资源
读取配置文件
Properties pro = new Properties();
InputStream in = ServletActionContext.getServletContext().getResourceAsStream("/WEB-INF/classes/upfilepath.properties");
pro.load(in);
String path = pro.getProperty("path");
JDBC存在的问题
- sql语句存在硬编码问题,不利于维护
- 链接频繁的创建,删除,消耗资源
- Sql参数设置硬编码,不利于维护
- 结果集获取与遍历复杂,存在硬编码,不利于维护,期望能够查询后返回一个java对象
Mybatis简单入门
工程搭建
1.导入依赖jar包
2.配置SqlMapConfig.xml(mybatis核心的配置文件,里面包括数据库连接池的配置和配置映射文件)
3.配置log4j.properties
4.创建pojo
5.配置sql查询的映射文件
6.加载映射文件(该文件书写对数据的操作通常把映射文件起名为模型+Mapper.xml)
映射文件
//根据id查询
<mapper namespace="user">
<select id="getUserById" parameterType="int" resultType="com.mx.pojo.User">
SELECT * FROM USER WHERE id = #{id1}
</select>
// 模糊查询
<select id="getUserByUserName" parameterType="string" resulType="com.mx.pojo.User">
// SELECT * FROM USER WHERE username LIkE #{name}
// SELECT * FROM USER WHERE username LIkE '%${value}%';
</select>
<--
这两个属性配套使用
keyProperty :用某个属性来接收
useGeneratedKeys="true" 使用自增
-->
<insert id="insertUser" parameterType="com.mxpojo.User" keyProperty="id" useGeneratedKeys="true">
<!--
selectKey:主键返回
keyProperty:user中主键的属性
resultType:主键的数据类型
order:指定selectKey何时执行
-->
<!-- <selectKey keyProperty="id" resultType="int" order="AFTER">
select last_insert_id()
</selectKey> -->
// 如果配置这个,上面的在insert上面配置的主键返回就会失效
<selectKey keyProperty="uuid" resultType="string" order="BEFORE">
select uuid()
</selectKey>
INSERT INTO `user`
(`username`,
`birthday`,
`sex`,
`address`)
VALUES (#{username}, // 直接取出pojo的属性值
#{birthday},
#{sex},
#{address});
</insert>
// 更新用户
<update id="updateUser" parameterType="com.mx.pojo.User">
update `user` set `username` = #{username}
where `id`= #{id};
</update>
<delete id ="deleteUser" parameterType="int">
DELETE FROM
`user` WHERE `id`=#{id};
</delete>
- namespace:命名空间,用于隔离sql语句
- id:语句的唯一标识
- parameterType:入参的数据类型
- resultType:返回结果的数据类型在
- #{}:占位符,相当于JDBC的?
- ${}:字符串拼接符,如果入参是基本类型,只能呢写value,如果是pojo,填写pojo的属性就好。
配置文件
在配置文件中加入映射文件
@Test
public void testGetUserById() throws Exception {
// 创建SqlSessionFactoryBuild对象
SqlSessionFactoryBuild ssfb = new SqlSessionFactoryBuild();
// 创建核心配置文件的输入流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = ssfb.build(inputStream);
// 创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession('true');// 设置为true的话会自动提交事务
// 执行查询
// 根据id查询
User user = sqlSession.selectOne("user.getUserById",1);
// 根据用户名模糊查询,没用字符串拼接
List<user> list = sqlSession.selectList("user.getUserByUserName","%张%");
// 用了字符串拼接
List<user> list = sqlSession.selectList("user.getUserByUserName","张");
// 插入用户,返回影响的函数。
。。。此处省去用户设置数据
int insert = sqlSession.insert("user.insertUser",user);
// 更新用户
SqlSession.update("user.updateUser",user);
// 删除用户
sqlSession.delete("user.deleteUser",33);
// 提交事务,删除和更新的时候。
// sqlSession.commit();
sqlSession.close();
}
Mybatis执行步骤
执行步骤按照序号标识
1. SqlSessionFactoryBuilder(方法级别,创建完成加载完文件便可销毁)
2. 加载配至文件:核心配置文件、映射文件
3. SqlSessionFactory(工程级别,一个工程需要一个即可)
4. SqlSession(接口)
5. 执行器
6. Map、单数据类型、pojo --输入映射--> MapperSteatment --输出映射-->Map、List、pojo、简单数据类型
7. 数据库
Mybatis开发Dao
1.原始方式:
public interface UserDao {
// 根据用户id查询用户信息
User getUserById(Integer id);
// 根据用户名查询
List<User> getUserBYUserName(String userName);
// 插入用户信息
void insertUser(User user);
}
public class UserDaoImple implements UserDao {
public User getUserById(Integer id) {
SqlSession sqlSessio = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
User user = sqlSession.selectOne("user.getUserById",id);
sqlSession.close();
return user;
}
public List<User> getUserByUserName(String userName) {
SqlSession sqlSessio = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
List<user> list = sqlSession.selectList("user.getUserName",userName);
return list;
}
public void insertUser(User user) {
SqlSession sqlSessio = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
sqlSession.insert(user.insertUser",user);
sqlSession.commit();
sqlSession.close();
}
2.动态代理方式包装dao
动态代理只有接口不用开发人员自己写实现类。
开发规则
- 在映射文件中namespace必须是接口的全路经名。
- 接口的方法名必须与sql id 一致。
- 接口的入参parameterType类型必须一致。
-
接口的返回值必须与resultType类型一致。
<mapper namespace="com.mx.dao.UserDao">
<select id="getUserById" parameterType="int" resultType="com.mx.pojo.User">
SELECT * FROM USER WHERE id = #{id1}
</select>
</mapper>// 通常我们把接口放在mapper包内,这里包UserDao更名为UserMapper.
@Test
public void testGetUserById() {
SqlSession sqlSession = sqlSessionFactoryUtils.getSqlSessionFactroy().openSesion();
// 获取接口的代理实现类
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.getUserById(30);
sqlSession.close();
}
sqlMapConfig 详情
-
properties:属性
// resource 是基于类路径下的。
// 先加载内部文件,再加载外部文件,当发现name属性相同,则替换内容。
-
别名配置
<typeAliases>
// 单个别名的配置,别名不区分大小写
<typeAlias type="con.mx.pojo.User" alias="user"/>
//别名包扫描,别名是类的全称,不区分大小写
<pacKage name="">
</typeAliases> -
映射文件的配置
-
传统dao只有第一种加载方式
-
动态代理可以使用第二种或者第三种配置方式
<mappers>
// 第一种配置方式
<mapper resource="mybatis/user.xml">
<mapper resource="mybatis/UserMapper.xml">
// 第二种配置方式
// 映射文件,类扫描器,符合要求是:1.映射文件和接口文件必须在同一文件目录下。2.接口的名称和映射文件的名称必须一致。
<mapper class="com.mx.mapper.UserMapper"/> // 接口的路径
// 第三种配置方式(推荐)
// 映射文件包扫描,满足要求::1.映射文件和接口文件必须在同一文件目录下。2.接口的名称和映射文件的名称必须一致
<packge name="com.mx.mapper"/>
</mappers>