- 框架图
-
- SqlSessionFactoryBuilder
- 通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory
- 将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSesssionFactoryBuilder
- 在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可
- SqlSessionFactory
- 通过SqlSessionFactory创建SqlSession,使用单例模式管理sqlSessionFactory(工厂一旦创建,使用一个实例)
- 将来mybatis和spring整合后,使用单例模式管理SqlSessionFactory
- SqlSession
- 是一个面向(程序员)接口
- SqlSession中提供了多操作数据库的方法,如:selectOne(返回单个对象)、selectList(返回单个或多个对象)
- SqlSession是线程不安全的,在SqlSession实现类中除了有接口中的方法(操作数据库的方法),还有数据域属性
- SqlSession最佳应用场合在方法体内,定义成局部变量使用。
- SqlSessionFactoryBuilder
- 基础工程结构
- 在db.properties的内容
-
# Create a file called log4j.properties as shown below and place it in your classpath: # 创建一个名为log4j.properties的文件,如下所示,并将其放在类路径中: # Global logging configuration # 在开发环境下日志级别要设置成DEBUG,生产环境设置成info或error log4j.rootLogger=DEBUG, stdout # MyBatis logging configuration... log4j.logger.org.mybatis.example.BlogMapper=TRACE # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
-
- 在SqlMapConfig.xml的内容
-
<?xml version="1.0" encoding="UTF-8" ?> <!-- 配置XML文件包含MyBatis系统核心的设置,包括用于获取数据库连接实例的DataSource, 以及用于确定如何确定事务范围和控制事务的TransactionManager。 --> <!-- 请注意验证XML文档所需的XML标头。 environment元素的主体包含事务管理和连接池的环境配置。 mappers元素包含一个映射器列表 - 包含SQL代码和映射定义的XML文件和/或带注释的Java接口类。--> <!-- 与spring整合后environments配置将废除 --> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理,事务控制由mybatis --> <transactionManager type="JDBC"/> <!-- 数据库连接池,由mybatis管理 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc://mysql://localhost:3306/[数据库名]?characterEncoding=utf-8"/> <property name="username" value="[账号]"/> <property name="password" value="[密码]"/> </dataSource> </environment> </environments> <!-- 加载映射文件 --> <mappers> <mapper resource="sqlmap/User.xml"/> </mappers> </configuration>
-
- 方法一
-
#db.properties #将数据库连接参数只配置在db.properties中(原因:方便对参数进行统一管理) jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/travelling_guideling?characterEncoding=utf-8 jdbc.username=root jdbc.password=root <?xml version="1.0" encoding="UTF-8" ?> <!-- 配置XML文件包含MyBatis系统核心的设置,包括用于获取数据库连接实例的DataSource, 以及用于确定如何确定事务范围和控制事务的TransactionManager。 --> <!-- 请注意验证XML文档所需的XML标头。 environment元素的主体包含事务管理和连接池的环境配置。 mappers元素包含一个映射器列表 - 包含SQL代码和映射定义的XML文件和/或带注释的Java接口类。--> <!-- 与spring整合后environments配置将废除 --> <!-- mybatis的全局配置文件SqlMapConfig.xml,配置内容如下: properties(属性)、settings(全局配置参数)、typeAliases(类型别名)、typeHandlers(类型处理器)、 objectFactory(对象工厂)、plugins(插件)、environments(环境集合属性对象)、environment(环境子属性对象)、 transactionManager(事务管理)、dataSource(数据源)、mappers(映射器) --> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties resource="db.properties"></properties> <!-- 别名定义 --> <typeAliases> <!-- 针对单个别名定义 type:类型的路径 alias:别名 --> <typeAlias type="cn.muriel.mybatis.po.User" alias="user"/> <!-- 批量别名定义 指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大小写都可以) --> <!--<package name="cn.muriel.mybatis.po"/>--> </typeAliases> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理,事务控制由mybatis --> <transactionManager type="JDBC"/> <!-- 数据库连接池,由mybatis管理 --> <dataSource type="POOLED"> <!-- ${jdbc.driver}写成${jdbc.Driver},报错 --> <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> <!-- 通过resource方法一次加载一个映射文件 --> <mapper resource="mapper/UserMapper.xml"/> <mapper resource="sqlmap/User.xml"/> <!-- 使用完全限定路径加载 --> <!--<mapper url="file:///"/>--> <!-- 使用mapper接口类路径 --> <!-- 遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录中 上边规范的前提是:使用的是mapper代理方法 --> <!--<mapper class=""/>--> <!-- 使用批量加载mapper --> <!-- 指定mapper接口的报名,mybatis自动扫描包下边的mapper接口进行加载 遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录中 上边规范的前提是:使用的是mapper代理方法 --> <!-- <package name=""/> --> </mappers> </configuration> <?xml version="1.0" encoding="UTF-8" ?> <!-- 此时您可能想知道SqlSession或Mapper类究竟执行了什么。 MyBatis提供的全套功能可以通过使用多年来MyBatis流行的基于XML的映射语言来实现。 如果您以前使用过MyBatis,那么您将很熟悉这个概念,但是对XML映射文档进行了大量改进,以后会很清楚。 --> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace命名空间。作用对sql进行分类化管理,理解sql隔离 注意:使用mapper代理方法开发,namespace有特殊重要的作用 --> <mapper namespace="user"> <select id="selectAllUser" resultType="cn.muriel.mybatis.po.User"> select * from user </select> </mapper> /** * mybatis是一个持久层的框架 */ public class JDBCUtils { public SqlSession connection() throws IOException { //mybatis配置文件 String path = "SqlMapConfig.xml"; //得到配置文件流 InputStream inputStream = null; SqlSession sqlSession = null; inputStream = Resources.getResourceAsStream(path); //创建会话工厂,传入mybatis的配置文件信息 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //通过工厂得到SqlSession sqlSession = sqlSessionFactory.openSession(); return sqlSession; } } public abstract class UserDao extends JDBCUtils { public abstract List<User> selectAllUser(); } /** * UserDao的实现类 */ public class UserDaoImpl extends UserDao { @Override public List<User> selectAllUser() { try { SqlSession connection = connection(); List<User> users = connection.selectList("user.selectAllUser"); return users; } catch (IOException e) { e.printStackTrace(); } return null; } } /** * 测试类 */ public class TestUtil { public static void main(String[] args) { UserDao userDao = new UserDaoImpl(); JSONArray jsonArray = JSONArray.fromObject(userDao.selectAllUser()); System.out.println(jsonArray + ""); } }
-
- 方法二
-
#db.properties #将数据库连接参数只配置在db.properties中(原因:方便对参数进行统一管理) jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/travelling_guideling?characterEncoding=utf-8 jdbc.username=root jdbc.password=root <?xml version="1.0" encoding="UTF-8" ?> <!-- 配置XML文件包含MyBatis系统核心的设置,包括用于获取数据库连接实例的DataSource, 以及用于确定如何确定事务范围和控制事务的TransactionManager。 --> <!-- 请注意验证XML文档所需的XML标头。 environment元素的主体包含事务管理和连接池的环境配置。 mappers元素包含一个映射器列表 - 包含SQL代码和映射定义的XML文件和/或带注释的Java接口类。--> <!-- 与spring整合后environments配置将废除 --> <!-- mybatis的全局配置文件SqlMapConfig.xml,配置内容如下: properties(属性)、settings(全局配置参数)、typeAliases(类型别名)、typeHandlers(类型处理器)、 objectFactory(对象工厂)、plugins(插件)、environments(环境集合属性对象)、environment(环境子属性对象)、 transactionManager(事务管理)、dataSource(数据源)、mappers(映射器) --> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties resource="db.properties"></properties> <!-- 别名定义 --> <typeAliases> <!-- 针对单个别名定义 type:类型的路径 alias:别名 --> <typeAlias type="cn.muriel.mybatis.po.User" alias="user"/> <!-- 批量别名定义 指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大小写都可以) --> <!--<package name="cn.muriel.mybatis.po"/>--> </typeAliases> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理,事务控制由mybatis --> <transactionManager type="JDBC"/> <!-- 数据库连接池,由mybatis管理 --> <dataSource type="POOLED"> <!-- ${jdbc.driver}写成${jdbc.Driver},报错 --> <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> <!-- 通过resource方法一次加载一个映射文件 --> <mapper resource="mapper/UserMapper.xml"/> <mapper resource="sqlmap/User.xml"/> <!-- 使用完全限定路径加载 --> <!--<mapper url="file:///"/>--> <!-- 使用mapper接口类路径 --> <!-- 遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录中 上边规范的前提是:使用的是mapper代理方法 --> <!--<mapper class=""/>--> <!-- 使用批量加载mapper --> <!-- 指定mapper接口的报名,mybatis自动扫描包下边的mapper接口进行加载 遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录中 上边规范的前提是:使用的是mapper代理方法 --> <!-- <package name=""/> --> </mappers> </configuration> <?xml version="1.0" encoding="UTF-8" ?> <!-- 此时您可能想知道SqlSession或Mapper类究竟执行了什么。 MyBatis提供的全套功能可以通过使用多年来MyBatis流行的基于XML的映射语言来实现。 如果您以前使用过MyBatis,那么您将很熟悉这个概念,但是对XML映射文档进行了大量改进,以后会很清楚。 --> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace命名空间。作用对sql进行分类化管理,理解sql隔离 注意:使用mapper代理方法开发,namespace有特殊重要的作用 --> <mapper namespace="user"> <!-- 通过OGNL(Object-Graph-Navigation-Language)方式来进行获取 --> <select id="selectUser" parameterType="cn.muriel.mybatis.po.UserQueryVo" resultType="cn.muriel.mybatis.po.UserCustom"> select * from user where id = #{userCustom.id} </select> </mapper> /** * mybatis是一个持久层的框架 */ public class JDBCUtils { public SqlSession connection() throws IOException { //mybatis配置文件 String path = "SqlMapConfig.xml"; //得到配置文件流 InputStream inputStream = null; SqlSession sqlSession = null; inputStream = Resources.getResourceAsStream(path); //创建会话工厂,传入mybatis的配置文件信息 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //通过工厂得到SqlSession sqlSession = sqlSessionFactory.openSession(); return sqlSession; } } /** * mapper.java接口中的方法名和mapper.xml中的statement的id一致 * mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致 * mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致 * * 系统框架中,dao层的代码是被业务处公用的 * 即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求 * 注意:持久层方法的参数可以包装类型、map、service方法中建议不要使用包装类型 * * 【使用mapper.java的时候 必须是public interface UserMapper, * 若不小心写成Type class cn.muriel.mybatis.mapper.UserMapper is not known to the MapperRegistry.】 */ public interface UserMapper { public List selectAllUser(); public User selectUser(int id) throws Exception; } /** * 测试类 */ public class TestUtil { public static void main(String[] args) { JDBCUtils jdbcUtils = new JDBCUtils(); try { SqlSession sqlSession = jdbcUtils.connection(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); JSONArray sendJson = JSONArray.fromObject(mapper.selectUser(4)); System.out.println(sendJson + ""); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } }
-
- ResultType和ResultMap的区别
-
<!-- 定义resultMap: id:对resultMap的唯一标识 type:reusltMap最终映射的java对象类型,可以使用别名 --> <resultMap id="userResultMap" type="cn.muriel.mybatis.po.User"> <!-- id标识查询结果集中唯一标识 column:查询出来的列名 property:type指定的pojo类型中的属性名 最终resultMap对column和property作一个映射关系(对应关系) --> <id column="id_" property="id"/> <!-- result:对普通名映射定义 column:查询出来对列名 property:type指定对pojo类型中对属性名 最终resultMap对column和property做一个映射关系(对应关系) --> <result column="username_" property="username"/> </resultMap> <!-- (resultType和resultMap的区别) resultType:使用resultType进行输出映射,只有查询出来的列名和Pojo中的属性名一致,该列才可以映射成功 不管是输出的pojp单个对象还是一个列表(list中包括pojo),在mapper.xml中resultType指定的类型是一样的 在mapper.java指定的方法返回值类型不一样: (1)输出单个pojo对象,方法返回值是单个对象类型 (2)输出list的pojo对象,方法返回值是List<pojo> resultMap:如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间做一个映射关系 (1)定义resultMap (2)使用resultMap作为statement的输出映射类型 --> <!-- 通过OGNL(Object-Graph-Navigation-Language)方式来进行获取 --> <select id="selectUser" parameterType="id" resultMap="userResultMap" resultType="cn.muriel.mybatis.po.UserCustom"> select id id_,username username username_ from user where id = #{userCustom.id} </select>
-
- 什么是动态sql
- mybatis核心对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼装、组接。
- if判断
-
<!-- 模糊查询用户 --> <!-- 若resultType写成resultMap 抛异常Result Maps collection does not contain value for XXX --> <select id="blurrySelectUser" parameterType="cn.muriel.mybatis.po.UserQueryVo" resultType="cn.muriel.mybatis.po.UserCustom"> SELECT * from USER <!-- where 可以自动去掉条件中第一个and --> <where> <if test="userCustom != null"> <if test="userCustom.root != null"> and root = #{userCustom.root} </if> <if test="userCustom.username != null and userCustom.username != ''"> and username LIKE '%${userCustom.username}%' </if> </if> </where> </select> public interface UserMapper { public List blurrySelectUser(UserQueryVo userQueryVo) throws Exception; } public class TestUtil { public static void main(String[] args) { JDBCUtils jdbcUtils = new JDBCUtils(); try { SqlSession sqlSession = jdbcUtils.connection(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); UserQueryVo userQueryVo = new UserQueryVo(); UserCustom user = new UserCustom(); user.setUsername("a"); user.setRoot(1); userQueryVo.setUserCustom(user); JSONArray sendJson = JSONArray.fromObject(mapper.blurrySelectUser(userQueryVo)); System.out.println(sendJson + ""); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } }
-
- sql片段
-
<!-- 定义sql片段: 是基于单表来定义sql片段,这样的话这个sql片段可重用性才高 在sql片段中不要包括where --> <sql id="blurry_select_user_where"> <if test="userCustom != null"> <if test="userCustom.root != null"> and root = #{userCustom.root} </if> <if test="userCustom.username != null and userCustom.username != ''"> and username LIKE '%${userCustom.username}%' </if> </if> </sql> <!-- 模糊查询用户 --> <!-- 若resultType写成resultMap 抛异常Result Maps collection does not contain value for XXX --> <select id="blurrySelectUser" parameterType="cn.muriel.mybatis.po.UserQueryVo" resultType="cn.muriel.mybatis.po.UserCustom"> SELECT * from USER <!-- where 可以自动去掉条件中第一个and --> <where> <!-- 引用sql片段的id,如果refid指定的Id不再当前mapper文件中,需要在前边加namespace --> <include refid="blurry_select_user_where"></include> <!-- 在这里还可以引用其它的sql片段 --> </where> </select>
-
- foreach
-
public class UserQueryVo { private List<Integer> ids; //用户查询条件 private UserCustom userCustom; public UserCustom getUserCustom() { return userCustom; } public void setUserCustom(UserCustom userCustom) { this.userCustom = userCustom; } public List<Integer> getIds() { return ids; } public void setIds(List<Integer> ids) { this.ids = ids; } } public interface UserMapper { public List blurrySelectUser(UserQueryVo userQueryVo) throws Exception; } <select id="blurrySelectUser" parameterType="cn.muriel.mybatis.po.UserQueryVo" resultType="cn.muriel.mybatis.po.UserCustom"> SELECT * from USER <!-- where 可以自动去掉条件中第一个and --> <where> <!-- 引用sql片段的id,如果refid指定的Id不再当前mapper文件中,需要在前边加namespace --> <include refid="blurry_select_user_where"></include> <!-- 在这里还可以引用其它的sql片段 --> </where> </select> <!-- 定义sql片段: 是基于单表来定义sql片段,这样的话这个sql片段可重用性才高 在sql片段中不要包括where --> <sql id="blurry_select_user_where"> <if test="userCustom != null"> <if test="userCustom.root != null"> and root = #{userCustom.root} </if> <if test="userCustom.username != null and userCustom.username != ''"> and username LIKE '%${userCustom.username}%' </if> </if> <!-- collection:指定输入对象中属性集合 item:每个遍历生成对象中 open:开始遍历时拼接的串 close:结束遍历时拼接的串 spearator:遍历时两个对象中需要拼接的串 (SQL语句格式:AND (id=1 or id=2 or id =3))=3)) --> <foreach collection="ids" item="user_id" open="AND (" close=")" separator="or"> <!-- 每个遍历需要拼接的串 --> id = #{user_id} </foreach> </sql> public class TestUtil { public static void main(String[] args) { JDBCUtils jdbcUtils = new JDBCUtils(); try { SqlSession sqlSession = jdbcUtils.connection(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); UserQueryVo userQueryVo = new UserQueryVo(); UserCustom user = new UserCustom(); user.setUsername("a"); user.setRoot(1); List list = new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); userQueryVo.setIds(list); userQueryVo.setUserCustom(user); JSONArray sendJson = JSONArray.fromObject(mapper.blurrySelectUser(userQueryVo)); System.out.println(sendJson + ""); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } }
-
<!-- collection:指定输入对象中属性集合 item:每个遍历生成对象中 open:开始遍历时拼接的串 close:结束遍历时拼接的串 spearator:遍历时两个对象中需要拼接的串 (SQL语句格式:AND id in (1 , 2 ,3)) --> <foreach collection="ids" item="user_id" open="and id IN (" close=")" separator=","> <!-- 每个遍历需要拼接的串 --> #{user_id} </foreach>
-