本章学习使用MyBatis框架进行CRUD操作(基于代理dao模式),使用Dao实现类的方式CRUD操作、MyBatis中参数深入及结果集的深入、MyBatis中主配置的标签使用、实体类的别名等。
MyBatis框架中的CRUD操作
一、前期准备 1、常见项目导入坐标 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <?xml version="1.0" encoding="UTF-8" ?> <project xmlns ="http://maven.apache.org/POM/4.0.0" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion > 4.0.0</modelVersion > <groupId > 002</groupId > <artifactId > 002</artifactId > <version > 1.0-SNAPSHOT</version > <packaging > jar</packaging > <dependencies > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > <version > 3.4.5</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.1.6</version > </dependency > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.10</version > </dependency > <dependency > <groupId > log4j</groupId > <artifactId > log4j</artifactId > <version > 1.2.12</version > </dependency > </dependencies > </project >
2、创建SqlMapConfig.xml的主配置文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <?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" > </transactionManager > <dataSource type ="POOLED" > <property name ="driver" value ="com.mysql.jdbc.Driver" /> <property name ="url" value ="jdbc:mysql://localhost:3306/eesy_mybatis" /> <property name ="username" value ="root" /> <property name ="password" value ="root" /> </dataSource > </environment > </environments > <mappers > <mapper resource ="com/itheima/dao/IUserDao.xml" /> </mappers > </configuration >
3、常见实体类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 package com.itheima.domain;import java.util.Date;public class User { private Integer id; private String username; private Date birthday; private String sex; private String address; public User () { } public User (Integer id, String username, Date birthday, String sex, String address) { this .id = id; this .username = username; this .birthday = birthday; this .sex = sex; this .address = address; } 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 Date getBirthday () { return birthday; } public void setBirthday (Date birthday) { this .birthday = birthday; } public String getSex () { return sex; } public void setSex (String sex) { this .sex = sex; } public String getAddress () { return address; } public void setAddress (String address) { this .address = address; } @Override public String toString () { return "User{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + '}' ; } }
4、常见接口在内部定义CRUD的方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 package com.itheima.dao;import com.itheima.domain.User;import java.util.List;public interface IUserDao { List<User> findByAll () ; User findByOne (int id) ; List<User> findByLike (String name) ; int addUser (User user) ; int updateUser (User user) ; void deleteUser (int id) ; }
二、编写映射文件并测试运行 1、创建映射文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 <?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 ="com.itheima.dao.IUserDao" > <select id ="findByAll" resultType ="com.itheima.domain.User" > select * from user </select > <select id ="findByOne" resultType ="com.itheima.domain.User" parameterType ="int" > select * from user where id = #{id} </select > <select id ="findByLike" parameterType ="string" resultType ="com.itheima.domain.User" > select * from user where username like '%${value}%' </select > <insert id ="addUser" parameterType ="com.itheima.domain.User" > <selectKey keyProperty ="id" keyColumn ="id" resultType ="int" order ="AFTER" > select last_insert_id() </selectKey > insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) </insert > <update id ="updateUser" parameterType ="com.itheima.domain.User" > update user <set > <if test ="username != null" > username = #{username}, </if > <if test ="sex != null" > sex = #{sex}, </if > <if test ="birthday != birthday" > birthday = #{birthday}, </if > <if test ="address != null" > address = #{address} </if > </set > where id = #{id} </update > <delete id ="deleteUser" parameterType ="int" > delete from user where id = #{id} </delete > </mapper >
该映射文件中的**#{}字符可以理解为和原来sql部分学习的“ ?**”一样,都是占位符。
parameterType的参数是一个简单类型 (基本类型8种+String)的时候,#{}中的值可以任意写,如果是一个对象(例如User),则必须使用属性名称。
ognl 表达式:
它是 apache 提供的一种表达式语言,全称是:
Object Graphic Navigation Language 对象图导航语言
它是按照一定的语法格式来获取数据的。
语法格式就是使用 #{对象.对象}的方式
#{}和${}的区别:
#{}表示一个占位符
通过#{}可以实现perparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。#{}可以接收简单类型值或pojo属性值
${}表示拼接sql串
通过${}可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换, ${}可以接收简单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,${}括号中只能是 value。
2、编写测试类进行测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 package com.itheima.test;import com.itheima.dao.IUserDao;import com.itheima.domain.User;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.After;import org.junit.Before;import org.junit.Test;import java.io.IOException;import java.io.InputStream;import java.util.Date;import java.util.List;public class IUserDaoTest { private InputStream in = null ; private SqlSession session = null ; private IUserDao userDao; @Before public void init () throws Exception { in = Resources.getResourceAsStream("SqlMapConfig.xml" ); SqlSessionFactory factory = new SqlSessionFactoryBuilder ().build(in); session = factory.openSession(); userDao = session.getMapper(IUserDao.class); } @After public void destroy () throws Exception { session.commit(); session.close(); in.close(); } @Test public void findByUserTest () { List<User> users = userDao.findByAll(); for (User user : users) { System.out.println(user); } } @Test public void findByOneTest () { User user = userDao.findByOne(43 ); System.out.println(user); } @Test public void findByLikeTest () { List<User> users = userDao.findByLike("王" ); for (User user : users) { System.out.println(user); } } @Test public void addUserTest () { User user = new User (null ,"wangwu" ,new Date (),"男" ,"西安" ); System.out.println(userDao.addUser(user)); System.out.println(user); } @Test public void updateUserTest () { User user = new User (53 ,"wangwu" ,null ,"男" ,null ); System.out.println(userDao.updateUser(user)); } @Test public void deleteUserTest () { userDao.deleteUser(49 ); } }
三、MyBatis参数深入 在上一章节中已经介绍了 SQL 语句传参,使用标签的 parameterType 属性来设定。该属性的取值可以是基本类型,引用类型(例如:String 类型),还可以是实体类类型(POJO 类)。同时也可以使用实体类的包装类,本章节将介绍如何使用实体类的包装类作为参数传递。
1、MyBatis中的基本数据类型别名 基本数据类型即可以直接写类型名称,也可以使用包名,类名的方式。
例如String既可以写成类型名称(String)也可以写成全限定类名(java.lang.String)。
官方文档给出了基本数据类型的别名说明文档
2、传递POJO包装对象 开发过程中可以通过POJO传递查询条件,查询条件是综合的查询条件,不仅包括用户查询条件还包括其他的查询条件(例如将用户的购买商品也作为查询条件),这时可以使用包装对象传递参数。
(1)实例——编写QueryVo类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class QueryVo { private User user; public QueryVo () { } public QueryVo (User user) { this .user = user; } public User getUser () { return user; } public void setUser (User user) { this .user = user; } }
(2)实例——编写持久层接口 1 2 3 4 5 6 7 8 9 10 11 12 13 import com.itheima.domain.QueryVo;import com.itheima.domain.User;import java.util.List;public interface IUserDao { List<User> findByVo (QueryVo queryVo) ; }
(3)实例——测试包装类查询 1 2 3 4 5 6 7 8 9 10 11 12 @Test public void findByVoTest () { QueryVo queryVo = new QueryVo (); User user1 = new User (); user1.setUsername("%王%" ); queryVo.setUser(user1); List<User> users = userDao.findByVo(queryVo); for (User user: users) { System.out.println(user); } }
四、MyBatis的输出结果的封装 1、resultType配置结果类型 resultType属性可以指定封装结果集的类型,它支持基本类型和实体类型。
resultType和parameterType一样,如果注册过类型别名的可以直接使用别名。没有注册过的必须使用全限定类名。
同时还有一个要求实体类中的属性名称必须和查询语句中的列明保持一致,否则无法实现封装。
2、resultMap结果类型 resultMap标签可以建立查询的列名和实体类的属性名称不一致时建立对应关系。从而实现封装。
在select标签中使用resultMap属性指定引用即可。同时resultMap可以实现将查询结果映射为复杂类型的POJO,例如在查询结果映射对象中包括POJO和List实现一对一和一对多查询。
(1)定义resultMap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <resultMap id ="userMap" type ="com.itheima.domain.User" > <id column ="id" property ="userid" /> <result column ="username" property ="userName" /> <result column ="birthday" property ="userBirthday" /> <result column ="sex" property ="userSex" /> <result column ="address" property ="userAddress" /> </resultMap >
(2)映射配置 1 2 3 4 <select id ="findByAll" resultMap ="userMap" > select * from user </select >
(3)测试及相应结果 1 2 3 4 5 6 7 8 9 10 @Test public void findByUserTest () { List<User> users = userDao.findByAll(); for (User user : users) { System.out.println(user); } }
五、SqlMapConfig.xml配置文件 1、配置的内容与顺序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 -properties(属性) --property -setting(全局配置参数) --setting -typeAliases(类型别名) --typeAliase --packge -typeHandlers(类型处理器) -objectFactory(对象工厂) -plugins(插件) -environments(环境集合属性对象) --environment(环境集合子属性对象) --transactionManager(事务管理) --dataSource(数据源) -mappers(映射器) --marpper --package
2、properties标签配置 配置连接数据库的信息
resource 属性: 用于指定 properties 配置文件的位置,要求配置文件必须在类路径下resource=”jdbcConfig.properties”
url 属性:
URL: Uniform Resource Locator 统一资源定位符
http://localhost:8080/mystroe/CategoryServlet URL
协议 主机 端口 URI
URI: Uniform Resource Identifier 统一资源标识符
/mystroe/CategoryServlet
它是可以在 web 应用中唯一定位一个资源的路径
六、类型别名 1、自定义别名 在SqlMapConfig.xml中配置:
1 2 3 4 5 6 7 <typeAliases > <typeAlias alias ="user" type ="com.itheima.domain.User" /> <package name ="com.itheima.domain" /> <package name ="其他包" /> </typeAliases >
alias属性: 被定义的别名名称。
type属性: 被定义别名的类的全限定类名。
七、mappers(映射器) 1、使用相对类路径的资源
2、使用mapper接口类路径
注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中。
3、注册指定包下的所有 mapper 接口
注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中。
参考资料:
传智黑马MyBatis阶段视频: