目录
MyBatis框架
作用:MyBatis框架是一个持久层框架,用于解决数据库持久化存储方案。
在Java语言中,可以通过JDBC技术实现数据库编程,但是,JDBC技术最大的问题就是编程套路固定,需要编写的代码大致相同,所以就产生了多种解决此问题的框架,例如Hibernate、MyBatis等,这些框架都可以大大的减少开发的工作量,甚至在某些细节的处理上,比手动编写JDBC代码处理得更好!
MyBatis就是可以明显简化开发的数据库持久化存储方案,开发者在使用MyBatis开发某个增/删/改/查功能时,**只需要定义这个功能的抽象方法,及匹配的SQL语句即可**!
除此以外,MyBatis还提供了数据缓存的处理等其它功能!
创建项目:
使用创建SpringMVC项目的步骤创建新的项目,**Group Id**使用`cn.tedu`,**Artifact Id**使用`MyBatis`,**Packaing**选择`war`(其实单机的MyBatis项目并不需要使用`war`,而只使用`jar`即可)。
关于MyBatis项目,必须添加的依赖有:
<!-- MyBatis框架 -->
<!-- 备选版本:3.5.0 ~ 3.5.3 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<!-- MyBatis整合Spring框架 -->
<!-- 备选版本:2.0.0 ~ 2.0.3 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.3</version>
</dependency>
<!-- Spring-WEBMVC -->
<!-- 版本:不低于4.2即可 -->
<!-- 只使用MyBatis的话,其实,只需要spring-context即可,spring-webmvc中包含了spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>XXX</version>
</dependency>
<!-- Spring-JDBC -->
<!-- 版本:必须与使用的spring-webmvc保持一致 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>XXX</version>
</dependency>
<!-- MySQL Connector -->
<!-- 备选版本:8.0.12 ~ 8.0.18 -->
<!-- 备选版本:5.1.34 ~ 5.1.39 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
<!-- 数据库连接池 -->
<!-- 备选版本:1.2, 1.2.2, 1.3, 1.4 -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<!-- 单元测试 -->
<!-- 备选版本:4.10, 4.11, 4.12 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
连接数据库
首先,应该在**src/main/resources**下创建数据库连接相关配置的**db.properties**文件:
url=jdbc:mysql://localhost:3306/tedu_ums?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Chongqing
driver=com.mysql.cj.jdbc.Driver
username=root
password=root
initialSize=2
maxActive=10
将现有的Spring配置文件改名为**spring-mvc.xml**,并将此文件复制得到**spring-dao.xml**文件,在当前项目,后续就只使用**spring-dao.xml**文件即可!
在**spring-dao.xml**中,添加配置,读取以上**db.properties**,并将读到的值注入至`BasicDataSource`对象中:
<util:properties id="config"
location="classpath:db.properties" />
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="url" value="#{config.url}" />
<property name="driverClassName" value="#{config.driver}" />
<property name="username" value="#{config.username}" />
<property name="password" value="#{config.password}" />
<property name="initialSize" value="#{config.initialSize}" />
<property name="maxActive" value="#{config.maxActive}" />
</bean>
,在**src/main/test**下创建`cn.tedu.mybatis.Tests`单元测试类,在类中测试获取数据库连接对象:
public class Tests {
ClassPathXmlApplicationContext ac;
@Before
public void doBefore() {
ac = new ClassPathXmlApplicationContext(
"spring-dao.xml");
}
@Test
public void getConnection() throws SQLException {
BasicDataSource dataSource
= ac.getBean("dataSource", BasicDataSource.class);
System.out.println(dataSource.getConnection());
}
@After
public void doAfter() {
ac.close();
}
}
接口与抽象方法
暂定当前目标:向数据库中插入1条用户数据。
MyBatis要求所有的抽象方法都应该定义在接口中,所以,先创建`cn.tedu.mybatis.UserMapper`接口:
public interface UserMapper {
}
然后,需要在接口中定义“增加用户数据”的抽象方法,关于抽象方法的设计原则:
1. 如果需要执行的数据操作是增、删、改类型的操作,应该将返回值类型声明为`Integer`,表示受影响的行数,如果不关心受影响的行数,也可以将返回值类型声明为`void`,但是,并不推荐这样做;如果需要执行的数据操作是查询操作,返回值类型可以设计为所期望的类型,只要能把查询结果都封装起来就可以;
2. 方法名称可以自由定义,但是,不允许使用重载;
3. 参数列表可以根据需要执行的SQL语句有哪些变量来决定,也可以参考以前学习JDBC时,SQL语句中需要写哪些问号来决定。
此次插入用户数据需要执行的SQL语句大致是:
insert into t_user (username,password,age,phone,email) values (?,?,?,?,?)
为了更加方便表达参数,可以将用户数据封装起来,所以,先创建`cn.tedu.mybatis.User`类,在类中声明与数据表字段对应的属性:
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
private String phone;
private String email;
// SET/GET/toString
}
则在接口中添加抽象方法:
Integer insert(User user);
完成以上代码后,目前,框架并不知道在哪个包中有哪些接口需要处理,所以,需要在**spring-dao.xml**添加配置`MapperScannerConfigurer`的`basePackage`属性:
<!-- MapperScannerConfigurer -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 接口文件在哪里 -->
<property name="basePackage"
value="cn.tedu.mybatis" />
</bean>
至此,关于接口与抽象方法部分的开发已经完成,但是,并不能执行任何测试检测开发与配置的效果!
配置SQL语句
先下载`http://doc.tedu.cn/config/mybatis-mapper.zip`文件,解压得到**SomeMapper.xml**文件。
在项目的**src/main/resources**下创建名为**mappers**的文件夹,并将以上得到的XML文件复制到该文件夹中。
与此前的抽象方法对应的SQL语句都需要配置在这个XML文件中!
在XML中,首先需要添加根节点`<mapper>`,并且,在该节点中配置`namespace`的属性,该属性值是需要对应的接口的全名:
<!-- namespace:对应哪个接口 -->
<mapper namespace="cn.tedu.mybatis.UserMapper">
</mapper>
然后,根据需要执行的SQL语句的种类,选择子级节点,以本次插入用户数据为例,则应该选择`<insert>`节点,这些节点必须指定`id`属性,其值是抽象方法的名称:
<!-- id:抽象方法的名称 -->
<insert id="insert">
</insert>
在该节点内部,配置需要执行的SQL语句:
<!-- id:抽象方法的名称 -->
<insert id="insert">
INSERT INTO t_user (
username, password,
age, phone,
email
) VALUES (
#{username}, #{password},
#{age}, #{phone},
#{email}
)
</insert>
以上代码中,使用`#{}`框住的名称,其实是`User`类中的属性名!
完成后,还需要配置`SqlSessionFactoryBean`,配置框架执行时使用的数据源,及配置SQL语句的XML文件的位置:
<!-- SqlSessionFactoryBean -->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- XML文件在哪里 -->
<property name="mapperLocations"
value="classpath:mappers/*.xml" />
<!-- 使用哪个数据源 -->
<property name="dataSource"
ref="dataSource" />
</bean>
至此,开发任务完成,在`Tests`测试类中编写并执行单元测试:
@Test
public void insert() {
// 获取UserMapper接口的代理对象
UserMapper userMapper
= ac.getBean("userMapper", UserMapper.class);
// 测试功能
User user = new User();
user.setUsername("mapper");
user.setPassword("8888");
user.setAge(25);
user.setPhone("13800139999");
user.setEmail("mapper@163.com");
Integer rows = userMapper.insert(user);
System.out.println("rows=" + rows);
}
如果执行出错,并且,不是注册重复的用户名,则错误的原因可能在于:
1. 配置的接口文件的位置有误,导致无法获取到名为`userMapper`的对象;
2. 配置的XML文件的位置有误;
3. 在XML文件中,根节点的`namespace`属性值有误;
4. 在`<insert>`节点中,`id`属性的值并不是抽象方法的名称;
开发新功能
1. 根据id删除指定的数据
在`UserMapper`接口中声明抽象方法:
Integer deleteById(Integer id);<