day 110- ssm-mybatis
mybatis学习
介绍
MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁移到了Google Code。随着开发团队转投Google Code旗下, iBatis3.x正式更名为MyBatis。代码于2013年11月迁移到Github。
1) MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架
2) MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
3) MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old JavaObjects,普通的Java对象)映射成数据库中的记录
4) MyBatis 是一个 半自动的ORM(Object Relation Mapping)框架
对比
-
JDBC
SQL 夹杂在Java代码中耦合度高,导致硬编码内伤
维护不易且实际开发需求中 SQL 有变化,频繁修改的情况多见
代码冗长,开发效率低
-
Hibernate 和 JPA
操作简便,开发效率高
程序中的长难复杂 SQL 需要绕过框架
内部自动生产的 SQL,不容易做特殊优化
基于全映射的全自动框架,大量字段的 POJO 进行部分映射时比较困难。
反射操作太多,导致数据库性能下降
-
MyBatis
轻量级,性能出色
SQL 和 Java 编码分开,功能边界清晰。Java代码专注业务、SQL语句专注数据
开发效率稍逊于HIbernate,但是完全能够接受
环境
依赖
<dependencies> <!-- Mybatis核心 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.13</version> </dependency> <!-- junit测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- MySQL驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.37</version> </dependency> <!-- log4j日志 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.13</version> <scope>compile</scope> </dependency> </dependencies>
核心文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- mybatis核心配置文件中的顺序是指定的 properties?,settings?,typeAliases?,typeHandlers?,objectFactory?, objectWrapperFactory?,reflectorFactory?,plugins?,environments?, databaseIdProvider?,mappers? --> <properties resource="jdbc.properties"/> <typeAliases> <package name="com.gu.mybatis.pojo"/> </typeAliases> <environments default="development"> <environment id="development"> <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> <mappers> <package name="com.gu.mybatis.mapper"/> </mappers> </configuration>
hello world
创建接口
public interface UserMapper { /* * 添加用户信息 * */ int insertUser(); /* * 修改用户信息 * */ void updateUser(); /* * 删除用户信息 * */ void deleteUser(); /* * 根据id查询用户 * */ User getUserById(int id); /* * 查询所有用户 * */ List<User> getAllUser(); }
对应xml文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.gu.mybatis.mapper.UserMapper"> <!-- mapper接口和映射文件要保持一致: 1. mapper接口的全类名和映射文件的namespace一致 2. mapper接口中的方法的方法名要和映射文件中的sql的id保持一致 --> <!-- int insertUser(); --> <insert id="insertUser"> insert into t_user values(null,'admin','123456',23,'男','792972270@qq.com') </insert> <!-- int updateUser(); --> <update id="updateUser"> update t_user set username='root',password='123' where id = 3 </update> <!-- void deleteUser(); --> <delete id="deleteUser"> delete from t_user where id = 3 </delete> <!-- User getUserById(int id);--> <!-- resultType:设置结果类型,查询的数据要转化为的Java类型 resultMap:自定义映射,处理多对一或一对多的映射关系 --> <select id="getUserById" resultType="com.gu.mybatis.pojo.User"> select * from t_user where id =2 </select> <!--List<User> getAllUser();--> <select id="getAllUser" resultType="user"> select * from t_user </select> </mapper>
实体类
package com.gu.mybatis.pojo; public class User { private Integer id; private String username; private String password; private Integer age; private String gender; private String email; public User() { } public User(Integer id, String username, String password, Integer age, String gender, String email) { this.id = id; this.username = username; this.password = password; this.age = age; this.gender = gender; this.email = email; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", age=" + age + ", gender='" + gender + '\'' + ", email='" + email + '\'' + '}'; } }
sql工具类
package com.gu.mybatis.utils; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; import java.io.InputStream; public class SqlSessionUtil { public static SqlSession getSqlSession() { SqlSession sqlSession = null; //获取核心配置文件的输入流 try { InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); //获取SqlSessionFactory对象,传入mybatis配置文件的输入流 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is); //通过SqlSessionFactory对象获取SqlSession对象 sqlSession = sqlSessionFactory.openSession(true); } catch (IOException e) { e.printStackTrace(); } return sqlSession; } }
测试类
package com.gu.mybatis.test; import com.gu.mybatis.mapper.UserMapper; import com.gu.mybatis.pojo.User; import com.gu.mybatis.utils.SqlSessionUtil; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.List; public class MyBatisTest { @Test public void testInsert() throws IOException { //获取核心配置文件的输入流 InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); //获取sqlssionFactoryBuilder对象 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); // 通过工厂构建SqlSessionFactory SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is); // 通过SqlSessionFactory构建SqlSession,不会自动提交事务 //SqlSession sqlSession = sqlSessionFactory.openSession(); //会自动提交事务 SqlSession sqlSession = sqlSessionFactory.openSession(true); // 通过sqlSession操作数据库,获取usermapper的代理实现对象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //调用usermapper接口中的方法,实现添加用户信息 int result = userMapper.insertUser(); /* * 调用mapper接口实现添加方法。面向接口方法 * 最原始的是提供最基础的sql语句 * 提供映射文件的唯一标识namespace.id * sqlSession.insert("com.example.dongbo.mapper.UserMapper.insertUser"), * */ System.out.println("添加用户数量: "+result + ""); //提交事务 //sqlSession.commit(); // 释放资源 sqlSession.close(); } @Test public void testUpdate(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); mapper.updateUser(); sqlSession.close(); } @Test public void testDelete(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); mapper.deleteUser(); sqlSession.close(); } @Test public void testGetUserById(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.getUserById(2); System.out.println(user); } @Test public void testGetAllUser(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> allUser = mapper.getAllUser(); for (User user: allUser) { System.out.println(user); } } }
数据库配置
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/ssm?characterEncoding=utf-8 jdbc.username=root jdbc.password=123456
总结
1、映射文件的命名规则:
表所对应的实体类的类名+Mapper.xml
例如:表t_user,映射的实体类为User,所对应的映射文件为UserMapper.xml
因此一个映射文件对应一个实体类,对应一张表的操作
MyBatis映射文件用于编写SQL,访问以及操作表中的数据
MyBatis映射文件存放的位置是src/main/resources/mappers目录下
2、 MyBatis中可以面向接口操作数据,要保证两个一致:
a>mapper接口的全类名和映射文件的命名空间(namespace)保持一致
b>mapper接口中方法的方法名和映射文件中编写SQL的标签的id属性保持一致
SqlSession:代表Java程序和数据库之间的会话。(HttpSession是Java程序和浏览器之间的
会话)
SqlSessionFactory:是“生产”SqlSession的“工厂”。
工厂模式:如果创建某一个对象,使用的过程基本固定,那么我们就可以把创建这个对象的
相关代码封装到一个“工厂类”中,以后都使用这个工厂类来“生产”我们需要的对象。
日志
<?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="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \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>
日志的级别
从左到右打印的内容越来越详细
核心文件讲解
<?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> <!--MyBatis核心配置文件中,标签的顺序: properties?,settings?,typeAliases?,typeHandlers?, objectFactory?,objectWrapperFactory?,reflectorFactory?, plugins?,environments?,databaseIdProvider?,mappers? --> <!--引入properties文件--> <properties resource="jdbc.properties" /> <!--设置类型别名--> <typeAliases> <!--typeAlias:设置某个类型的别名 属性:type:设置需要设置别名的类型 alias:设置某个类型的别名,若不设置该属性,那么该类型拥有默认的别名,即类名 且不区分大小写 --> <!--<typeAlias type="com.atguigu.mybatis.pojo.User"></typeAlias>--> <!--以包为单位,将包下所有的类型设置默认的类型别名,即类名且不区分大小写--> <package name="com.atguigu.mybatis.pojo"/> </typeAliases> <!--environments:配置多个连接数据库的环境 属性:default:设置默认使用的环境的id --> <environments default="development"> <!--environment:配置某个具体的环境 属性:id:表示连接数据库的环境的唯一标识,不能重复 --> <environment id="development"> <!--transactionManager:设置事务管理方式 属性:type="JDBC|MANAGED" JDBC:表示当前环境中,执行SQL时,使用的是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> <environment id="test"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/ssmserverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <!--引入映射文件--> <mappers> <!--<mapper resource="mappers/UserMapper.xml"/>--> <!--以包为单位引入映射文件 要求: 1、mapper接口所在的包要和映射文件所在的包一致 2、mapper接口要和映射文件的名字一致 --> <package name="com.atguigu.mybatis.mapper"/> </mappers> </configuration>
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术