Mybatis基本流程 1、利用Resources工具类加载配置文件,并转换成输入输出流
2、利用解析的配置,创建SqlSessionFactory工厂
3、生产SqlSession
4、SqlSession调用方法
Mybatis配置文件分析 sqlMapConfig.xml MyBatis核心配置文件层级
MyBatis常用配置解析 输出日志,在sqlMapConfig.xml添加如下配置:
1 2 3 4 <settings > <setting name ="logImpl" value ="STDOUT_LOGGING" /> </settings >
1)environments标签
事务管理器( transactionManager
)类型有两种:
JDBC:直接使用JDBC的提交和回滚设置,依赖于从数据源得到的链接来管理事务的作用域
MANAGED:几乎不做事。不提交事务也不会回滚。让容器(例如JEE的应用服务器的上下文)来管理事务的整个生命周期。
默认情况下会关闭链接,然而一些容器不希望这样,需要配置 closeConnection
的属性为 false
来阻止它的默认关闭行为。
数据源( DataSource
)有三种:
UNPOOLED:每次请求都打开和关闭链接
POOLED:采用连接池管理JDBC链接
JNDI:为了配合EJB容器使用,容器可以集中在外部配置数据源,然后放置一个JNDI的上下文引用
2)mapper标签
作用是加载映射,加载方式有以下四种:
使用相对类路径的引用,例如:
1 <mapper resource ="org/mybatis/builder/AuthorMapper.xml" />
使用URL,例如:
1 <Mappper url ="file:///var/mapper/AuthorMapper.xml" />
使用接口实现类的全限定类名,例如:
1 <mapper class ="org.mybatis.builder.AuthorMapper" />
使用包名称,例如:
1 <package name ="org.mybatis.builder" />
3)Properties
习惯性将数据量配置信息单独配置在 jdbc.properties
文件中
1 2 3 4 jdbc.dirver =com.mysql.jdbc.Driver jdbc.url =jdbc:mysql://localhost:3306/zdy_mybatis?characterEncoding=utf8 jdbc.username =root jdbc.password =123456
1 <properties resource ="jdbc.properties" />
注意顺序:properties必须在最前面,否则会报如下错误
4)typeAliases标签
类型别名是为Java类设置一个短的名字。原来的类型配置如下:
1 2 3 <select id ="findAll" resultType ="com.terwergreen.pojo.User" > select * from user </select >
配置typeAliases,为 com.terwergreen.pojo.User
指定别名 user
1 2 3 <typeAliases > <typeAlias type ="com.terwergreen.pojo.User" alias ="user" /> </typeAliases >
1 2 3 <select id ="findAll" resultType ="user" > select * from user </select >
上面是我们自定义的别名,Mybatis 默认已经为我们设置好了一些别名:
如果实体类较多,上面方法不可取,可以使用指定包名的方式
1 2 3 4 5 6 <typeAliases > <package name ="com.terwergreen.pojo" /> </typeAliases >
批量起别名:该包下所有类本身的类名,不区分大小写
mapper.xml 1)动态SQL
动态SQL语句概述
https://mybatis.org/mybatis-3/dynamic-sql.html
动态SQL之 <if>
根据实体类的不用取值,使用不同的SQL进行查询
1 2 3 4 5 6 7 8 9 10 <select id ="findByCondition" parameterType ="user" resultType ="user" > select * from user where 1=1 <if test ="id!=null" > and id=#{id} </if > <if test ="username!=null" > and username=#{username} </if > </select >
动态SQL之 where
1 2 3 4 5 6 7 8 9 10 11 12 <select id ="findByConditionWhere" parameterType ="user" resultType ="user" > select * from user <where > <if test ="id!=null" > and id=#{id} </if > <if test ="username!=null" > and username=#{username} </if > </where > </select >
同时设置id和username之后,日志如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Test @Throws(IOException::class) fun test7 () { val resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml" ) val sqlSessionFactory = SqlSessionFactoryBuilder().build(resourceAsStream) val sqlSession = sqlSessionFactory.openSession() val userDao = sqlSession.getMapper(IUserDao::class .java) val user = User() user.id = 1 user.username = "tyw" val userList = userDao.findByConditionWhere(user) for (user2 in userList) { println(user2) } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public void test7 () throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml" ); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder ().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); IUserDao userDao = sqlSession.getMapper(IUserDao.class); User user = new User (); user.setId(1 ); user.setUsername("tyw" ); List<User> userList = userDao.findByConditionWhere(user); for (User user2 : userList) { System.out.println(user2); } }
1 2 3 4 5 6 ==> Preparing: select * from user WHERE id=? and username=? ==> Parameters: 1(Integer), tyw(String) <== Columns: id, username <== Row: 1, tyw <== Total: 1 User{id=1, username='tyw'}
动态SQL之 foreach
循环执行SQL的拼接动作。例如:select * from user where id in(1,2,4)
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @Test @Throws(IOException::class) fun test8 () { val resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml" ) val sqlSessionFactory = SqlSessionFactoryBuilder().build(resourceAsStream) val sqlSession = sqlSessionFactory.openSession() val userDao = sqlSession.getMapper(IUserDao::class .java) val ids = arrayOf(1 , 2 , 4 ) val userList = userDao.findByIds(ids) for (user2 in userList) { println(user2) } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public void test8 () throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml" ); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder ().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); IUserDao userDao = sqlSession.getMapper(IUserDao.class); Integer[] ids = new Integer []{1 , 2 , 4 }; List<User> userList = userDao.findByIds(ids); for (User user2 : userList) { System.out.println(user2); } }
配置如下
1 2 3 4 5 6 7 8 9 <select id ="findByIds" parameterType ="list" resultType ="user" > select * from user <where > <foreach collection ="array" open ="id in (" close =")" item ="id" separator ="," > #{id} </foreach > </where > </select >
日志如下:
1 2 3 4 5 6 7 8 9 10 ==> Preparing: select * from user WHERE id in ( ? , ? , ? ) ==> Parameters: 1(Integer), 2(Integer), 4(Integer) <== Columns: id, username <== Row: 1, tyw <== Row: 2, 张月 <== Row: 4, haha <== Total: 3 User{id=1, username='tyw'} User{id=2, username='张月'} User{id=4, username='haha'}
foreach各项的含义如下:
<foreach>
用于遍历几乎
collection:要遍历的集合元素,不能带有#{}
open:语句开始部分
close:结束部分
item:遍历的元素生成的变量名
sperator:分隔符
SQL片段抽取 可以将重复sql抽取出来放在sql标签中,使用时候用include
1 2 <sql id ="selectUser" > select * from user</sql >
使用
1 2 3 4 <select id ="findById" parameterType ="int" resultType ="user" > <include refid ="selectUser" > </include > where id=#{id} </select >
测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Test @Throws(IOException::class) fun test9 () { val resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml" ) val sqlSessionFactory = SqlSessionFactoryBuilder().build(resourceAsStream) val sqlSession = sqlSessionFactory.openSession() val userDao = sqlSession.getMapper(IUserDao::class .java) val user2 = userDao.findById(1 ) println(user2) }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Test public void test9 () throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml" ); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder ().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); IUserDao userDao = sqlSession.getMapper(IUserDao.class); User user2 = userDao.findById(1 ); System.out.println(user2); }
日志如下:
1 2 3 4 5 6 ==> Preparing: select * from user where id=? ==> Parameters: 1(Integer) <== Columns: id, username <== Row: 1, tyw <== Total: 1 User{id=1, username='tyw'}
文章更新历史 2022-08-30 feat:初稿