JAVAEE框架技术之7-myBatis ORM框架入门基础CRUD
Posted teayear
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVAEE框架技术之7-myBatis ORM框架入门基础CRUD相关的知识,希望对你有一定的参考价值。
MyBatis
ORM概述
在使用JDBC 的时候,我们通常将数据直接返回,但现在也会将数据封装到实体类对象中,由对象携带数据。这样操作的时候,可以通过操作对象的方式操作数据。但是手写这类代码通常是繁琐的、重复的,如果有自动完成这些功能的程序就好了。
ORM
(Object-Relational-Mapping):是对象关系映射的意思,它是一种思想,是指将数据库中的每一行数据用对象的形式表现出来。可以将 ORM 简单理解为上面我们提出的,可以自动将对象与数据进行映射的技术。
Java | 数据库 |
---|---|
类 | 表 |
对象 | 一行数据(表中的某行数据) |
属性 | 列(一行数据中的某个列) |
常见ORM框架
Hibernate
优点
- 简化了整个jdbc操作过程
- 对于开发者来说不需要关心sql了,只需要去操作对象就可以了,hibernate可以帮我们自动生成所需要的sql
- 代码移植性比较好,通过hibernate操作db都是通过操作对象来进行的,而hibernate会根据我们的操作和db的类型生成符合各种db要求的sql,如果我们需要切换db的类型,hibernate会自动适应,对于开发者业务代码来说不需要做任何业务代码上的调整
- 开发效率比较高
即使开发人员不知道sql,也能使用Hibernate来完成数据的CRUD的操作
缺点
- sql优化比较艰难,各种操作最终发给db的sql是由hibernate自动生成的,对于开发者来说如果想干预最终需要执行的sql,相对来说比较困难
- hibernate入门比较容易,但是想成为高手学习成本比较高
- 对于复杂的动态sql,代码中也需要写很多判断进行组装,动态sql这块的支持比较欠缺
如果做一些简单的系统,开发周期也比较紧急,对sql的优化要求也不是很高,可以使用hibernate。
JdbcTemplate
jdbctemplate是在spring框架的基础上开发的一个jdbc框架,所以对spring是有依赖的,它对jdbc做了封装,隐藏了各种重复的操作,使用时只需传入:需要执行的sql、参数以及对于结果如何解析的程序就可以了,使用起来还是很方便的,但是面对与动态sql,它也是无能为力了。整体上来说,jdbctemplate相对于纯jdbc隐藏了很多重复性的操作,对于sql的写法和结果的组装上完全交给了开发者自己去控制,在系统中使用也可以帮助我们节约很多时间,而且学习相当简单.
MyBatis
MyBatis简介
MyBatis是一个半自动化的orm框架,为什么说是半自动化的呢,因为他需要我们自己去写sql,而他做的更好的地方就是动态sql
的支持上面,而上面说的各种技术,面对与动态sql只能自己写很多判断去组装sql,而这些判断和组装在mybatis中实现起来就非常简单了,完全由mybatis去帮我们实现了。mybatis将sql交由开发者去控制,所以在sql的优化方面,开发者可以随心所欲,也就是说mybatis将重复性的工作优化到了极致:操作db的过程、动态sql的拼装、结果和对象的映射
,这些mybatis都帮我们实现的很好,而让我们将更多的经历花在sql的写法和优化上面,所以毫无疑问mybatis使用人数和公司也是最多的。
MyBatis概述
MyBatis官网地址:https://mybatis.org/mybatis-3/zh/index.html
1. mybatis是一个半自动化的持久层框架
2. mybatis封装了jdbc的很多细节,开发者只需要关注sql本身,无需关注注册驱动 获取连接等操作
3. mybatis使用ORM思想来对结果集一个封装
MyBatis 优缺点
-
优点
- 简单易学,容易上手(相比于 Hibernate ) : 基于SQL编程 - 消除了JDBC大量冗余的代码,不需要手动开关连接 - 很好的与各种数据库兼容(因为 MyBatis 使用JDBC来连接数据库,所以只要JDBC 支持的数据库 MyBatis 都支持,而JDB提 供了可扩展性,所以只要这个数据库有针对Java的jar包就可以就可以与 MyBatis 兼容),开发人员不需要考虑数据库的差异性。 - 提供了很多第三方插件(分页插件 / 逆向工程) - 能够与Spring很好的集成 - 如果`使用映射文件`的话,可以让代码和配置文件完全分离。只要方法的定义没有改变,那么只需要修改配置文件就可以达到修改的目的。
-
缺点
- SQL语句的编写工作量较大,尤其是字段多、关联表多时,更是如此,对开发人员编写SQL语句的功底有一定要求。
- SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库
Mybatis的工作原理
mybatis快速入门
数据库准备
CREATE TABLE `tb_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_name` varchar(20) DEFAULT NULL,
`sex` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
导入依赖
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
<scope>provided</scope>
</dependency>
编写全局配置文件
- mybatis-config.xml
<configuration>
<!--引入外部jdbc.properties文件-->
<properties resource="jdbc.properties"/>
<!--连接数据库-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="$driver"/>
<property name="url" value="$url"/>
<property name="username" value="$username"/>
<property name="password" value="$password"/>
</dataSource>
</environment>
</environments>
<!-- <mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>-->
</configuration>
jdbc.properties文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql:///mybatis
username=root
password=root
pojo实体类
@Data
public class User
private int id;
private String userName;
private String sex;
实现操作
参照官网API学习:https://mybatis.org/mybatis-3/zh/index.html
public class TestMybatis
public static void main(String[] args) throws IOException
//获取核心配置文件
String resource = "mybatis-config.xml";
//加载配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//构建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//构建SqlSession对象
try (SqlSession session = sqlSessionFactory.openSession())
//执行sql
User user = (User) session.selectOne("abc.selectById", 4);
System.out.println(user);
Mapper.xml映射文件
<?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="abc">
<!--
select: 标签可以发送select sql
id: select标签的唯一标识
resultType: 查询返回的结果
#id : 传递过来的参数
-->
<select id="selectById" resultType="cn.yanqi.pojo.User">
select * from tb_user where id = #id
</select>
</mapper>
加载sql映射文件
- mybatis-config.xml 加载sql映射文件(别忘了)
<!--加载mapper映射文件-->
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
测试
添加日志支持
以上虽然可以实现际,但并没有看发送的sql和参数,我们可以加入日志
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
</dependency>
- log4j.properties
log4j.rootLogger=DEBUG,A1
log4j.logger.org.mybatis=DEBUG
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-dyyyy-MM-dd HH:mm:ss,SSS [%t] [%c]-[%p] %m%n
CRUD操作
dao层代码准备
- 接口 userDao
package cn.yanqi.dao;
import cn.yanqi.pojo.User;
import java.util.List;
/**
* @Dese: dao层接口
*/
public interface UserDao
/**
* 根据id查询用户信息
* @param id
* @return
*/
public User queryUserById(int id);
/**
* 查询所有用户信息
* @return
*/
public List<User> queryAllUser();
/**
* 根据id删除用户信息
* @param id
*/
public void deleteUserById(int id);
/**
* 添加用户信息
* @param user
*/
public void addUser(User user);
/**
* 修改用户信息
* @param user
*/
public void updateUser(User user);
- 实现类 UserDaoImpl
public class UserDaoImpl implements UserDao
//需要sqlsession对象,可以操作crud
private SqlSession sqlSession;
//临时解决方案
public UserDaoImpl(SqlSession sqlSession)
this.sqlSession = sqlSession;
//根据id来查询用户
@Override
public User queryUserById(int id)
return sqlSession.selectOne("abc.queryUserById", id);
//查询所有
@Override
public List<User> queryAllUser()
return sqlSession.selectList("abc.queryAllUser");
//删除用户
@Override
public void deleteUserById(int id)
sqlSession.delete("abc.deleteUserById",id);
//添加用户
@Override
public void addUser(User user)
sqlSession.insert("abc.addUser",user);
//修改用户
@Override
public void updateUser(User user)
sqlSession.update("abc.updateUser",user);
编写User对应的UserMapper.xml
<?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="abc">
<!--修改 #name pojo类属性一样 -->
<update id="updateUser">
UPDATE tb_user SET
user_name = #userName, sex = #sex WHERE id = #id;
</update>
<!--添加user-->
<insert id="addUser">
INSERT INTO tb_user(id, user_name, sex)
VALUES (#id, #userName, #sex)
</insert>
<!--根据id删除-->
<delete id="deleteUserById">
delete from tb_user where id = #id
</delete>
<!--查询所有-->
<select id="queryAllUser" resultType="cn.yanqi.pojo.User">
select * from tb_user
</select>
<!--根据id进行查询-->
<select id="queryUserById" resultType="cn.yanqi.pojo.User">
select * from tb_user where id = #id
</select>
<!--
id: 是select的一个唯一标识
resultType: 查询要返回的结果,书写结果集的全路径
#id: 获取转递过来的参数,相当于?
-->
<select id="selectById" resultType="cn.yanqi.pojo.User">
select * from tb_user where id = #id
</select>
</mapper>
加载sql映射文件
- 在mybatis-config.xml里面引入UserMapper.xml
<!--加载mapper映射文件-->
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
去除xml中校验sql
编写测试
public class UserDaoTest
private UserDao userDao;
private SqlSession sqlSession;
//在执行test测试之前一定会执行Before
@Before
public void setUp() throws Exception
//指定核心配置文件的位置
String resource = "mybatis-config.xml";
//加载核心配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//构建sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象,SqlSession可以操作crud
sqlSession = sqlSessionFactory.openSession();
//SqlSession进行数据库操作
userDao = new UserDaoImpl(sqlSession);
/**
* 根据id进行查询
*/
@Test
public void queryUserById()
User user = this.userDao.queryUserById(1);
System.out.println(user);
/**
* 查询所有
*/
@Test
public void queryAllUser()
List<User> users = this.userDao.queryAllUser();
for (User u : users)
System.out.println(u);
/**
* 根据id进行删除
*/
@Test
public void deleteUserById()
this.userDao.deleteUserById(3);
sqlSession.commit();//需要手动提交事务
/**
* 添加
*/
@Test
public void addUser()
User user = new User();
user.setId(11);
user.setPassworld("123");
user.setUserName("tom");
user.setSex("男");
this.userDao.addUser(user);
sqlSession.commit();
/**
* 修改
*/
@Test
public void updateUser()
User user = new User();
user.setId(11);
user.setPassworld("123");
user.setUserName("yiyaniandyanqi");
user.setSex("女男");
this.userDao.updateUser(user);
sqlSession.commit();
字段名和属性名不一致的问题
查询数据的时候,查不到userName的信息,
原因:数据库的字段名是user_name pojo中的属性名字是userName
解决方案1:在sql语句中使用别名(麻烦)
Select * , user_name as username from t_user;
解决方案2:参考驼峰匹配 --- mybatis-config.xml 的时候
解决方案3: 参考后面的resultMap –mapper具体的配置的时候
mybatis中dao层的命名规则
在mybatis中dao层的接口的名字不在使用xxDao 而是修改成xxMapper
例如:把UserDao,修改成UserMapper
思考CURD的dao中的问题
接口->实现类->mapper.xml
思考:能否只写UserDao接口,不书写实现类UserDaoImp,只编写Mapper.xml即可
名称空间
接口的全类名 要和 sql映射文件中的namespace保持一致
接口的方法史 要和 sql映射文件中的标签名保持一致
修改测试类
mybatis-config 配置
驼峰匹配
开启驼峰匹配:从经典数据库的命名规则user_name,到经典java命名规则的映射userName
java命名规则:
驼峰书写,大小写区分两个单词的界限。举例: userName;
数据库经典命名规则:
两个单词之间,使用下划线分割。举例:user_name
开启驼峰匹配:相当于去掉数据库名字中的下划线,然后在与java中的属性名进行对应。
数据库中的user_name 和java属性中的 userName 是一样的
- mybatis-config.xml
<!--开启驼峰匹配-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
typeAliaseso类别名
- mybatis-config.xml
<!--类别名-->
<typeAliases>
<!--方式一:指定具体的实体类-->
<typeAlias type="cn.yanqi.pojo.User" alias="User"/>
<!--方式二:扫描pojo包下所有实体类,类别名不区别大小写。建议大家直接写类名即可-->
<package name="cn.yanqi.pojo"/>
</typeAliases>
- UserMapper.xml
<!--查询所有-->
<!--resultType 返回的类型,可以直接使用类别名-->
<select id="queryAllUser" resultType="User">
select * from tb_user
</select>
typeHandlers(类型处理器)
environments环境
其实我们后开发中,不止一个环境,例如:开发环境,测试环境,发布环境等
可以在项目中设置多环境
<!--连接数据库-->
<environments default="development">
<!--默认环境-->
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="$driver"/>
<property name="url" value="$url"/>
<property nameJAVAEE框架技术之7-myBatis ORM框架入门基础CRUD
JAVAEE框架技术之8-myBatis ORM框架技术参数和动态SQL语句
JAVAEE框架技术之8-myBatis ORM框架技术参数和动态SQL语句