官方这样解释:
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
简而言之,所有框架都是为了方便我们程序员进行操作,Mybatis就是一个操作在持久层的框架。
使用mybatis需要导入一下依赖:
//这里可以统一定义下面使用的依赖的版本,当然也可以根据idea的提示自动补全选择自己需要的版本版本
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mybatis.version>3.4.5</mybatis.version>
</properties>
<dependencies>
//mybatis的依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
//log4j的日志依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
//数据库的驱动依赖,我使用的是mysql数据库
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
//junit单元测试的依赖,方便程序测试,可以测试某几个功能的正确与否
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
log4j的配置
https://blog.csdn.net/qq_45147812/article/details/105044337
Mybatis的主配置文件(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">
<!--mybatis的主配置文件-->
<configuration>
<properties resource="jdbcConfig.properties">
<!--<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/数据库名称?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="用户名"/>
<property name="password" value="密码"/>-->
<!--可以引用外部文件-->
</properties>
<!--配置延迟加载-->
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<!--使用typeAliases配置别名,这里只能配置bean中类的别名,且别名即为类名-->
<typeAliases>
<package name="bean"/>
</typeAliases>
<!--1.配置数据库的环境-->
<environments default="mysql">
<!--开发环境:在以后事务管理器和连接池都是交给Spring框架来管理-->
<environment id="mysql">
<!--事务管理器-->
<transactionManager type="JDBC"/>
<!--连接池-->
<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>
<!--2.关联映射文件-->
<!--
注意这里的路径是SqlMapConfig.xml文件找到IUserDao.xml的路径
如果在java的目录下,找不到IUserDao.xml
-->
<mappers>
<!-- resource就用目录/子目录/xxx.xml-->
<!--<mapper resource="dao/IUserDao.xml"/>-->
<!-- class 就指定目标全限定类名-->
<!-- <mapper class="dao.IUserDao"/>-->
<!--用package标签指定dao接口所在的包,制定后不需要在配置mapper标签-->
<package name="dao"/>
</mappers>
</configuration>
这里我引用了jdbc.properties配置文件加载数据库相关的配置信息,可根据自己需要选择,不引用配置文件可把注释掉的那部分配置打开来。
- jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/数据库名称?useSSL=true&useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=密码
然后就可以开始写我们的第一个小例子啦,写例子前需要先创建数据库哦,这里是我创建的表的结构,如果不觉得麻烦可以自己建一个数据库哦,自己建也不需要和我的保持一致,这样可以在后面的配置中有自己的思考
/*
Navicat Premium Data Transfer
Source Server : test
Source Server Type : MySQL
Source Server Version : 50717
Source Host : localhost:3306
Source Schema : mybatis
Target Server Type : MySQL
Target Server Version : 50717
File Encoding : 65001
Date: 30/03/2020 16:37:35
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for customerinfo
-- ----------------------------
DROP TABLE IF EXISTS `customerinfo`;
CREATE TABLE `customerinfo` (
`ID` int(10) NOT NULL AUTO_INCREMENT,
`Name` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`telphone` varchar(24) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`Department` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`RegionCode` char(6) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`Address` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`PostCode` int(10) NULL DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
然后开始我们mybatis的第一个项目啦
-创建一个与数据库对应的实体类User.java,添加属性,并设置getter和setter,为了方便查询也要写上toString()方法哦(我这里都是Alt+Shift+s自动生成的)
public class User implements Serializable {
private int id;
private String name;
private String phone;
private String department;
private char regionCode;
private String address;
private int postCode;
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", phone='" + phone + '\'' +
", department='" + department + '\'' +
", regoinCode=" + regionCode +
", address='" + address + '\'' +
", postCode=" + postCode +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public char getRegionCode() {
return regionCode;
}
public void setRegionCode(char regoioCode) {
this.regionCode = regionCode;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getPostCode() {
return postCode;
}
public void setPostCode(int postCode) {
this.postCode = postCode;
}
}
- 写出要使用的接口IUserDao.java
public interface IUserDao {
//查询所有
List<User> findAll();
//保存
void saveUser(User user);
//更新
void updateUser(User user);
//删除
void deleteUser(int id);
//查询一个
User findById(int id);
//实现模糊查询
List<User> findByName(String name);
//查询总数
int findTotal();
//通过user的某一属性或某几个属性查找
List<User> findByCondition(User user);
}
- 在resources文件夹下创建于IUserDao.java相同的同级目录,并对接口进行配置
同级目录不懂的话可以看看这个图_
<?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">
<!--命名空间,类似包的概念: namespace:必须是全限定类名绑定一个对应的Dao/Mapper接口-->
<mapper namespace="dao.IUserDao">
<!--配置列名和实体类属性名的对应关系-->
<resultMap id="userMap" type="bean.User">
<!--主键字段的对应-->
<id property="id" column="id"></id>
<!--非主键字段的对应 sql中不区分大小写-->
<result property="name" column="name"></result>
<result property="phone" column="telphone"></result>
<result property="department" column="department"></result>
<result property="regionCode" column="regoincode"></result>
<result property="address" column="address"></result>
<result property="postCode" column="postcode"></result>
</resultMap>
<!-- select的id只能写UserDao的方法名-->
<!--查询所有-->
<select id="findAll" resultMap="userMap">
select * from customerinfo;
</select>
<!--保存用户-->
<insert id="saveUser" parameterType="bean.User">
insert into customerinfo( name,telphone,department,regioncode,address,postcode)values(#{name},#{phone},#{department},#{regionCode},#{address},#{postCode})
</insert>
<!--更新用户-->
<update id="updateUser" parameterType="bean.User">
update customerinfo set name=#{name},telphone=#{phone},regioncode=#{regionCode},address=#{address},postcode=#{postCode} where id=#{id}
</update>
<!--删除用户-->
<delete id="deleteUser" parameterType="int" >
delete from customerinfo where id=#{id}
</delete>
<!--查询一个-->
<select id="findById" parameterType="int" resultMap="userMap">
select * from customerinfo where id=#{id}
</select>
<!--模糊查询-->
<select id="findByName" parameterType="String" resultMap="userMap">
select * from customerinfo where name like #{name}
</select>
<!--用户总数-->
<select id="findTotal" resultType="int">
select count(*) from customerinfo
</select>
<!--把SQL语句抽离出来-->
<sql id="selectALl">
select * from customerinfo
</sql>
<!--通过user的某一属性或某几个属性查找-->
<!--if标签-->
<select id="findByCondition" resultMap="userMap" parameterType="user">
<include refid="selectAll"/>
<where>
<if test="name !=null">
and name=#{name}
</if>
<if test="address != null">
and address=#{address}
</if>
</where>
</select>
</mapper>
到这里我们的配置就已经完成了,是不觉得很轻松呢哈哈哈,好像要比jdbc单独写简单了不少,这就是框架的妙处吧(▽)
这里我们写个测试对这些方法进行测试。
public class MybatisTest {
private InputStream in;
private SqlSession sqlSession;
private IUserDao userDao;
@Before//用于在运行test之前执行
public void init() throws Exception{
//1. 从classpath路径去加载MyBatis全局配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2. 创建sqlSessionFactory对象,好比是DataSource
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3. 创建sqlSession对象,好比是Connection
sqlSession = factory.openSession();
//4.获取dao的代理对象
userDao = sqlSession.getMapper(IUserDao.class);
}
@After//用于在运行test之后执行
public void destroy() throws Exception{
sqlSession.close();
in.close();
}
@Test
public void testFindAll() throws Exception{
//4. 具体操作
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
}
}
@Test
public void testSaveUser() throws Exception{
User user=new User();
user.setName("Test");
user.setPhone("123456");
user.setDepartment("河南省郑州市");
user.setRegionCode('c');
user.setAddress("zzu");
user.setPostCode(15612);
userDao.saveUser(user);
sqlSession.commit();
}
@Test
public void testUpdateUser(){
User user=new User();
user.setId(1);
user.setName("Testupdate");
user.setPhone("123456");
user.setDepartment("河南省郑州市");
user.setRegionCode('c');
user.setAddress("zzu");
user.setPostCode(15612);
userDao.updateUser(user);
}
@Test
public void testDeleteUser(){
userDao.deleteUser(12);
}
@Test
public void testFindByID(){
User user=userDao.findById(1);
System.out.println(user);
}
@Test
public void testFindByName(){
List<User> users=userDao.findByName("%张%");
System.out.println(users);
}
@Test
public void testFindTotal(){
int count=userDao.findTotal();
System.out.println(count);
}
@Test
public void testFindByCondition(){
User user=new User();
user.setName("哈哈");
List<User> users =userDao.findByCondition(user);
System.out.println(users);
}
}
总结
我也是看视频自学的,所以理解肯定没有那些大佬深,但是我觉得自己跟着敲一个项目就知道大致的用法,对于以后的使用肯定是有帮助的,希望以后使用到了之后可以由更深的领悟,加油呀
我们专业现在进行的课程有用到了hibernate,也是一个持久层的框架,但是那个框架用起来就感觉没有这个用起来方便,可能是因为我没好好学那个吧o(╥﹏╥)o,但是这个框架是真的挺容易上手的呢
最后在放上一个mybatis的优缺点的比较
- 优点:
简单易学:本身就很小且简单。配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。
解除sql与程序代码的耦合:将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
提供映射标签,支持对象与数据库的orm字段关系映射
提供对象关系映射标签,支持对象关系组建维护
提供xml标签,支持编写动态sql。
- 缺点
编写SQL语句时工作量很大,尤其是字段多、关联表多时,更是如此。
SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库。
框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。
二级缓存机制不佳