Mybatis技术点学习-基础篇
Posted IT技术屋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis技术点学习-基础篇相关的知识,希望对你有一定的参考价值。
1. Mybatis介绍
MyBatis 是支持 普通 SQL 查询 , 存储过程 和 高级映射的优秀持久层框架。MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索封装。MyBatis 可以使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJO(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录
1. 快速入门
1.1 xml方式实现
1.1.1 添加 jar
1.1.2 创建表
Create database mybatis_demo; DROP TABLE IF EXISTS `tb_user`; CREATE TABLE `tb_user` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(32) DEFAULT NULL, `birthday` date DEFAULT NULL, `sex` char(1) DEFAULT NULL, `address` varchar(32) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8; |
1.1.3 添加配置文件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"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo?useUnicode=true&characterEncoding=utf-8" /> <property name="username" value="root" /> <property name="password" value="111111" /> </dataSource> </environment> </environments> <mappers> <mapper resource="top/zlcxy/mapper/method1/UserMapper.xml" /> </mappers> </configuration>
|
1.1.4 定义实体
publicclass UserBean { // 编号 private Integer id; // 姓名 private String name; // 出生年月 private Date birthday; // 性别 private Integer sex; private String address; //省略get,set |
1.1.5 添加映射文件UserMapper.xml
<?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"> <mapper namespace="top.zlcxy.mapper.method1.UserMapper"> <!-- 主键查询 --> <select id="findUserByID" parameterType="java.lang.Integer" resultType="top.zlcxy.domain.UserBean"> select * from tb_user where id=#{id} </select> <!-- 用户名模糊查询 --> <select id="findUserLikeName" parameterType="java.lang.String" resultType="top.zlcxy.domain.UserBean"> select * from tb_user where name like '%${value}%' </select> <!-- 插入用户 --> <insert id="insertUser" parameterType="top.zlcxy.domain.UserBean"> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> select last_insert_id() </selectKey> insert into tb_user(name, birthday, sex, address) values(#{name}, #{birthday}, #{sex}, #{address}) </insert> <!-- 删除用户 --> <delete id="deleteUser" parameterType="java.lang.Integer"> delete from tb_user where id=#{id} </delete> <update id="updateUser" parameterType="top.zlcxy.domain.UserBean"> update tb_user set name=#{name} , birthday=#{birthday} ,sex= #{sex}, address = #{address} where id=#{id} </update> </mapper> |
1.1.6 测试代码
publicclass MybatisTest { // 配置文件 privatefinal String CONFIG = "SqlMapConfig.xml"; // 会话对象 private SqlSession session = null;
@Before publicvoid setUp() throws Exception { InputStream is = Resources.getResourceAsStream(CONFIG); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); session = factory.openSession(); } @After publicvoid setDown() throws Exception { if(null!=session){ session.commit(); session.close(); } } /** * 插入用户 */ @Test publicvoid testInsertUser() throws Exception { UserBean user = new UserBean(); user.setAddress("安徽"); user.setName("zlcxy"); user.setBirthday(new Date()); user.setSex(1); session.insert("top.zlcxy.mapper.method1.UserMapper.insertUser", user); System.out.println(user.getId()); } /** * 根据编号查询用户信息 */ @Test publicvoid testQueryUserById() throws Exception { UserBean user = (UserBean) session.selectOne("top.zlcxy.mapper.method1.UserMapper.findUserByID", 1); System.out.println(user); } /** * 根据姓名模糊查询 */ @Test publicvoid testQueryUserLikeName() throws Exception { List<UserBean> users = session.selectList("top.zlcxy.mapper.method1.UserMapper.findUserLikeName", "zlcxy"); System.out.println(users.size()); } /** * 更新用户 */ @Test publicvoid testUpdateUser() throws Exception { UserBean user = new UserBean(); user.setId(1); user.setAddress("广州天河区"); user.setName("zlcxy"); user.setBirthday(new Date()); user.setSex(1); session.update("top.zlcxy.mapper.method1.UserMapper.updateUser", user); } /** * 删除用户 */ @Test publicvoid testDeleteUser() throws Exception { session.delete("top.zlcxy.mapper.method1.UserMapper.deleteUser",1); } } |
1.2 注解方式实现
1.2.1 配置文件中注册mapper
注意:仅有mybatis-3.2.X以后的版本才支持这种写法 <mappers> <mapper class="top.zlcxy.mapper.UserMapper" /> </mappers> |
1.2.2 Mapper接口定义
publicinterface UserMapper { /** * 根据用户编号查询 */ @Select("select * from tb_user where id=#{id}") UserBean findUserByID(Integer id) throws Exception; /** * 根据姓名模糊查询 */ @Select("select * from tb_user where name like '%${value}%'") List<UserBean> findUserLikeName(String name) throws Exception; /** * 插入 */ @Insert("insert into tb_user(name, birthday, sex, address) values(#{name}, #{birthday}, #{sex}, #{address})") @SelectKey(keyProperty="id",before=false,resultType=java.lang.Integer.class, statement = {"select last_insert_id()" }) Integer insertUser(UserBean user) throws Exception; /** * 删除 */ @Delete("delete from tb_user where id=#{id}") void deleteUser(intid) throws Exception; /** *更新 */ @Update("update tb_user set name=#{name}, birthday=#{birthday}, sex=#{sex}, address=#{address} where id=#{id}") void updateUser(UserBean user) throws Exception; } |
1.2.3 测试代码
publicclass MybatisTest2 { // 配置文件 privatefinal String CONFIG = "SqlMapConfig.xml"; // 会话对象 private SqlSession session = null;
@Before publicvoid setUp() throws Exception { InputStream is = Resources.getResourceAsStream(CONFIG); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); session = factory.openSession(); } @After publicvoid setDown() throws Exception { if(null!=session){ session.commit(); session.close(); } } /** * 插入用户 */ @Test publicvoid testInsertUser() throws Exception { UserBean user = new UserBean(); user.setAddress("安徽安庆"); user.setName("zlcxy"); user.setBirthday(new Date()); user.setSex(1); UserMapper mapper = session.getMapper(UserMapper.class); mapper.insertUser(user);
System.out.println(user.getId()); } /** * 根据编号查询用户信息 */ @Test publicvoid testQueryUserById() throws Exception { UserMapper mapper = session.getMapper(UserMapper.class); UserBean user = mapper.findUserByID(1); System.out.println(user); } /** * 根据姓名模糊查询 */ @Test publicvoid testQueryUserLikeName() throws Exception { UserMapper mapper = session.getMapper(UserMapper.class); List<UserBean> users = mapper.findUserLikeName("zlcxy"); System.out.println(users.size()); } /** * 更新用户 */ @Test publicvoid testUpdateUser() throws Exception { UserBean user = new UserBean(); user.setId(1); user.setAddress("广州天河区2"); user.setName("zlcxy"); user.setBirthday(new Date()); user.setSex(1); UserMapper mapper = session.getMapper(UserMapper.class); mapper.updateUser(user); } /** * 删除用户 */ @Test publicvoid testDeleteUser() throws Exception { UserMapper mapper = session.getMapper(UserMapper.class); mapper.deleteUser(1); } } |
1.3 Mapper代理方式实现
1.3.1 在配置文件中注册xml
<mapper resource="top/zlcxy/mapper/method3/UserMapper.xml" /> |
1.3.2 定义mapper接口
publicinterface UserMapper { /** * 根据用户编号查询 */ UserBean findUserByID(Integer id) throws Exception; /** * 根据姓名模糊查询 */ List<UserBean> findUserLikeName(String name) throws Exception; /** * 插入 */ Integer insertUser(UserBean user) throws Exception; /** * 删除 */ void deleteUser(intid) throws Exception; /** *更新 */ void updateUser(UserBean user) throws Exception; } |
1.3.3 定义xml文件
<mapper namespace="top.zlcxy.mapper.method3.UserMapper"> <!-- 主键查询 --> <select id="findUserByID" parameterType="java.lang.Integer" resultType="top.zlcxy.domain.UserBean"> select * from tb_user where id=#{id} </select> </mapper> |
1.3.4 测试代码
publicclass MybatisTest3 { /** * 根据编号查询用户信息 */ @Test publicvoid testQueryUserById() throws Exception { UserMapper mapper = session.getMapper(top.zlcxy.mapper.method3.UserMapper.class); UserBean user = mapper.findUserByID(1); System.out.println(user); } }
|
2. SqlMapConfig.xml配置
2.1 Properties属性
<properties resource="db.properties"/> |
加载顺序:1:在properties元素体内的属性首先被读取;
2:读取resource或url中的属性
3:最后读取parameterType传递的属性,同名会覆盖
2.2 Settings属性
设置全局参数属性,如开启二级缓存,开启延迟加载等
2.3 TypeAliases属性
针对parameterType、resultType的类型定义一些别名
1:单个实体别名
<typeAliases> <typeAlias type="top.zlcxy.domain.UserBean" alias="user"/> </typeAliases> |
2:批量实体类别名
<package name="top.zlcxy.domain"/> resultType="UserBean" 或 resultType="userBean" |
2.4 typeHandlers类型处理器
2.5 mappers映射配置
1:单个映射文件的注入
<mapper resource="top/zlcxy/mapper/method1/UserMapper.xml" /> <mapper class="top.zlcxy.mapper.method2.UserMapper" /> |
2:批量映射文件注入
<package name="top.zlcxy.mapper"/> |
3. 输入映射
通过parameterType指定输入参数的类型,可以是简单类型,hashmap,自定义pojo等
3.1 自定义pojo包装类
publicclass UserQueryVo { private UserBean userBean; public UserBean getUserBean() { returnuserBean; } publicvoid setUserBean(UserBean userBean) { this.userBean = userBean; } } |
3.2 Mapper接口定义方法
/** * 高级查询 */ List<UserQueryVo> findUserList(UserQueryVo userQueryVo) throws Exception; |
3.3 Xml定义
<!-- 高级查询 --> <select id="findUserList" parameterType="top.zlcxy.vo.UserQueryVo" resultType="top.zlcxy.vo.UserQueryVo"> select * from tb_user where sex=#{userBean.sex} and name like '%${userBean.name}%' </select> |
3.4 测试代码
/** * 高级查询 */ @Test publicvoid testQueryUserList() throws Exception { UserMapper mapper = session.getMapper(UserMapper.class); UserQueryVo userQueryVo=new UserQueryVo(); UserBean userBean=new UserBean(); userBean.setSex(1); userBean.setName("zlcxy"); userQueryVo.setUserBean(userBean); List<UserQueryVo> users = mapper.findUserList(userQueryVo); System.out.println(users.size()); } |
4. 输出映射
4.1 ResultType,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功;也可以映射简单类型:返回值只有一行一列
4.2 ResultMap:查询出来的列名和pojo属性名不一致,可以通过ResultMap来设置映射关系
4.2.1 定义xml
<resultMap type="UserBean" id="UserResultMap"> <id column="id_" property="id"/> <result column="name_" property="name"/> <result column="birthday_" property="birthday"/> <result column="sex_" property="sex"/> <result column="address_" property="address"/> </resultMap>
<!-- 主键查询 --> <select id="findUserByIDResultMap" parameterType="java.lang.Integer" resultMap="UserResultMap"> select id id_,name name_, birthday birthday_,sex sex_,address address_ from tb_user where id=#{id} </select> |
4.2.2 定义mapper接口
/** * 根据编号查询 */ UserBean findUserByIDResultMap(Integer id) throws Exception; |
4.2.3 测试代码
/** * 根据编号查询 */ @Test publicvoid testQueryUserByIDResultMap() throws Exception { UserMapper mapper = session.getMapper(UserMapper.class); UserBean user = mapper.findUserByIDResultMap(1); System.out.println(user); } |
5. 动态sql
将高级查询语句优化:
<!-- 高级查询优化 --> <select id="findUserList2" parameterType="top.zlcxy.vo.UserQueryVo" resultType="top.zlcxy.vo.UserQueryVo"> select * from tb_user <where> <if test="userBean!=null"> <if test="userBean.sex!=null and userBean.sex!=''"> and sex=#{userBean.sex} </if> <if test="userBean.name!=null and userBean.name!=''"> and name like '%${userBean.name}%' </if> </if> </where> </select> |
6. Sql片段
6.1 定义sql片段
<sql id="query_user_where"> <if test="userBean!=null"> <if test="userBean.sex!=null and userBean.sex!=''"> and sex=#{userBean.sex} </if> <if test="userBean.name!=null and userBean.name!=''"> and name like '%${userBean.name}%' </if> </if> </sql> |
6.2 使用sql片段
<!-- 高级查询统计优化--> <select id="findUserCount2" parameterType="top.zlcxy.vo.UserQueryVo" resultType="int"> select count(*) from tb_user <where> <include refid="query_user_where"></include> </where> </select> |
7. Foreach使用
7.1 优化pojo包装类
publicclass UserQueryVo { // 用户编号列表 private List<Integer> ids; |
7.2 优化sql片段
<sql id="query_user_where"> <if test="userBean!=null"> <if test="userBean.sex!=null and userBean.sex!=''"> and sex=#{userBean.sex} </if> <if test="userBean.name!=null and userBean.name!=''"> and name like '%${userBean.name}%' </if> </if> <if test="ids!=null"> <foreach collection="ids" separator="or" open="and (" close=")" item="id" > id=#{id} </foreach> </if> </sql> |
7.3 第二种写法
<sql id="query_user_where2"> <if test="userBean!=null"> <if test="userBean.sex!=null and userBean.sex!=''"> and sex=#{userBean.sex} </if> <if test="userBean.name!=null and userBean.name!=''"> and name like '%${userBean.name}%' </if> </if> <if test="ids!=null"> <foreach collection="ids" separator="," open="and id in(" close=")" item="id" > #{id} </foreach> </if> </sql> |
7.4 测试代码
/** * 高级查询优化 */ @Test publicvoid testQueryUserList2() throws Exception { UserMapper mapper = session.getMapper(UserMapper.class); UserQueryVo userQueryVo = new UserQueryVo(); List<Integer> ids=new ArrayList<Integer>(); ids.add(1); ids.add(2); userQueryVo.setIds(ids); //UserBean userBean = new UserBean(); //userBean.setSex(1); //userBean.setName("zlcxy"); //userQueryVo.setUserBean(userBean); List<UserQueryVo> users = mapper.findUserList2(userQueryVo); System.out.println(users.size()); } |
8. 小结
8.1 Mybatis执行过程
8.1.1 配置mybatis的配置文件,SqlMapConfig.xml(名称不固定)
8.1.2 通过配置文件加载mybatis的运行环境,创建SqlSessionFactory会话工厂, SqlSessionFactory在实际使用中是单例方式
8.1.3 通过SqlSessionFactory创建SqlSession会话对象,SqlSession是一个面向用户接口(提供操作数据库方法),实现对象的线程是不安全的,建议应用场合在方法体内
8.1.4 调用SqlSession中的方法执行数据库,若需要提交事务,需执行commit方法
8.1.5 释放资源,关闭SqlSession
8.2 Mybatis开发dao的方法
8.2.1 原始dao开发方式:需要定义接口和实现接口,实现类中注入SqlSessionFactory工厂
8.2.2 Mapper代理开发方式:定义mapper接口,编写mapper.xml映射文件,遵循mybatis开发规范
8.2.2.1 开发规范
mapper.xml中的namespace与mapper接口类名路径一致
mapper.xml中的statement的id与mapper接口的方法名一致
mapper.xml中的statement的parameterType输入类型与mapper接口方法中输入参数类型一致
mapper.xml中的statement的resultType输出类型与mapper接口方法中返回值类型一致
8.2.3 输入映射
ParameterType:指定输入参数类型可以是简单类型,hashmap,自定义pojo
8.2.4 输出映射
ResultType:查询的列名与pojo的属性名一致,才能映射成功
ResultMap:不一致时,可以通过resultMap设置查询列名与属性名间的对应完成映射
欢迎加入技术研究,备注:1
以上是关于Mybatis技术点学习-基础篇的主要内容,如果未能解决你的问题,请参考以下文章
MyBatis基础篇 - 输出映射( resultType)