前言
mybatis是一个非常优秀的持久层框架,相信很多人之前都使用过JDBC来操作数据库,说实话的确是比较麻烦的,我们先得根据DriverManager创建数据库连接对象connecting,然后根据连接对象创建Statement对象,接下来在根据statement对象执行相应的操作,我们应该把重心放在业务逻辑的代码实现上面,那莫mybatis就做到了让程序员专注功能的代码实现。接下来我们就看一看如何开心的使用mybatis吧。
配置
首先我们需要一个xml配置文件,必要的连接数据库的信息
mybatis.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">
<!--核心配置文件,可以配置多个环境,默认就是的development-->
<configuration>
<properties resource="db.properties"/>
<environments default="development">
<!-- 可以有多个环境 ,设定一个默认的,id对应你要设置默认的-->
<environment id="development">
<!--使用JDBC事务管理-->
<transactionManager type="JDBC"/>
<!-- 使用数据库连接池,POOLED-->
<dataSource type="POOLED">
<!--底下一些连接数据库的必要信息,是根据上面db.properties文件来获取的-->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
</configuration>
db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&userUnicode=true&characterEncoding=utf-8
username=root
password=13468724917qkm,
还需要获取sqlSession对象的工具类,sqlSession对象可以执行CRUD操作
MybatisUtils.java
public class MybatisUtils {
//工厂对象只需要创建一次,并且一直存在,不要引起资源浪费,最好使用单例模式,想象成数据库连接池,从中取所以他得存在,并且只存在一个
private static SqlSessionFactory sqlSessionFactory;
static{
String resource = "mybatis.xml";
try {
//加载全局配置文件
InputStream resourceAsStream = Resources.getResourceAsStream(resource);
//SqlSessionFactoryBuilder尽量放成局部变量,因为只使用一次,还要解析xml文件(XMLConfigBuilder),获取配置文件的信息,
// 然后获取sqlSessionFactory对象
sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//SqlSession对象类似于每个请求一个该对象,所以用完该对象一定记得关闭
//设置为true自动提交,尽量不设置自动提交,怕代码有问题。
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
操作
数据库连接操作做好之后,我们现在有Blog类,同时在数据库里面有一张表blog,现在我们来对这张表进行操作
Blog类
public class Blog {
private String id;
private String title;
private String author;
private Date createTime;
private int views;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public int getViews() {
return views;
}
public void setViews(int views) {
this.views = views;
}
@Override
public String toString() {
return "Blog{" +
"id='" + id + '\'' +
", title='" + title + '\'' +
", author='" + author + '\'' +
", createTime=" + createTime +
", views=" + views +
'}';
}
}
我们还需要一个mapper接口来定义关于一些方法,如下
public interface BlogMapper {
//增加
void addBlog(Blog blog);
//查询所有的
List<Blog> queryBlog();
//更新
void updateBlog();
//根据ID查询
Blog queryBlogById(String id);
//根据ID删除
void deleteBlog(String id);
}
上面的接口定义了5个方法,接下来我们要使用这些方法是不是想着要写实现类了。在mybatis里我们不用写一个实现类,而是写一个mapper映射的xml文件,在mapper.xml文件写具体的sql语句。
xml文件来写具体的sql
BlogMapper.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="com.mybatis.Dao.BlogMapper">
<!--查询,id对应方法的命名,resultType表示结果参数,返回为list里面的泛型-->
<select id="queryBlog" resultType="com.mybatis.Bean.Blog">
select * from blog
</select>
<!--插入,id对应方法的命名,parameterType表示方法参数类型,用#{
}表示占位符,就是你要传入参数的命名,当你传入一个对象时,那么就可以写每个属性的名字,-->
<insert id="insertUser" parameterType="com.mybatis.Bean.Blog" >
insert into blog values(insert into blog values(#{
id},#{
title},#{
author},#{
createTime},#{
views}));
</insert>
<!--同时参数也可以根据Map传递,就是相当于,将对象的每个属性名称作为键,然后他的值就是Map的值,则在传递参数的时候就是输入键命名就可以。当时用Map传递时就将parameterType改为map,如下-->
<!--更新-->
<update id="updateBlog" parameterType="map" >
update blog set title = #{
title}, author = #{
author} where id = #{
id}
</update>
</mapper>
接下来很重要的一步就是在mybatis.xml里面注册BlogMapper.xml文件
<mappers>
<!--注册BlogMapper一定要注册,不然会报错没有注册-->
<mapper class="com.mybatis.Dao.BlogMapper"/>
</mappers>
mapper里面可以有很多种写法,上面是class意味着注解和xml实现sql都可以,但是写class是有要求的mapper java文件和mapper配置文件命名相同且在同一个包下才会读取到mapper xml文。当你使用resource时可以这样写resource=“com/mybatis/Dao/BlogMapper.xml” 这个意味着注册BlogMapper.xml利用xml实现sql具体操作。当你把mapper配置文件放在java的目录下时,项目是读取不到该配置文件的,但你还是想放在这个地方,那就得在pom.xml中添加如下,就可以了,如果你放在resource底下,就可以不用加,默认就是从这目录下读取。
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
写个Test方法测试一下查询
@Tes <typeAliases>
<!--这个就是直接给类起别名,不能是接口-
<typeAlias type="com.mybatis.Bean.User" alias="user"/>-->
<!--当一个包下的类比较多的时候可以直接写包名,那么类名小写就是他的别名,
或者使用注解@Alias(只有在有底下这个的时候才可以用)在xml文件里面可以写Alias的别名,也可以是类名小写-->
<package name="com.mybatis.Bean"/>
</typeAliases>
t
public void queryBlogTest(){
//获取SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//根据SqlSession对象来获取接口的实现类(底层是利用JDK动态代理创建接口的实现类,会读取mapper配置文件)
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
//调用接口里面定义的方法
List<Blog> blogs = mapper.queryBlog();
//输出
blogs.forEach((blog)-> System.out.println(blog.toString()));
//关闭资源
sqlSession.close();
}
上面测试就可以出现结果,然后我们在来说一下改进的方面 resultType可在mybatis.xml里面重命名,简化,在mybatis里面配置
<typeAliases>
<!--这个就是直接给类起别名,不能是接口-
<typeAlias type="com.mybatis.Bean.User" alias="user"/>-->
<!--当一个包下的类比较多的时候可以直接写包名,那么类名小写就是他的别名,
或者使用注解@Alias(只有在有底下这个的时候才可以用)在xml文件里面可以写Alias的别名,也可以是类名小写-->
<package name="com.mybatis.Bean"/>
</typeAliases>
所以也可以直接写blog,这里还有一个问题就是当返回结果集的类属性和数据库里列的命名命名不一致的话,我们可以利用resultMap来实现,如下:
<resultMap id="BlogMap" type="com.mybatis.Bean,Blog">
<!--property 为类中属性的名字,column为表中列的名字-->
<result property="id" column="t_id"/>
</resultMap>
<select id="queryBlog" resultMap="BlogMap">
select * from blog
</select>
注意保证resultMap id 和操作sql语句的resultMap一致就可以达到结果集映射
测试插入
@Test
public void addBlogTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Blog blog = new Blog();
blog.setId(UuidUtils.getId());
blog.setTitle("Mybatis");
blog.setAuthor("狂神说");
blog.setCreateTime(new Date());
blog.setViews(9999);
mapper.addBlog(blog);
sqlSession.commit();
sqlSession.close();
}
其中UuidUtils是一个随机数的工具类
public class UuidUtils {
public static String getId(){
return UUID.randomUUID().toString().replaceAll("-","");
}
}
我们可以看到new出Blog对象然后设置值进行增加就可以,还有就是我们可以传入Map来实现增加如下,注意我们在进行增删改差的时候一定记得进行提交,不然最终数据库是不会发生改变的,如果你使用Map作为参数那么在接口方法的参数也要发生改变:
Map作为参数
@Test
public void addBlogTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap<String, Object> map1 = new HashMap<>();
map1.put("id",UuidUtils.getId());
map1.put("title","Mybatis");
map1.put("author","狂神说");
map1.put("createTime",new Date());
map1.put("views",9999);
mapper.addBlog(map1);
sqlSession.commit();
sqlSession.close();
}
如上就是进行map作为参数增加Blog,那么在#{}里面填入的就是map的键,你设置的。
测试一下更新
@Test
public void updateBlogTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap<String, Object> map = new HashMap<>();
map.put("title","Java3");
map.put("author","狂神说2");
map.put("id","2a327598c9374510aa929a18724d4b0a");
mapper.updateBlog(map);
sqlSession.commit();
sqlSession.close();
}
如上是利用map来更新表,我们从mapper文件可以看到更新的sql语句是固定的,那如果我在更新的前提是他不为空我在更新,那写绝对的sql就是有问题的,这是就有标签和标签我们来使用使用如下:
<update id="updateBlog" parameterType="map" >
update blog
<set>
<if test="title != null">
title = #{
title},
</if>
<if test="author != null">
author = #{
author}
</if>
</set>
where id = #{
id}
/update>
上面是一个动态sql外面是一个set标签他具有很智能的功能,会自动加不加逗号,我们也知道最后一个更新语句是不用加逗号的,其次就是if,if 里面的test就是判断条件,满足的话就加入sql语句中,这样就会形成很动态的sql,还有一个标签是可以很智能的判断要不要加and和where
还没写完。。。。。