正文记录第①次利用Mybatis时遇上的有的荒谬和精炼明白,采取的演示是Eclipse中的JAVA工程,选用XML文件定义数据库连接。

 

能够使用Java JDBC
API直接操作数据库,但利用框架会更便捷、高效而且还是能利用框架提供的一些强大的效应(比如事务管理),而Mybatis就是那般的1个框架。

Mybatis重要由四大学一年级些组成:

①SqlSessionFactoryBuilder

②SqlSessionFactory

③SqlSession

④SQL Mapper

要想拜会(操作)数据库:要确立数据库连接,要定义数据库操作方法(insert/update/delete…),要有切实可行的操作数据库中的表
的SQL语句,而SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession正是用来承担底层建立数据库连接、管理总是、释放连接等。对于业务层而言,关切的是:定义叁个SQL语句,让Mybatis方便地把SQL语句执行后的结果
显示给使用者,而那足以通过SQL Mapper来实现。

SQL Mapper由两部分组成,一是:JAVA 接口,该接口中定义了 业务层
要对数据库进行何种操作;另一局地是:XML配置文件,定义了切实可行的数据库操作语句和照耀规则。

只要要操作数据库test中的表 t_role,t_role有七个字段:id
,role_name,和 note

+———–+————-+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+———–+————-+——+—–+———+—————-+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| role_name | varchar(20) | YES | | NULL | |
| note | varchar(20) | YES | | NULL | |
+———–+————-+——+—–+———+—————-+

该表对应的POJO类如下:

图片 1图片 2

package chapter2.pojo;

public class Role {
    private Long id;
    private String roleName;
    private String note;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getRoleName() {
        return roleName;
    }
    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }
    public String getNote() {
        return note;
    }
    public void setNote(String note) {
        this.note = note;
    }

    @Override
    public String toString() {
        return "id:" + id + ", roleName:" + roleName + ", note:" + note;
    }
}

View Code

 

JAVA接口中定义的一对操作如下:

package chapter2.mapper;
import java.util.List;
import java.util.Map;
import chapter2.pojo.Role;

public interface RoleMapper {
    public Role getRole(Long id);
    public int deleteRole(Long id);
    public int insertRole(Role role);
    public List<Role> findRoleByMap(Map<String, String> params);
}

 

与该接口对应,定义的具体操作数据库的配置文件RoleMapper.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="chapter2.mapper.RoleMapper">

