一、MyBatis介绍java
二、MyBatis架构mysql
四、传统Dao开发与MyBatis的Mapper动态代理开发spring
六、输入映射和输出映射数据库
6.1 parameterTypeexpress
6.2 resultTypeapache
七、动态sql数组
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,而且更名为MyBatis 。2013年11月迁移到Github。
MyBatis是一个优秀的持久层框架,它对jdbc的操做数据库的过程进行封装,使开发者只须要关注 SQL 自己,而不须要花费精力去处理例如注册驱动、建立connection、建立statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis经过xml或注解的方式将要执行的各类statement(statement、preparedStatemnt、CallableStatement)配置起来,并经过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
一、mybatis配置的sqlMapConfig.xml,此文件做为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
mapper.xml文件即sql映射文件,文件中配置了操做数据库的sql语句。此文件须要在sqlMapConfig.xml中加载。
二、经过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
三、由会话工厂建立sqlSession即会话,操做数据库须要经过sqlSession进行。
四、mybatis底层自定义了Executor执行器接口操做数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
五、Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id便是Mapped statement的id。
六、Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor经过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
七、Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor经过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程至关于jdbc编程中对结果的解析处理过程。
1)基本开发环境搭建:基于maven搭建MyBatis开发环境,而后进行测试数据库建立以及相关jar包的引入
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.13</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency>
2)建立配置文件:根据架构图,首先建立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> <properties resource="jdbc.properties"/> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理 --> <transactionManager type="JDBC" /> <!-- 数据库链接池 --> <dataSource type="POOLED"> <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> </configuration>这里咱们使用了jdbc.properties将数据库的相关信息单独提取出来
3)建立pojo:与数据库中的表进行匹配,这里以user表举例
import java.io.Serializable; import java.util.Date; public class User implements Serializable { private static final long serialVersionUID = 1L; private Integer id; private String username;// 用户姓名 private String sex;// 性别 private Date birthday;// 生日 private String 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 String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address=" + address + "]"; } }4)建立映射文件并集中到sqlMapConfig.xml:为User.java建立映射文件User.xml,该文件中主要进行SQL语句的编写
<?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"> <!-- 写Sql语句 --> <mapper namespace="user"> <select id="findUserById" parameterType="Integer" resultType="com.panlei.pojo.User"> select * from user where id = #{v} </select> </mapper>这里的不一样的声明用不一样的id进行区别,parameterType是传参的类型,resultType是返回值类型,要与后面讲到的方法调用进行匹配。namespace是为了区分不一样的映射mapper文件集中到sqlMapConfig.xml中可能id冲突的问题,后面还会具体讲解。
5)具体测试1:根据id查询用户信息,仍是建立SqlSessionFactory,而后获取SqlSession,再调用selectOne(..)方法,根据传递的"user.findUserById"定位到具体的映射文件的具体sql语句,这里传递的参数即是前面定义的所需参数
import com.panlei.pojo.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.Test; import java.io.IOException; import java.io.InputStream; public class TestMyBatis { @Test public void test1() { try { String resource = "sqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); User o = sqlSession.selectOne("user.findUserById", 10); System.out.println(o); } catch (IOException e) { e.printStackTrace(); } } }6)具体测试2:根据用户名模糊匹配查询
具体的sql语句格式:select * from user where username like '%五%'
这里传递的参数就是String类型,而后返回值多是一个用户列表,这里用的是${value},不是前面的#{},后面具体讲解区别
<select id="findUserByUsername" parameterType="String" resultType="com.panlei.pojo.User"> select * from user where username like '%${value}%' </select>// 根据用户名模糊匹配 @Test public void test2() { try { String resource = "sqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); List<User> users = sqlSession.selectList("user.findUserByUsername", "五"); for(User u:users) { System.out.println(u); } } catch (IOException e) { e.printStackTrace(); } }7)#{}与${}的区别
#{}表示一个占位符号,经过#{}能够实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}能够有效防止sql注入。 #{}能够接收简单类型值或pojo属性值。 若是parameterType传输单个简单类型值,#{}括号中能够是value或其它名称。
${}表示拼接sql串,经过${}能够将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}能够接收简单类型值或pojo属性值,若是parameterType传输单个简单类型值,${}括号中只能是value。
8)具体实例3:添加用户,这里直接传递的参数是自定义的User对象实例,直接进行映射,其属性要与pojo中的属性名一致
<!-- 保存用户 --> <insert id="saveUser" parameterType="com.panlei.pojo.User"> INSERT INTO `user` (username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address}) </insert>
这里在实际应用中可能须要当即获取新添加用户的id来进行后续操做,下面演示如何编码:
<insert id="saveUser" parameterType="com.panlei.pojo.User"> <!-- selectKey 标签实现主键返回 --> <!-- keyColumn:主键对应的表中的哪一列 --> <!-- keyProperty:主键对应的pojo中的哪个属性 --> <!-- order:设置在执行insert语句前执行查询id的sql,仍是在执行insert语句以后执行查询id的sql --> <!-- resultType:设置返回的id的类型 --> <selectKey keyColumn="id" keyProperty="id" order="AFTER" resultType="int"> SELECT LAST_INSERT_ID() </selectKey> INSERT INTO `user` (username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address}) </insert>LAST_INSERT_ID():是mysql的函数,返回auto_increment自增列新记录id值。
而后在测试代码中能够直接打印插入用户的id,发现是最新的自增id。不须要额外的代码。
Mybatis解决jdbc编程的问题
一、数据库链接建立、释放频繁形成系统资源浪费从而影响系统性能,若是使用数据库链接池可解决此问题。
解决:在SqlMapConfig.xml中配置数据链接池,使用链接池管理数据库连接。
二、Sql语句写在代码中形成代码不易维护,实际应用sql变化的可能较大,sql变更须要改变java代码。
解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
三、向sql语句传参数麻烦,由于sql语句的where条件不必定,可能多也可能少,占位符须要和参数一一对应。
解决:Mybatis自动将java对象映射至sql语句,经过statement中的parameterType定义输入参数的类型。
四、对结果集解析麻烦,sql变化致使解析代码变化,且解析前须要遍历,若是能将数据库记录封装成pojo对象解析比较方便。
解决:Mybatis自动将sql执行结果映射至java对象,经过statement中的resultType定义输出结果的类型。
传统的Dao开发,就是建立Dao,而后建立Dao的实现类,而后在Service中使用便可,仍是须要针对具体的pojo,建立具体的mapper.xml文件。具体实现就再也不详述。
MyBatis中官方推荐使用编写Mapper接口(至关于Dao接口),而后交给Mybatis进行处理,根据该接口自动建立该接口的动态代理对象。为实现这一目标,事先定义了Mapper接口的开发规范:
1.Mapper.xml文件中的namespace与mapper接口的类路径相同;
2.Mapper接口方法名和Mapper.xml中定义的每一个statement的id相同;
3.Mapper接口方法的输入参数类型和mapper.xml中定义的每一个sql 的parameterType的类型相同;
4.Mapper接口方法的输出参数类型和mapper.xml中定义的每一个sql的resultType的类型相同。
下面结合具体实例解释上述规范:
这样咱们在具体执行时,会自动生成接口的代理类对象,而后执行接口的具体方法时,会根据规范找到对应mapper文件下的相应方法
package com.panlei.mybatisdemo; import com.panlei.mapper.UserMapper; import com.panlei.pojo.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.Before; import org.junit.Test; import java.io.InputStream; import java.util.Date; public class TestMapper { private SqlSessionFactory sqlSessionFactory; @Before public void init() throws Exception { // 建立SqlSessionFactoryBuilder SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); // 加载SqlMapConfig.xml配置文件 InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml"); // 建立SqlsessionFactory this.sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream); } @Test public void testSaveUser() { // 获取sqlSession,和spring整合后由spring管理 SqlSession sqlSession = this.sqlSessionFactory.openSession(); // 从sqlSession中获取Mapper接口的代理对象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = new User(); user.setUsername("萨其马"); user.setSex("2"); user.setBirthday(new Date()); user.setAddress("北京"); // 执行查询方法 userMapper.saveUser(user); // 至关于 sqlSession.insert("namespace.saveUser", user) // System.out.println(user); sqlSession.commit(); // 和spring整合后由spring管理 sqlSession.close(); } }关于selectOne仍是selectList
动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,若是返回list则调用selectList方法,若是返回单个对象则调用selectOne方法。
SqlMapConfig.xml中配置的内容和顺序以下:
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)
1) properties(属性)
能够引用java属性文件中的配置信息,好比前面用到的jdbc.properties
2) typeAliases(类型别名)
咱们前面在传递参数,设置类型的时候,都是使用的 包名+类名,这样比较费劲,那么能不能像配置基本数据类型或者String同样来进行配置呢?答案是能够的,须要利用类型别名。
<typeAliases> <!-- 单个别名定义 --> <typeAlias alias="user" type="com.panlei.pojo.User" /> <!-- 批量别名定义,扫描整个包下的类,别名为类名(大小写不敏感) --> <package name="com.panlei.pojo" /> </typeAliases>在sqlMapConfig.xml中利用<typeAliases>的<typeAlias>进行单个别名的定义。当有特别多的类须要定义的时候,一个一个的定义一样很繁琐,这就能够利用<package>来进行统一的配置。
3) mappers(映射器)
<mapper resource=" " />
使用相对于类路径的资源(如今的使用方式),如:<mapper resource="sqlmap/User.xml" />
<mapper class=" " />
使用mapper接口类路径,如:<mapper class="com.panlei.mybatis.mapper.UserMapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
<package name=""/>
注册指定包下的全部mapper接口,如:<package name="com.panlei.mybatis.mapper"/>。注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
在配置文件的编写具体语句时,咱们须要传入一些参数,前面的例子,咱们已经使用了简单的类型,例如Integer,还有本身定义的POJO的类型,好比咱们自定义的User类型。
还有另一种状况,就是自定义的类型中有另外一个自定义类型的属性,好比User中有一个自定义Order类型的属性,这时咱们须要传递POJO包装对象。下面以一个例子来具体讲解:
1)根据用户名模糊查询用户信息,这里虚设一个只有一个User属性的包装类,而后传递该包装类,利用其User属性的username模糊查询用户信息
包装类
在UserMapper.java中编写查询接口方法:
在UserMapper.xml中编写具体的数据库查询代码,注意四条对应规则(namespace,id,传参,返回类型):这里咱们看到传递参数的名称并未使用,而是直接使用了TestUser中的user属性中的username属性
编写测试代码:
1)输出简单类型
测试例子:SELECT COUNT(*) FROM ‘user’
先是在UserMapper接口中定义查询方法
而后在UserMapper.xml文件中具体编写查询语句
测试输出
2)此外还能够输出POJO对象以及POJO的对象列表,这咱们前面已经使用了,再也不详述
resultType能够指定将查询结果映射为pojo,但须要pojo的属性名和sql查询的列名一致方可映射成功。
若是sql查询字段名和pojo的属性名不一致,能够经过resultMap将字段名和属性名做一个对应关系 ,resultMap实质上还须要将查询结果映射到pojo对象中。
resultMap能够实现将查询结果映射为复杂类型的pojo,好比在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。
下面咱们以具体的例子演示:
1) 查询order表的全部数据
order表的字段及数据以下:这里的user_id不为空
而后咱们定义相应的POJO类型,这里咱们将表中的user_id定义为userId属性,模拟字段与属性不一致的状况。
![]()
为更好的演示,咱们第一次查询仍然使用resultType,看一下运行结果,而后再使用resultMap
具体的步骤仍然是建立OrderMapper接口,定义查询方法,而后在OrderMapper.xml中编写具体的查询语句,并设置resultType类型
最终查询结果输出以下:能够看到userId为null
上面的结果产生缘由就是由于字段与属性没有一一对应的缘由。下面咱们使用resultMap进行演示:
只须要修改OrderMapper.xml便可,为其添加<resultMap>,而后在具体的语句中利用resultMap属性进行关联便可,注意里面的各个属性的含义。
这里由于只须要进行user_id与userId的映射,因此其余属性能够不用处理。
而后咱们运行测试,发现userId已经有值了。
经过mybatis提供的各类标签方法实现动态拼接sql。
需求:根据性别和名字查询用户,有时候条件可能为空,须要进行判断,为空就再也不做为条件
<select id="queryUserByWhere" parameterType="user" resultType="user"> SELECT id, username, birthday, sex, address FROM `user` WHERE 1=1 <if test="sex != null and sex != ''"> AND sex = #{sex} </if> <if test="username != null and username != ''"> AND username LIKE '%${username}%' </if> </select>
上面的sql还有where 1=1 这样的语句,很麻烦
可使用where标签进行改造
<select id="queryUserByWhere" parameterType="user" resultType="user"> SELECT id, username, birthday, sex, address FROM `user` <!-- where标签能够自动添加where,同时处理sql语句中第一个and关键字,也就是删除 --> <where> <if test="sex != null"> AND sex = #{sex} </if> <if test="username != null and username != ''"> AND username LIKE '%${username}%' </if> </where> </select>
Sql中可将重复的sql提取出来,使用时用include引用便可,最终达到sql重用的目的。
把上面例子中的id, username, birthday, sex, address提取出来,做为sql片断,以下:
<!-- 声明sql片断 --> <sql id="userFields"> id, username, birthday, sex, address </sql> <select id="queryUserByWhere" parameterType="user" resultType="user"> <!-- SELECT id, username, birthday, sex, address FROM `user` --> <!-- 使用include标签加载sql片断;refid是sql片断id --> SELECT <include refid="userFields" /> FROM `user` <!-- where标签能够自动添加where关键字,同时处理sql语句中第一个and关键字 --> <where> <if test="sex != null"> AND sex = #{sex} </if> <if test="username != null and username != ''"> AND username LIKE '%${username}%' </if> </where> </select>若是要使用别的Mapper.xml配置的sql片断,能够在refid前面加上对应的Mapper.xml的namespace
<select id="queryUserByWhere" parameterType="user" resultType="user"> SELECT <include refid="com.panlei.mapper.OrderMapper.userFields" /> FROM `user` <!-- where标签能够自动添加where关键字,同时处理sql语句中第一个and关键字 --> <where> <if test="sex != null"> AND sex = #{sex} </if> <if test="username != null and username != ''"> AND username LIKE '%${username}%' </if> </where> </select>
向sql传递数组或List,mybatis使用foreach解析,以下:
根据多个id查询用户信息
查询sql:
SELECT * FROM user WHERE id IN (1,10,24)
对上面用到包装类添加一个 List<Integer> ids 属性
UserMapper.xml以下
<!-- 根据ids查询用户 --> <select id="queryUserByIds" parameterType="queryVo" resultType="user"> SELECT * FROM `user` <where> <!-- foreach标签,进行遍历 --> <!-- collection:遍历的集合,这里是QueryVo的ids属性 --> <!-- item:遍历的项目,能够随便写,,可是和后面的#{}里面要一致 --> <!-- open:在前面添加的sql片断 --> <!-- close:在结尾处添加的sql片断 --> <!-- separator:指定遍历的元素之间使用的分隔符 --> <foreach collection="ids" item="item" open="id IN (" close=")" separator=","> #{item} </foreach> </where> </select>测试代码以下:
@Test public void testQueryUserByIds() { // mybatis和spring整合,整合以后,交给spring管理 SqlSession sqlSession = this.sqlSessionFactory.openSession(); // 建立Mapper接口的动态代理对象,整合以后,交给spring管理 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 使用userMapper执行根据条件查询用户 QueryVo queryVo = new QueryVo(); List<Integer> ids = new ArrayList<>(); ids.add(1); ids.add(10); ids.add(24); queryVo.setIds(ids); List<User> list = userMapper.queryUserByIds(queryVo); for (User u : list) { System.out.println(u); } // mybatis和spring整合,整合以后,交给spring管理 sqlSession.close(); }
需求:查询全部订单信息,关联查询下单用户信息。
sql语句:
SELECT o.id, o.user_id userId, o.number, o.createtime, u.username, u.address FROM `order` o LEFT JOIN `user` u ON o.user_id = u.id
方法一:使用resultType
这里咱们,继承Order类编写Order2User类做为新的pojo类,此pojo类中新增长了订单信息和用户信息。这样返回对象的时候,mybatis自动把用户信息也注入进来了。
使用OrderMapper接口,并在OrderMapper.xml中添加对应的查询语句,最后测试。
这里咱们在sql语句中对数据库字段的uer_id使用了别名userId,这样就不须要使用resultMap来进行映射了。
方法二:使用resultMap
这里直接对Oeder.java进行修改,添加一个User属性,而后在OrderMapper.xml中创建对应的映射。
需求:查询全部用户信息及用户关联的订单信息
sql语句:
SELECT u.id, u.username, u.birthday, u.sex, u.address, o.id oid, o.number, o.createtime, o.note FROM `user` u LEFT JOIN `order` o ON u.id = o.user_id
这里相似于上面的方法二。修改User类,在UserMapper.xml的配置文件中添加<resultMap>,而后编写相应查询语句,最后测试。
一、SqlSessionFactory对象应该放到spring容器中做为单例存在;
二、传统dao的开发方式中,应该从spring容器中得到sqlsession对象;
三、Mapper代理形式中,应该从spring容器中直接得到mapper的代理对象;
四、数据库的链接以及数据库链接池事务管理都交给spring容器来完成。
Spring相关jar包:
Spring<dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.1.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-expression --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jms --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-messaging --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-messaging</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.1.4.RELEASE</version> </dependency>MyBatis相关jar包:
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency>Spring+mybatis的整合包:
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.2</version> </dependency>Mysql的数据库驱动jar包:
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.13</version> </dependency>数据库链接池的jar包:
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 --> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency>
1) applicationContext.xml
View Code<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 引入JDBC配置文件 --> <context:property-placeholder location="jdbc.properties"/> <!-- 配置数据库链接池 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driverClass}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.user}"/> <property name="password" value="${jdbc.password}"/> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 配置数据源 --> <property name="dataSource" ref="dataSource"/> <!-- 配置mybatis核心配置文件 --> <property name="configLocation" value="sqlMapConfig.xml"/> </bean> </beans>2) sqlMapConfig.xml
View Code<?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> <!-- 设置别名 --> <typeAliases> <!-- 2. 指定扫描包,会把包内全部的类都设置别名,别名的名称就是类名,大小写不敏感 --> <package name="com.panlei.pojo" /> </typeAliases> </configuration>3) jdbc.properties
View Codejdbc.driverClass=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost/webuser?serverTimezone=GMT%2B8 jdbc.user=root jdbc.password=panlei
4) log4j.properties
View Code# Global logging configuration log4j.rootLogger=DEBUG, stdout # 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
这里的内容前面有所涉及,本次只讲解关键的内容。
Dao接口与实现类具体代码再也不展现,注意一点,在dao实现类中由于须要调用对应mapper.xml中的具体sql语句,也就须要SqlSession对象,由于咱们是MyBatis与Spring整合,因此咱们不须要本身去new一个对象了,前面咱们已经在applicationContext.xml中对 SqlSessionFactoryBean 进行了配置,并且在spring与mybaits整合的jar包中对这种必然会使用的操做抽象为一个类:SqlSessionDaoSupport,咱们须要在具体的Dao实现类中继承该类,而后使用其中的方法便可,具体以下图:
还有就是编写对应的mapper.xml文件,并在sqlMapConfig.xml中加载该文件,最后在applicationContext.xml配置Dao
而后运行测试
这一部分的基础知识在第4节也有讲解,本次也只是讲解重要的部分或者没有涉及的部分。
首先仍是UserMapper接口与UserMapper.xml按规则对应,而后仍是讲解一下applicationContext.xml中的配置。
第一种方式是为每个Mapper接口配置一个<bean>
用到的MapperFactoryBean也是属于mybatis-spring整合jar包
运行测试
第二种方式是用扫描包的形式配置。第一种方式须要为每个mapper配置一个<bean>,当数量太多时,显得太麻烦。这里能够不注入SqlSessionFactoryBean,能够自动注入