ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java之Mybatis

2021-08-26 01:32:10  阅读:163  来源: 互联网

标签:xml Java UserMapper sqlSession user sql Mybatis id


Mybatis

Mybatis简介

什么是Mybatis?

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

Mybatis作用

数据持久化:

持久化就是将程序的数据在持久状态和瞬时状态转换的过程

持久层主要是写完成持久化操作的代码块

而Mybatis就一个优秀的持久层框架

帮助程序员将数据存入数据库中,传统JDBC代码太复杂了,Mybatis可以更方便操作持久化层,容易上手

技术没有高低之分,只有掌握技术的人有高低之分

优点:

  • 简单易学
  • 灵活
  • sql与代码分离,降藕
  • 提供映射标签,支持对象与数据库的orm字段关系映射
  • 提供对象关系映射标签,支持对象关系组建维护
  • 提供xml标签,支持动态编写sql

Mybatis-config.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>
<!--    mybatis环境-->
    <environments default="development">
<!--        第一个环境,id处也可以是default-->
        <environment id="development">
<!--            JDBC事务-->
            <transactionManager type="JDBC"/>
<!--            连接数据库配置-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=GMT-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="com/zh1z3ven/mapper/UserMapper.xml"/>
    </mappers>
</configuration>

注册Mapper的小tips

可以借助*实现匹配所有Mapper.xml

<mappers>
    <mapper resource="com/zh1z3ven/mapper/*Mapper.xml"/>
</mappers>

Mybatis.Utils

因为上面说到了SqlSession实例对象才可以进行对于数据库的操作,这里封装了这个获取sqlSession的步骤

主要是通过:SqlSessionFactoryBuilder > SqlSessionFactory> SqlSession实例==>执行sql语句,操作数据库

//SqlSessionFactoryBuilder ==> SqlSessionFactory
//SqlSessionFactory ==> SqlSession实例
//sqlSession可以执行sql语句,操作数据库
public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;
    //从xml配置生成SqlSessionFactory实例
    static{
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = null;
            inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //获取sqlSession,操作数据库
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
    
}

Mapper接口与Mapper.xml配置文件

这里利用Mapper接口和Mapper.xml配置文件替代了原先的Dao+实现类的操作。

UserMapper接口

public interface UserMapper {
    public List<User> getUserList();
}

UserMapper.xml

可以将Mapper.xml看作是Mapper接口的实现类

  1. namespace绑定dao层接口:namespace="com.zh1z3ven.mapper.UserMapper"
  2. id指定此标签中的sql语句对应于dao层接口的哪个方法:id="getUserList"
  3. resultType设置返回值类型,此处返回的User类型的对象resultType="com.zh1z3ven.pojo.User"
<?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.zh1z3ven.mapper.UserMapper">
    <select id="getUserList" resultType="com.zh1z3ven.pojo.User">
        select * from user
    </select>
</mapper>

SqlSession对象

获取sqlSession对象

String resource = "mybatis-config.xml";
InputStream resourceAsStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();

封装成工具类

MybatisUtils