<resultMap type="chapter2.pojo.Role" id="roleMap">
<id property="id" column="id"/><!-- primary key -->
<result property="roleName" column="role_name"/><!-- 普通列的映射关系 -->
<result property="note" column="note"/>
</resultMap>


    <select id="getRole" parameterType="long" resultType="Role">
        select id, role_name as roleName, note from t_role where id = #{id}
    </select>
    <insert id="insertRole" parameterType="Role">
        insert into t_role(role_name,note) values(#{roleName},#{note})
    </insert>
    <delete id="deleteRole" parameterType="long">
        delete from t_role where id = #{id}
    </delete>

    <select id="findRoleByMap" parameterType="map" resultMap="roleMap">
        select id,role_name,note from t_role
        where role_name like concat('%', #{roleName},'%')
        and note like concat('%',#{note},'%')
    </select>
</mapper>

 

然后,就能够用SqlSessionFactory创立SqlSession,SqlSession获取相应的RoleMapper实例,再使用RoleMapper实例调用RoleMapper接口中定义的方式,最后由Mybatis依据RoleMapper.xml配置文件将 方法 与
映射成具体的数据库操作语句,最终访问数据库。

使用SqlSessionFactoryBuilder 依据 mybatisConfig.xml中配备的
dataSource成立SqlSessionFactory,再利用SqlSessionFactory成立SqlSession
,代码如下:

图片 3图片 4

package chapter2.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

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 SqlSessionFactoryUtil {
    private static SqlSessionFactory sqlSessionFactory = null;
    private static final Class CLASS_LOCK = SqlSessionFactoryUtil.class;
    private SqlSessionFactoryUtil() {}

    public static SqlSessionFactory initSqlSessionFactory() {
        String resource = "mybatisConfig.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        }catch(IOException ex) {
            Logger.getLogger(SqlSessionFactoryUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        synchronized (CLASS_LOCK) {
            if(sqlSessionFactory == null) {
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            }
        }
        return sqlSessionFactory;
    }

    public static SqlSession openSqlSession() {
        if(sqlSessionFactory == null)
        {
            initSqlSessionFactory();
        }
        return sqlSessionFactory.openSession();
    }
}

View Code

 

报错:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in 
class path resource [detect/xx/xx/applicationContext.xml]: Invocation of init method failed; nested exception is org.springframework.core.NestedIOException:
 Failed to parse config resource: class path resource [detect/xx/xx/mybatisConfig.xml]; nested exception is org.apache.ibatis.builder.BuilderException:
 Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error creating document instance.  
Cause: org.xml.sax.SAXParseException; lineNumber: 18; columnNumber: 142; 元素内容必须由格式正确的字符数据或标记组成。

从上边错误可看出,若无法正确地开创sqlSessionFactory,有恐怕是
mybatisConfig.xml配置有错
,而 mybatisConfig.xml里面 通过
<mapper>标签钦赐了 xxxMapper.xml SQL Mapper Configuration。

因此,也要检查 xxxMapper.xml 中写的 SQL 语句 是不是科学

用户程序遵照SqlSession来获取RoleMapper(第叁0行),然后调用里面定义的方法操作数据库,从那里也得以见见,咱俩只须要定义好接口,在XML配置文件中定义SQL操作语句,就能够访问数据库了:代码如下:

图片 5图片 6

package chapter2.main;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

import chapter2.mapper.RoleMapper;
import chapter2.pojo.Role;
import chapter2.util.SqlSessionFactoryUtil;

public class Chapter2Main {
    public static void main(String[] args)throws IOException {
        SqlSession sqlSession = null;

        try {
            sqlSession = SqlSessionFactoryUtil.openSqlSession();
            RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);

            Role role = new Role();
            role.setRoleName("testName");
            role.setNote("testNote");
            roleMapper.insertRole(role);
            //roleMapper.deleteRole(1L);
            sqlSession.commit();

            Map<String, String> paramsMap = new HashMap<>();
            paramsMap.put("roleName", "me");
            paramsMap.put("note", "no");//与sql语句中的 #{note} #{roleName}一致
            List<Role> result = roleMapper.findRoleByMap(paramsMap);
            for (Role role2 : result) {
                System.out.println(role2);
            }

        }catch(Exception e) {
            System.out.println(e);
            sqlSession.rollback();
        }finally {
            if(sqlSession != null)
                sqlSession.close();
        }

    }
}

View Code

 

Mybatis配置数据库连接: mybatisConfig.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"    
 3 "http://mybatis.org/dtd/mybatis-3-config.dtd">
 4 <configuration>
 5     <properties resource="jdbc.properties">
 6     </properties>
 7     <typeAliases>
 8         <typeAlias alias="Role" type="chapter2.pojo.Role" />
 9     </typeAliases>
10 
11     <environments default="development">
12         <environment id="development">
13             <transactionManager type="JDBC">
14                 <property name="autoCommit" value="false" />
15             </transactionManager>
16             <dataSource type="POOLED">
17                 <property name="driver" value="${driver}" />
18                 <property name="url" value="${url}" />
19                 <property name="username" value="${username}" />
20                 <property name="password" value="${password}" />
21             </dataSource>
22         </environment>
23     </environments>
24 
25     <mappers>
26         <mapper resource="chapter2\mapper\RoleMapper.xml" />
27     </mappers>
28 </configuration>

Mybatis的XML配置文件定义了诸多配置标签:比如 <configuration>
<properties> <settings> <typeAliases> ….等标签。

这一个标签是有层次结构的,顺序无法乱。比如,<properties>标签应该放在 <typeAliases>
标签后边。

上面包车型地铁第4行<properties>标签 通过  resource
钦赐八个表面jdbc配置文件
,这样在16-21行铺排 数据源 的时候,就足以选择变量 来引用 外部jdbc配置文件中定义的值了,从而利于切换数据库配置。

外表jdbc配置文件如下:

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=xxxx

 

上边来重点表明:操作数据库的XML配置文件RoleMapper.xml 和 接口RoleMapper
以及POJO类RoleMapper之间的局地事关:

RoleMapper 接口中定义的getRole方法:

public Role getRole(Long id);

 

RoleMapper.xml配置文件中与该方法对应的SQL语句:

    <select id="getRole" parameterType="long" resultType="Role">
        select id, role_name as roleName, note from t_role where id = #{id}
    </select>

id 用来唯一标明这条 select 语句。它与RoleMapper.xml中 <mapper
namespace>标签内容结合在同步,唯一标识了 这条 select
操作语句。那边的resultType=”Role”,”Role”是在mybatisConfig.xml中定义的外号。

<mapper namespace="chapter2.mapper.RoleMapper">

public Role getRole(Long id);

<select id="getRole" parameterType="long" resultType="Role">


id 的值getRole 就是接口RoleMapper中 定义的 getRole方法名
parameterType 就是getRole方法的参数类型
resultType 就是执行SQL语句后返回的结果,把结果 封装 成POJO类 Role 类型---这也是getRole方法的返回类型。而方法的参数 会传递给#{id}

 

两种传 四个参数
给SQL语句的格局:

一,通过Map对象传参数

RoleMapper中定义的findRoleByMap方法

    public List<Role> findRoleByMap(Map<String, String> params);

    <select id="findRoleByMap" parameterType="map" resultMap="roleMap">
        select id,role_name,note from t_role
        where role_name like concat('%', #{roleName},'%')
        and note like concat('%',#{note},'%')
    </select>

当大家供给依照五个 参数
查找数据库时,且查找的结果也说不定回到多条记下时,就使用方面包车型大巴布局。

paramterType=”map”,传入一个map对象作为select语句的参数,其中map中的每一个成分的key
对应 while子句中的#{roleName},#{note}

出于此处的while子句 只根据 多个参数 来询问,于是map的长短为2.
而map的value,则是 查询的尺码的值。

            Map<String, String> paramsMap = new HashMap<>();
            paramsMap.put("roleName", "me");//value是要满足的条件值   while note = "me"
            paramsMap.put("note", "no");//Key与sql语句中的 #{note} #{roleName}一致
            List<Role> result = roleMapper.findRoleByMap(paramsMap);

select id,role_name,note from t_role   where role_name like
concat(‘%’, ?,’%’)   and note like concat(‘%’,?,’%’)

比如:select id,role_name,note from t_role   where role_name
like concat(“me”)   and note
like concat(“no”)

 

resultMap指明了回去的“结果”的样式:resultMap=roleMap。resultMap的概念如下:(可领略为:resultMap的key是
属性名也许字段名,而value则是 相应的 结果值)

<resultMap type="chapter2.pojo.Role" id="roleMap">
<id property="id" column="id"/><!-- primary key -->
<result property="roleName" column="role_name"/><!-- 普通列的映射关系 -->
<result property="note" column="note"/>
</resultMap>

<id property=”id” column=”id” 表明 id
是 t_role表的主键
,主键的列名是 “id”

<result property=”roleName” colum=”role_name”/>
证明:roleName是POJO类的属性名,”role_name”是数据库表t_role的列名,将双边对应起来。

 

二,使用参数申明的艺术传送多少个参数

抑或使用更“易懂“的照射方法:—-参数阐明

RoleMapper接口里面定义的点子:

    public List<Role> findRoleByAnnotation(@Param("roleName")String roleName, @Param("note")String note);

 

RoleMapper.xml配置文件之中的概念的SQL语句:那里就没有 paramterType 来定义查询的参数了

        <select id="findRoleByAnnotation"resultMap="roleMap">
        select id,role_name,note from t_role
        where role_name like concat('%', #{roleName},'%')
        and note like concat('%',#{note},'%')
    </select>

 

客户端 调用方法:那里,就能够不用HashMap封装四个待查询的参数了。

List<Role> res = roleMapper.findRoleByAnnotation("me", "no");
for (Role role2 : res) {
    System.out.println(role2);
    }

 

三,使用JAVA Bean对象传递参数:

RoleMapper.xml配置文件之中的定义的SQL语句:

    <select id="findRoleByParam" parameterType="chapter2.pojo.RoleParam"
        resultMap="roleMap">
        select id,role_name,note from t_role
        where role_name like
        concat('%', #{roleName},'%')
        and note like concat('%',#{note},'%')
    </select>

 

RoleMapper.java接口方法:

    public List<Role> findRoleByParam(RoleParam role);

 

客户端调用实践:

            RoleParam rp = new RoleParam();
            rp.setNote("note");
            rp.setRoleName("test");
            List<Role> roles = roleMapper.findRoleByParam(rp);

 

批量布置操作:

RoleMapper.xml配置文件之中的概念的SQL语句:

    <insert id="insertBatch"  useGeneratedKeys="true" parameterType="java.util.List">
        insert into t_role(role_name, note)
        values
        <foreach collection="list" item="item" index="index"
            separator=",">
            (#{item.roleName},#{item.note})
        </foreach>
    </insert>

useGeneratedKeys=”true”
注明使用数据库表中自带的主键自增策略。在篇章所述的t_role表的结构中, id
是自增的主键,可是此地的批量安排操作,并不要求突显的插入 id 的值。

待插入的每条记下值 放在 java.util.List 对象中保存,通过 foreach
循环遍历,”item”代表遍历到的每条记下—即每种Role对象, 通过
#{item.roleName} 和 #{item.note}
取出Role对象属性值—即每一个表的字段值。

RoleMapper.java接口方法:

    public void insertBatch(List<Role> roleList);

 

客户端调用实践:(记得最后 调用 commit() 方法实行提交)

            sqlSession = SqlSessionFactoryUtil.openSqlSession();
            RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);

            Role role = new Role();
            role.setRoleName("testName");
            role.setNote("testNote");

            Role role2 = new Role();
            role2.setRoleName("xx");
            role2.setNote("notexx");

            List<Role> roleList = new ArrayList<>();
            roleList.add(role2);
            roleList.add(role2);

            roleMapper.insertBatch(roleList);
            System.out.println("insert finished");
            sqlSession.commit();

 

相关文章

网站地图xml地图