)2.3.1.1、标准日志实现
指定 MyBatis 应该使用哪个日志记录实现,如果此设置不存在,则会自动发现日志记录实现
在mybatis-config.xml
核心配置文件配置
<settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
)2.3.1.2、Log4j日志实现
使用步骤:
<!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
Log4j配置文件编写
log4j.properties
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码 log4j.rootLogger=DEBUG,console,file #控制台输出的相关设置 log4j.appender.console = org.apache.log4j.ConsoleAppender log4j.appender.console.Target = System.out log4j.appender.console.Threshold=DEBUG log4j.appender.console.layout = org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=[%c]-%m%n #文件输出的相关设置 log4j.appender.file = org.apache.log4j.RollingFileAppender log4j.appender.file.File=./log/kuang.log log4j.appender.file.MaxFileSize=10mb log4j.appender.file.Threshold=DEBUG log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n #日志输出级别 log4j.logger.org.mybatis=DEBUG log4j.logger.java.sql=DEBUG log4j.logger.java.sql.Statement=DEBUG log4j.logger.java.sql.ResultSet=DEBUG log4j.logger.java.sql.PreparedStatement=DEBUG
<settings> <setting name="logImpl" value="LOG4J"/> </settings>
//注意导包:org.apache.log4j.Logger static Logger logger = Logger.getLogger(MyTest.class); @Test public void textLog4j(){ logger.info("info:进入了selectUser方法"); logger.debug("debug:进入了selectUser方法"); logger.error("error:进入了selectUser方法"); }
)2.3.2、开启驼峰命名法
使用步骤:
<settings> <!-- 开启驼峰命名转化--> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
[](
)1.6、mappers标签
该标签的作用是加载映射的,加载方式有如下几种(主要使用第三种):
/
而不是用点<mappers> <mapper resource="com/kuang/dao/UserMapper.xml"></mapper> </mappers>
<mappers> <mapper class="com.kuang.dao.TeacherMapper" /> <mapper class="com.kuang.dao.StudentMapper" /> </mappers>
<!-- 定义dao接口所在的包。要求xml文件存放的路径和dao接口的包名要对应 --> <mappers> <package name="com.kuang.dao" /> </mappers>
[](
)3、Mybatis相应API
================================================================================
[](
)3.1、Resources
加载资源的工具类:
| 返回值 | 方法名 | 说明 |
| --- | --- | --- |
| InputStream | getResourceAsStream(String fileName) | 通过类加载器返回指定资源的字节输入流 |
//1.加载核心配置文件 InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); // 我们也可以自己加载 InputStream inputStream = 类名.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
[](
)3.2、SqlSessionFactoryBuilder
SqlSessionFactoryBuilder工厂构建器:
SqlSessionFactory.build(InputStream inputStream)
通过加载mybatis的核心文件的输入流的形式构建一个SqlSessionFactory对象
String resource = "org/mybatis/example/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
[](
)3.3、SqlSessionFactory
SqlSessionFactory有多个方法创建SqlSession实例,常用的有如下两个:
SqlSessionFactory.openSession
:会默认开启一个事务,但事务不会自动提交,也就意味着需要手动提交该事务,更新操作数据才会持久化到数据库中
SqlSessionFactory.openSession(boolean autoCommit)
: 参数为是否自动提交,如果设置为true,那么不需要手动提交事务
| 返回值 | 方法名 | 说明 |
| --- | --- | --- |
| SqlSession | openSession() | 通过SqlSession构建者对象,并开启手动提交事务 |
| SqlSession | openSession(boolean autoCommit) | 通过SqlSession构建者对象,如果参数为true,则开启自动提交事务 |
[](
)3.4、SqlSession
SqlSession 提供了在数据库执行 SQL 命令所需的所有方法 。它还提供了事务的相关操作。
成员方法如下:
sqlSession.commit()
:提交事务
sqlSession.rollback()
:回滚事务
sqlSession.close()
:释放资源
[](
)3.5、mybatis工具类
我们通常将mybatis获取SqlSession实例封装成一个工具类
public class MybatisUtils { private static SqlSessionFactory sqlSessionFactory; static{ try { // 使用Mybatis // 第一步: 获取sqlSessionFactory对象 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } //既然有了SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。 public static SqlSession getSqlSession(){ // SqlSession sqlSession = sqlSessionFactory.openSession(); // return sqlSession; return sqlSessionFactory.openSession(); } }
[](
)4、Mybatis开发方式
===============================================================================
[](
)4.0、Mybatis传统方式开发
[](
)4.0、Dao 层传统实现方式
分层思想:控制层(controller)、业务层(service)、持久层(dao)。
调用流程
[](
)4.1、Dao层代理开发方式
Mapper 接口开发方法只需要程序员编写Mapper 接口(相当于Dao 接口)
我们之前的开发规范是编写Dao接口,之后再编写实现类DaoImpl
代理开发规范是编写Dao接口,之后再编写xml配置文件
Mapper 接口开发需要遵循以下规范:
Mapper.xml文件中的namespace与mapper接口的全限定名相同
Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
[](
)4.2、参数的获取
)4.2.1、一个参数
)4.2.1.1、基本参数
我们可以使用#{}
直接来取值,写任意名字都可以获取到参数。但是一般用方法的参数名来取。
例如:
public interface UserDao { User findUser(Integer id); }
<select id="findUser" parameterType="int" resultType="com.sangeng.pojo.User"> select * from user where id = #{id} </select>
@Test public void findUser() throws IOException { //定义mybatis配置文件的路径 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //获取Sqlsession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //获取UserDao实现类对象 UserDao userDao = sqlSession.getMapper(UserDao.class); //调用方法测试 User user = userDao.findUser(2); System.out.println(user); //释放资源 sqlSession.close(); }
)4.2.1.2、POJO
我们可以使用POJO中的属性名来获取对应的值。
例如:
public interface UserDao { User findByUser(User user); }
<select id="findByUser" resultType="com.sangeng.pojo.User"> select * from user where id = #{id} and username = #{username} and age = #{age} and address = #{address} </select>
@Test public void findByUser() throws IOException { //定义mybatis配置文件的路径 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //获取Sqlsession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //获取UserDao实现类对象 UserDao userDao = sqlSession.getMapper(UserDao.class); //调用方法测试 User byUser = userDao.findByUser(new User(2, "PDD", 25, "上海")); System.out.println(byUser); //释放资源 sqlSession.close(); }
)4.2.1.3、Map
我们可以使用map中的key来获取对应的值。
例如:
public interface UserDao { User findByMap(Map map); }
<select id="findByMap" resultType="com.sangeng.pojo.User"> select * from user where id = #{id} and username = #{username} and age = #{age} and address = #{address} </select>
@Test public void findByMap() throws IOException { //定义mybatis配置文件的路径 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //获取Sqlsession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //获取UserDao实现类对象 UserDao userDao = sqlSession.getMapper(UserDao.class); //调用方法测试 Map map = new HashMap(); map.put("id",2); map.put("username","PDD"); map.put("age",25); map.put("address","上海"); User byMap = userDao.findByMap(map); System.out.println(byMap); //释放资源 sqlSession.close(); }
)4.2.2、多个参数
Mybatis会把多个参数放入一个Map集合中,默认的key是argx和paramx这种格式。
例如:
接口中方法定义如下
public interface UserDao { User findByCondition(@Param("tid") Integer id,@Param("username")String username); }
<select id="findByCondition" resultType="com.sangeng.pojo.User"> select * from user where id = #{tid} and username = #{username} </select>
@Test public void findByCondition() throws IOException { //定义mybatis配置文件的路径 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //获取Sqlsession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //获取UserDao实现类对象 UserDao userDao = sqlSession.getMapper(UserDao.class); //调用方法测试 User pdd = userDao.findByCondition(2, "PDD"); System.out.println(pdd); //释放资源 sqlSession.close(); }
)4.2.3、总结
建议如果只有一个参数的时候不用做什么特殊处理。
如果是有多个参数的情况下一定要加上@Param来设置参数名。
)4.2.4、获取参数时 #{}和${}的区别
如果使用#{}.他是预编译的sql可以防止SQL注入攻击
如果使用${}他是直接把参数值拿来进行拼接,这样会有SQL注入的危险
[](
)5、CRUD操作
==========================================================================
[](
)5.1、select
select 语句有很多属性可以详细配置每一条SQL语句
id
: 就是对应的namespace中的方法名
resultType
: Sql语句执行的返回值【完整的类名或者别名】
parameterType
:传入SQL语句的参数类型
示例:
public interface UserMapper { // 查询全部用户 List<User> getUserList(); }
<mapper namespace="com.kuang.dao.UserMapper"> <select id="getUserList" resultType="com.kuang.pojo.User"> select * from mybatis.user; </select> </mapper>
public void test(){ //第一步:获得SqlSession对象 SqlSession sqlSession = MybatisUtils.getSqlSession(); //方式一:执行SQL UserMapper userDao = sqlSession.getMapper(UserMapper.class); List<User> userList = userDao.getUserList(); for (User user : userList) { System.out.println(user); } // 关闭SqlSession sqlSession.close(); }
示例2:根据id查询用户
public interface UserMapper { // 根据ID查询用户 User getUserById(int id); }
<select id="getUserById" parameterType="int" resultType="com.kuang.pojo.User"> select * from mybatis.user where id = #{id} </select>
@Test public void getUserById(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.getUserById(1); System.out.println(user); sqlSession.close(); }
[](
)5.2、insert
需求:给数据库增加一个用户
public interface UserMapper{ // insert int addUser(User user); }
<insert id="addUser" parameterType="com.kuang.pojo.User"> insert into mybatis.user(id, name, pwd) VALUES (#{id},#{name},#{pwd}) </insert>
// 增删改需要提交事务 @Test public void addUser(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); int res = mapper.addUser(new User(5, "哈哈2", "1234")); if(res > 0) { System.out.println("插入成功"); } // 提交事务 sqlSession.commit(); sqlSession.close(); }
在插入操作中,使用parameterType
属性指定要插入的数据类型
Sql语句中使用#{实体属性名}
方式引用实体中的属性值
增、删、改操作涉及数据库数据变化,所以要使用sqlSession
对象显式的提交事务,即sqlSession.commit()
[](
)5.3、update
需求:修改用户的信息
public interface UserMapper{ // 修改用户 int updateUser(User user); }
<update id="updateUser" parameterType="com.kuang.pojo.User"> update mybatis.user set name=#{name},pwd=#{pwd} where id = #{id}; </update>
@Test public void updateUser(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); int res = mapper.updateUser(new User(4, "呵呵", "123123")); if(res > 0){ System.out.println("修改成功"); } sqlSession.commit(); sqlSession.close(); }
[](
)5.4、delete
需求:根据id删除一个用户
public interface UserMapper{ // 删除一个用户 int deleteUser(int id); }
<delete id="deleteUser" parameterType="int"> delete from mybatis.user where id = #{id} </delete>
@Test public void deleteUser(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); int res = mapper.deleteUser(4); if(res > 0){ System.out.println("删除成功"); } sqlSession.commit(); sqlSession.close(); }
[](
)5.5、万能Map
假设我们的实体类,或者数据库中的表,字段或者参数过多,我们应当考虑使用Map!
)5.5.1、select
public interface UserMapper{ // 万能的map User getUserById2(Map<String,Object> map); }
<select id="getUserById2" parameterType="map" resultType="com.kuang.pojo.User"> select * from mybatis.user where id = #{helloid} and name = #{name}; </select>
@Test public void getUserById2(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); Map<String, Object> map = new HashMap<>(); map.put("helloId",1); sqlSession.close(); }
)5.5.2、insert
public interface UserMapper{ // 万能的map int addUser2(Map<String, Object> map); }
<insert id="addUser2" parameterType="map"> insert into mybatis.user(id, name, pwd) VALUES (#{id},#{name},#{pwd}) </insert>
// 传递map的key @Test public void addUser2(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); HashMap<String, Object> map = new HashMap<>(); map.put("id",5); map.put("name","啦啦啦"); map.put("pwd","123456"); sqlSession.close(); }
[](
)6、动态SQL
=========================================================================
在实际开发中的SQL语句没有之前的这么简单,很多时候需要根据传入的参数情况动态的生成SQL语句。Mybatis提供了动态SQL相关的标签让我们使用。
[](
)6.1、if标签
可以使用if标签进行条件判断,条件成立才会把if标签中的内容拼接进sql语句中。
例如:
<select id="findByCondition" resultType="com.sangeng.pojo.User"> select * from user where id = #{id} <if test="username!=null"> and username = #{username} </if> </select>
如果参数username为null则执行的sql为:select * from user where id = ?
如果参数username不为null则执行的sql为:select * from user where id = ? and username = ?
注意:在test属性中表示参数的时候不需要写#{},写了会出问题。
[](
)6.2、trim标签
可以使用该标签动态的添加前缀或后缀,也可以使用该标签动态的消除前缀。
注意:trim标签其实在真正开发中不会太用到,主要是为了理解后面的where标签,所以这里理解即可
)6.2.1、prefixOverridess属性
用来设置需要被清除的前缀,多个值可以用|分隔,注意|前后不要有空格。例如: and|or
例如:
<select id="findByCondition" resultType="com.sangeng.pojo.User"> select * from user <trim prefixOverrides="and|or" > and </trim> </select>
最终执行的sql为: select * from user
)6.2.2、suffixOverrides属性
用来设置需要被清除的后缀,多个值可以用|分隔,注意|前后不要有空格。例如: and|or
<select id="findByCondition" resultType="com.sangeng.pojo.User"> select * from user <trim suffixOverrides="like|and" > where 1=1 like </trim> </select>
最终执行的sql为: select * from user 去掉了后缀like
)6.2.3、prefix属性
用来设置动态添加的前缀,如果标签中有内容就会添加上设置的前缀
<select id="findByCondition" resultType="com.sangeng.pojo.User"> select * from user <trim prefix="where" > 1=1 </trim> </select>
最终执行的sql为:select * from user where 1=1 动态增加了前缀where
)6.2.4、 suffix属性
? 用来设置动态添加的后缀,如果标签中有内容就会添加上设置的后缀
<select id="findByCondition" resultType="com.sangeng.pojo.User"> select * from user <trim suffix="1=1" > where </trim> </select>
最终执行的sql为:select * from user where 1=1 动态增加了后缀1=1
)6.2.5、trim综合使用
动态添加前缀where 并且消除前缀and或者or
<select id="findByCondition" resultType="com.sangeng.pojo.User"> select * from user <trim prefix="where" prefixOverrides="and|or" > <if test="id!=null"> id = #{id} </if> <if test="username!=null"> and username = #{username} </if> </trim> </select> ## 最后 针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。 > 最新整理面试题 > ![在这里插入图片描述](https://upload-images.jianshu.io/upload_images/24616006-379dee2451e757a1?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) > 上述的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题 > > **[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](https://ali1024.coding.net/public/P7/Java/git)** > 最新整理电子书 ![在这里插入图片描述](https://upload-images.jianshu.io/upload_images/24616006-4b35c587fdc28ff3?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) > 最新整理大厂面试文档 ![在这里插入图片描述](https://upload-images.jianshu.io/upload_images/24616006-ed2b9d216983310f?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。