public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;

    static {

        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = null;
            inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

Mybatis-Select

方法一、getMapper()

sqlSession.getMapper(UserMapper.class);

public class test {
    @Test
    public void testSql(){
        //获取sqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //sqlSession.getMapper()执行SQL
        //调用实现类的getUserList方法
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = userMapper.getUserList();
        //遍历输出
        for (User user : userList) {
            System.out.println(user);
        }
        //关闭资源
        sqlSession.close();
    }
}

方法二、sqlSession.selectList()

sqlSession.selectList("com.zh1z3ven.mapper.UserMapper.getUserList");

public class test {
    @Test
    public void testSql(){
        //获取sqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //sqlSession.select("com.zh1z3ven.UserMapper.getUserList") 执行sql
				List<User> userList = sqlSession.selectList("com.zh1z3ven.mapper.UserMapper.getUserList");
        //遍历输出
        for (User user : userList) {
            System.out.println(user);
        }
        //关闭资源
        sqlSession.close();
    }
}

Mybatis-CRUD

增删改操作需要提交事务才可以完成

Mybatis-Add

UserMapper

int addUser(User user);

UserMapper.xml

<!--    对象中的属性可以直接取出来-->
<insert id="addUser" parameterType="com.zh1z3ven.pojo.User">
    insert mybatis.user(id, name , pwd) values(#{id}, #{name}, #{pwd})
</insert>

testAddUser

@Test
public void testAddUser(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    int i = mapper.addUser(new User(4, "ago", "123321"));
    if (i>0){
        System.out.println("Add User Success");
    }

    //提交事务
    sqlSession.commit();
    sqlSession.close();
}

Mybatis-Update

UserMapper

int updateUser(User user);

UserMapper.xml

<update id="updateUser" parameterType="com.zh1z3ven.pojo.User">
    update mybatis.user set pwd = #{pwd} where id = #{id} and name = #{name}
</update>

testUpdateUser()

//修改user
@Test
public void testUpdateUser(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    int i = mapper.updateUser(new User(4, "ago", "123123"));
    if (i>0){
        System.out.println("Update User Success");
    }
    sqlSession.commit();
    sqlSession.close();
}

Mybatis-Delete

UserMapper

int delUser(User user);

UserMapper.xml

<delete id="delUser" parameterType="com.zh1z3ven.pojo.User">
    delete from mybatis.user where id = #{id} and name  = #{name} and pwd = #{pwd}
</delete>

testDeleteUser()

@Test
public void testDeleteUser(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    int i = mapper.delUser(new User(4, "ago", "123123"));
    if (i>0){
        System.out.println("Delete User Success");
    }
    sqlSession.commit();
    sqlSession.close();
}

Mybatis-Map

普通传参

当数据库需要操作的表的字段或者xml中sql语句需要传入的参数过多时可以考虑用Map传递参数

UserMapper

int addUser2(Map<String,Object> map);

UserMapper.xml

<insert id="addUser2" parameterType="map">
    insert mybatis.user(id, name, pwd) values(#{userId}, #{userName}, #{userPassword})
</insert>

test

@Test
public void addUser2(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    Map<String, Object> map = new HashMap<String, Object>();
    map.put("userId", 6);
    map.put("userName", "zh1z3ven");
    map.put("userPassword", "12344321");

    int i = mapper.addUser2(map);
    if (i>0){
        System.out.println("Add User With Map Success");
    }
    sqlSession.commit();
    sqlSession.close();
}

模糊查询

模糊查询时需要使用到通配符%,一般放在java代码里

UserMapper

List<User> getUserLike(String value);

UserMapper.xml

<select id="getUserLike" resultType="com.zh1z3ven.pojo.User">
    select * from user where name like  #{value}
</select>

test

@Test
public void testGetUserLike(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    HashMap<String, Object> map = new HashMap<String, Object>();
    map.put("value", "li");

    List<User> userList = mapper.getUserLike("%li%");
    for (User user : userList) {
        System.out.println(user);
    }
    sqlSession.close();

}

Mybatis-配置解析

Mybatis-config.xml核心配置文件

环境配置(environments)

mybatis可以适应多种环境,但是SqlSession只能一次用于一种环境

一般通过id属性来配置sql环境

通过default属性选择要使用的sql环境

<environments default="development">

transactionManager(事务管理器)有两种事务管理器JDBC和MANAGED,一般用JDBC可以提交事务和事务回滚。

<transactionManager type="JDBC"/>

dataSource(数据源)用于连接数据库,默认为POOLED,有池的连接

<dataSource type="POOLED">
    <property name="driver" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=GMT-8"/>
    <property name="username" value="root"/>
    <property name="password" value="123456"/>
</dataSource>

属性(properties)

通过配置属性来引用配置文件

之前是像下面一样直接把连接数据库所需的driver url 等写死的,也可以不写死

<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=GMT-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>

通过properties引入外部配置文件

<properties resource="db.properties">
</properties>

<environments default="development">
    <environment id="development">
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
            <property name="driver" value="${driver}"/>
            <property name="url" value="${url}"/>
            <property name="username" value="${username}"/>
            <property name="password" value="${password}"/>
        </dataSource>
    </environment>
</environments>
  • 可以直接引入外部文件
  • 可以在其中增加一些属性配置
  • 如果两个文件同时有同名字段,优先使用外部配置文件的

类型别名(typeAliases)

设置返回类型的别名。只和xml有关,用来减少完全限定名的冗余。

通过指定一个类来给起短名

<typeAliases>
    <typeAlias type="com.zh1z3ven.pojo.User" alias="User"/>
</typeAliases>

通过扫描package来指定JavaBean

在没有注解的情况下会使用JavaBean的小写名来当作别名

<typeAliases>
    <package name="com.zh1z3ven.pojo"/>
</typeAliases>

使用注解形式起别名(在使用扫描package的情况下)

@Alias("类名")

settings(设置)

logImpl => 指定日志实现

映射器(mappers)

方式一:通过指定资源文件xml注册

<mappers>
    <mapper resource="com/zh1z3ven/mapper/UserMapper.xml"/>
</mappers>

方式二:通过class指定映射

<mappers>
    <mapper class="com.zh1z3ven.mapper.UserMapper"/>
</mappers>
  • 接口和他的Mapper配置文件必须同名
  • 接口和他的Mapper配置文件必须在同一个包下

方式三:使用package

<mappers>
    <package name="com.zh1z3ven.mapper.UserMapper"/>
</mappers>

ResultMap

解决属性名和字段名不一致的问题

将数据表中的列与实体类中的属性对应上

UserMapper.xml

<resultMap id="" type="UserMap">
    <result column="id" property="id"/>		<!--column对应数据表中字段,property对应javabean中属性-->
    <result column="name" property="username"/>
    <result column="pwd" property="password"/>
</resultMap>
<!--指定resultMap名字为UserMap-->
<select id="getUserList" resultMap="UserMap">
    select * from user
</select>

设置日志

标准日志输出

在mybatis核心配置文件中添加如下:

<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

Log4j

Log4j是Apache的开源项目,Log4j可以控制日志输出的地方为控制台、GUI组件、文件等;可以设置输出日志的等级;只需要操作配置文件即可,无需改动代码。

Log4j.properties

#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file

#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/kuang.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

在mybatis核心文件中配置log4j

mybatis-config.xml

<settings>
    <setting name="logImpl" value="LOG4J"/>
</settings>

简单使用

//设置log为当前类
static Logger logger = Logger.getLogger(test.class);
@Test
public void testLog4j(){
  //设置log级别
    logger.info("info:进入了Log4j");
    logger.debug("debug:进入了Log4j");
    logger.error("error:进入了Log4j");
}
 public void testSql(){
		//获取sqlSession对象
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    logger.info("info:获取SqlSession对象成功");
    List<User> userList = sqlSession.selectList("com.zh1z3ven.mapper.UserMapper.getUserList");
    //遍历输出
    for (User user : userList) {
        logger.info("info:用户:" + user);
    }
    //关闭资源
    sqlSession.close();
    logger.info("info:关闭资源");
}

Mybatis-注解实现CRUD

之前提到的都是用Mapper映射xml实现的sql语句操作数据库,sql语句主要是写到了xml文件中,Mybatis还提供了注解实现sql语句操作数据库,更加简化了代码编写。但是如果是更复杂的sql,还是需要用xml来编写,注解的方式只适合一些简单的sql语句。

mybatis-config.xml 绑定接口(注意用注解绑定的就是接口,)

<mappers>
    <mapper class="com.zh1z3ven.mapper.UserMapper"></mapper>
</mappers>

UserMapper

public interface UserMapper {
    //查询所有用户
    @Select("select * from user")
    List<User> getUserList();
}

test

static Logger logger = Logger.getLogger(test.class);

@Test
public void testGetUserList(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    List<User> userList = mapper.getUserList();
    for (User user : userList) {
        logger.info("info:"+user);
    }
    sqlSession.close();
}

在mybatis-config.xml注册Mapper(这里不能像xml可以用*匹配所有,需要一个一个注册)

<mappers>
    <mapper class="com.zh1z3ven.mapper.UserMapper"></mapper>
</mappers>

接口

//查询所有用户
@Select("select * from user")
List<User> getUserList();

//根据id查询用户,利用@param注解传参
@Select("select * from user where id = #{id}")
User getUserById(@Param("id") int id);

//add user
@Insert("insert into user (id, name, pwd) values (#{id}, #{username}, #{password})")
int addUser(Map map);

//update user
@Update("update user set name=#{username},pwd=#{password} where id = #{id}")
int updateUser(User user);

//delete user
@Delete("delete from user where id = #{id}")
int deleteUser(@Param("id") int id);

关于@Param注解

  • 用于基本类型或String,引用类型不需要
  • 在sql中引用的就是这里@Param中的值

关于#{}与${}

{}为预编译;${}为直接拼接,可能引发sql注入

Mybatis-动态SQL

动态SQL:利用Mybatis中自带的标签,根据不同的条件生成不同的SQL语句。

简单来说,我们之前利用JDBC写dao层的时候,是没有办法处理sql语句逻辑的,处理逻辑只能在上层实现,那么就造成了可能需要写很多的sql,而动态sql可以帮助我们在mybatis中实现部分的逻辑处理,简化一部分的开发。

在Mybatis中有4种标签

if
choose(when, otherwise)
trim(where, set)
foreach

if

类似于java中if else语句

<select id="StudentMapper" parameterType="Map" resultMap="Student">
    select * from user where
    <if test="id != null!">
        id = #{id}
    </if>
</select>

trim(where, set)

trim标签可以定制where元素的一些功能, trim标签有几个属性值。

prefix=""
prefixOverrides="" 
suffix="" 
suffixOverrides=""

移除指定在prefixOverrides的内容并且插入prefix中指定的内容

当然如果类似于上面if标签那样拼接语句时如果有多个条件的情况下,还是形容上面那样写可能就会报错,例如

<select id="StudentMapper" parameterType="Map" resultMap="Student">
    select * from user where
      <if test="id != null!">
          id = #{id}
      </if>
  		<if test="id != null!">
          and name = #{name}
      </if>
</select>

如果此时之匹配到了name条件的话,sql就会变成

select * from user where and name = xxx;

这样是会出现bug的,正常逻辑应该是如果只匹配到了name参数但是他的sql语句中有and关键字,那么需要去除掉这个and。

而where标签就很好的解决了这个事情:将原sql中的where去掉,改用where标签代替即可

<select id="StudentMapper" parameterType="Map" resultMap="Student">
    select * from user
    <where>
        <if test="id != null!">
          	id = #{id}
      	</if>
  			<if test="name != null!">
        	  and name = #{name}
      	</if>
    </where>
</select>

set 元素可以用于动态包含需要更新的列,忽略其它不更新的列;

set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)

可以配合if或者choose来筛选需要更新的列

<update id="updateAuthorIfNecessary">
  update Author
    <set>
      <if test="username != null">username=#{username},</if>
      <if test="password != null">password=#{password},</if>
      <if test="email != null">email=#{email},</if>
      <if test="bio != null">bio=#{bio}</if>
    </set>
  where id=#{id}
</update>

choose(when, otherwise)

类似于java中swtich case语句,满足when标签中的表达式,则执行该when中的sql语句,若都不满足则执行otherwise中的sql语句

<select id="StudentMapper" parameterType="Map" resultMap="Student">
  select * from user
  <where>
  	<choose>
      <when test="id != null!">
        id = #{id}
      </when>
      <when test="name != null!">
        and name = #{name}
      </when>
      <otherwise>
        and 1=1
      </otherwise>
    </choose>
  </where>
</select>

标签:xml,Java,UserMapper,sqlSession,user,sql,Mybatis,id
来源: https://www.cnblogs.com/CoLo/p/15187683.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有