一、数据库准备
二、搭建MyBatis环境
1.这里又与我们前面创建的项目不太一样,创建的是一个web项目而不是java项目。
2.引入依赖的jar包
3.编写日志输出环境配置文件
log4j.properties
#Global logging configuration
log4j.rootLogger = DEBUG,stdout
//指定日志输出级别,此处为“调试级别”
#Console output..
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
//设置名为stdout的输出载体是“控制台”
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
//设置名为stdout的输出载体的页面布局是可以灵活指定的布局模式
log4j.appender.stdout.layout.ConversionPattern = %5p[%t] - %m%n
//如果layout页面布局选择了PatternLayout,要制定的打印信息的具体格式
4.编写数据库连接池文件
<?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>
<settings>
<!--指定日志输出格式LOGImpl为LOG4J-->
<setting name = "logImpl" value = "LOG4J"></setting>
</settings>
<!--数据库配置环境-->
<environments default = "development">
<environment id = "development">
<!--配置MyBatis的事务控制-->
<transactionManager type = "JDBC"/>
<!--真正的数据库配置信息-->
<dataSource type = "POOLED">
<property name = "driver" value = "com.mysql.jdbc.Driver"></property>
<property name = "url" value = "jdbc:mysql://localhost:3306/test?characterEncoding=utf-8"></property>
<property name = "username" value = "root"></property>
<property name = "password" value = "admin"></property>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource = "com/mr/mapper/Users-Mapper.xml"/>
</mappers>
</configuration>
5.编写SQL映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org/DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace = "test">
<select id = "findUserById" parameterType = "int" resultType = "com.mr.entity.Users">
select * from users where id = #{id}
</select>
</mapper>
#{}是一个占位符,而其中的id表示接收输入参数的名称。由于id是int类型的,因此parameterType的取值为int。
在MyBatis的全局配置文件中,我们没有为包指定别名,因此在resultType中我们用的是完整包名。
在编写玩SQL映射文件之后,为了能让MyBatis资源文件加载类解析Mapper文件,需要把Mapper文件的路径配置在全局配置文件中。
5.编写数据交互类与测试类
DataConnection.java
package com.mr.dataSource;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class DataConnection {
//读入核心配置文件
private String resource = "sqlMapConfig.xml";
//先提前创建好两个对象,会话工厂和会话
private SqlSessionFactory sqlSessionFactory;
private SqlSession sqlSession;
public SqlSession getSqlSession() throws Exception{
//创建输入流,将配置文件读入
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建会话工厂,传入MyBatis配置文件
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}
}
在前面我们如果想要实现某一具体的功能,我们每一个测试类的前面一定都要上面几行代码。尽管我们只需要写一次后面赋值粘贴就好,但是代码仍然看起来非常的冗余。因此,在这里我们做了一步优化,将这两个对象提取出来封装到一个类里面方便以后的使用。
MyBatisTest.java
package com.mr.test;
import java.text.SimpleDateFormat;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import com.mr.dataSource.DataConnection;
import com.mr.entity.Users;
public class MyBatisTest {
public DataConnection dataConnection = new DataConnection();
@Test
public void TestSelect() throws Exception{
//获取sqlSession对象,后面直接使用即可
SqlSession sqlSession = dataConnection.getSqlSession();
Users users = sqlSession.selectOne("test.findUserById", 3);
System.out.println("姓名:" + users.getUserName());
System.out.println("性别:" + users.getGender());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
System.out.println("生日:" + sdf.format(users.getBirthday()));
System.out.println("所在地:" + users.getProvince() + users.getCity());
sqlSession.close();
}
}
@Test标识接下来的这个类是一个测试类,是通过junit实现的,因此如果想要在程序中加入这句话不会报错,就要先引入junit的jar包。
输出结果:
可以看到,log4j和应该出来的结果都已经正常的运行了,说明我们的环境已经每什么问题了,就可以继续进行后面的操作了。
三、模糊查询
模糊查询最重要的一点其实就是SQL语句的书写
<select id = "findUserByUserName" parameterType = "String" resultType = "com.mr.entity.Users">
select * from users where username like '%${value}%'
</select>
我不知道各位有没有注意到这里我们用到的其实是${},而不是之前的#{},这两者之间是有区别的。
${}标识的是连接SQL,在${}中只能使用value代表其中的参数,但是这种方式最大的缺点就是不能防范SQL注入,因此需要谨慎使用${}。
而concat('%', #{value}, '%')却可以防止SQL注入。也可以起到连接字符串的作用,拼接之后就跟上面的那个形式上差不了太多。
我在MyBatisTest中写了两个Test,如果我们想要只运行其中一个的话,我们只需要选中方法名,然后右键运行即可,这样最终出来的结果就不是是多个Test都运行了。
四、案例——增删改
- 新增案例
新增前的数据库:
另外两个测试类程序都可以运行成功,唯独新增案例。
报错信息:
才发现数据库中的Id中的I为大写,但是我在创建User实体类的时候里面写的又是id,其中的i为小写。名称不同,导致MyBatis在映射的时候出现错误。
解决:将数据库中的字段名称改为id。
又是一个报错:这次的错误信息是说在执行插入时字段的数目与数据库中的字段不匹配。
生日列的值与字段的类型不匹配:
插入成功数据后的图片:
解决:
前面报了那么多种错误,我发现只需要解决一个地方就可以彻底解决问题了。
<insert id = "insertUser" parameterType = "com.mr.entity.Users">
insert into users(userName, password, gender, birthday, email, province, city)
values(#{userName}, #{password}, #{gender}, #{birthday,jdbcType=DATE},
#{email}, #{province}, #{city})
</insert>
因为我们在values中缺少id,因此总会报错。于是我在users后面加上了需要插入字段的列名,注意列名的顺序一定要和下面的数据相对应。
仅仅只是按照书上那么写SQL语句是会一直报错的。
注意:在前面的查询操作的过程中,我们都没有执行sqlSession.commit()这样一句话,因为前后都只是从数据库中进行查询;并没有涉及到对数据库的修改。接下来的“增删改”都涉及到了对于数据库的更新操作,因此一定要加上这样一句话——sqlSession.commit()。
- 修改案例
数据库修改前数据
继续报错
注意书上这一部分是有误的
<update id = "updateUser" parameterType = "com.mr.entity.Users">
update users set username = #{username} where id = #{id}
</update>
上面写的是username,而其实我们的数据库与实体类中都是userName。
更改完成之后就可以正常地执行了。
- 删除案例
删除前数据库中数据:
<delete id = "deleteUser" parameterType = "java.lang.Integer">
delete from users where id = #{id}
</delete>
id为5地Steven被删掉了。