Mybatis笔记

ORM object relation mapping(对象关系映射)

实现思想:将关系型数据库中的表记录映射成对象,通过对象进行展示

public class User{
    private Integer id;
    private String name;
    private String pwd;

}
数据库中表的数据
id   name   pwd
1    张三   123456
2    李四   123123

映射关系

类 表

对象 表的(行)记录

属性 表的(列)记录

一.为什么使用Mybatis

1.传统JDBC访问数据库

  • 使用jdbc时大量代码冗余
  • sql写死在程序当中,当sql修改时 类重新编译
  • sql执行后的结果resultSet对象,需要手动处理

2.mybatis

  1. 对jdbc进行封装和简化
  2. sql和类分离 sql写在映射文件Mapper.xml中,当sql修改时 ,类不需要重新编译
  3. sql执行后的结果不需要手动处理,mybatis自动转换成Java对象(自动映射)

3.搭建mybatis工程

(1)创建maven工程,并导入jar包

​
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.chen</groupId>
    <artifactId>mavenTestchen</artifactId>
    <version>1.0-SNAPSHOT</version>
添加依赖的方式:
通过快捷键ale+insert 进行搜索
www.mvnrepository.com
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.9</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.9</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.36</version>
        </dependency>
使用小辣椒快速编写实体类
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
        </dependency>
    </dependencies>
</project>

​

(2)在resources下进行mybatis-config的文件配置

可以通过properties进行配置 创建jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver //数据库版本为8 com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/system?characterEncoding=UTF-8
jdbc.username=用户名
jdbc.password=密码
<?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>
<!--这里的标签要按照顺序进行-->
<!--    用于引入properties文件,之后可以通过${key}访问对应的value值-->
    <properties resource="jdbc.properties"></properties>
<!--设置别名-->
    <typeAliases>
<!--        默认生成的别名不区分大小写 user  User-->
<!--        <typeAlias type="com.chen.pojo.User"></typeAlias>-->
<!--        通过包名的方式解决以后实体类非常多且使用多个typeAlias标签-->
<!--        这个包下的所有实体类都会生成别名-->
        <package name="com.chen.pojo"/>
    <environments default="develop">
可以有多个environment  当需要用到其他的时候进行更换(通过id)
        <environment id="develop">
进行事务管理的方式:可以通过JDBC代理   MANAGER 自己管理事务
            <transactionManager type="JDBC"></transactionManager>
配置数据源: 连接池  JNDI:过时了  POOLED 使用连接池   UNPOOLED 不适用连接池
            <dataSource type="POOLED">
这里其中的 name 和 value 不要写错
                <property name="driver" value="com.mysql.jdbc.Driver"></property>
                <property name="url" value="jdbc:mysql://localhost:3306/数据库名?characterEncoding=UTF-8"></property>
                <property name="username" value="数据库用户"></property>
                <property name="password" value="数据库密码"></property>
            </dataSource>
        </environment>
     <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
mapper文件导入当有多个的时候 可以通过多个mapper标签导入  ./表示当前目录 可以省略
    <mappers>
        <mapper resource="UserMapper.xml"></mapper>
    </mappers>
</configuration> 

(3)进行mapper文件的配置

<?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">
namespace 为对应接口中的全限定类名
<mapper namespace="com.chen.dao.UserDao">
resultType指定的结果返回到什么对象的类型中
mybatis-config中配置 这里可以直接用User作为返回
    <select id="findAll" resultType="User">
        select * from user
    </select>
</mapper> 

(4)pojo类 这里采用小辣椒Lombok简化代码

package com.chen.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Integer user_id;
    private String user_name;
    private String user_pwd;
}

 (5)测试类

    @Test
   public void findAll() throws IOException {
       //1.读取配置文件
       InputStream is=Resources.getResourceAsStream("mybatis-config.xml");
        //获取工厂会话对象
        SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is);
        //通过工厂对象获取sqlsession对象
        SqlSession sqlSession = ssf.openSession();
        //sqlsession通过namespace+id找到要执行的sql语句
        //这里采用动态代理
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> all = mapper.findAll();
        //遍历数据
        for (User u:all){
            System.out.println(u);
        }
    }

 进行代码封装 通过static进行加载

package com.chen.test;

import com.chen.dao.UserDao;
import com.chen.pojo.User;
import com.sun.xml.internal.ws.runtime.config.TubelineFeatureReader;
import jdk.internal.dynalink.support.TypeUtilities;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.jdbc.Null;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import javax.sound.midi.Soundbank;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLOutput;
import java.util.List;
import java.util.Map;
public class UserTest {
    public static SqlSessionFactory ssf=null;
    static {
        try {
            InputStream is=Resources.getResourceAsStream("mybatis-config.xml");
            ssf=new SqlSessionFactoryBuilder().build(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Test
   public void findAll() throws IOException {
//       //1.读取配置文件
//       InputStream is=Resources.getResourceAsStream("mybatis-config.xml");
//        //获取工厂会话对象
//        SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is);
        //通过工厂对象获取sqlsession对象
        SqlSession sqlSession = ssf.openSession();
        //sqlsession通过namespace+id找到要执行的sql语句
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> all = mapper.findAll();
        //遍历数据
        for (User u:all){
            System.out.println(u);
        }
    }
}


4. mybatis执行流程

1.先读取配置文件      mybatis-config.xml    EmpMapper.xml 这里进行两个读取

2.通过配置文件创建sqlSessionFactory工厂

3.通过工厂创建sqlSession对象(连接数据库)

4.通过对象执行sql语句 namespace+id 进行sql定位

(1)找到mapper文件和找到要执行的sql语句

(2)执行sql语句 指定返回的结果用什么类型封装

(3)将数据记录到封装的对象(这里通过pojo中的set方法进行)

(4)最后返回List<V>泛型  二.mybatis增删查改

1.UserDao

    //查询所有
    List<User> findAll();
    //添加用户
    int addUser(User user);
    //删除用户 根据id
    int deleteUser(Integer user_id);
    //修改用户信息
    int updateUser(User user);
    //根据id查询用户信息
    User findById(Integer user_id);

2.mapper配置文件中

<select id="findAll" resultType="User">
        select * from user
    </select>
    <insert id="addUser">
        insert into user values (null,#{user_name},#{user_pwd})
    </insert>
    <delete id="deleteUser">
        delete from user where user_id=#{user_id}
    </delete>
<!--    int updateUser(User user);-->
    <update id="updateUser">
        update user set user_name=#{user_name},user_pwd=#{user_pwd} where user_id=#{user_id}
    </update>
<!--    User findById(Integer user_id);-->
    <select id="findById" resultType="User">
        select * from user where user_id=#{user_id}
    </select>

3.测试

public class UserTest {
    public static SqlSessionFactory ssf=null;
    static {
        try {
            InputStream is=Resources.getResourceAsStream("mybatis-config.xml");
            ssf=new SqlSessionFactoryBuilder().build(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Test
   public void findAll() throws IOException {
//       //1.读取配置文件
//       InputStream is=Resources.getResourceAsStream("mybatis-config.xml");
//        //获取工厂会话对象
//        SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is);
        //通过工厂对象获取sqlsession对象
        SqlSession sqlSession = ssf.openSession();
        //sqlsession通过namespace+id找到要执行的sql语句
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> all = mapper.findAll();
        //遍历数据
        for (User u:all){
            System.out.println(u);
        }
    }
    @Test
    public void addUser() throws IOException {
        User user = new User();
        user.setUser_name("张三");
        user.setUser_pwd("1123");
//        InputStream is=Resources.getResourceAsStream("mybatis-config.xml");
//        SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = ssf.openSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        int i = mapper.addUser(user);
        if(i>0){
            System.out.println("添加成功");
        }
    }
    @Test
    public void deleteUser() throws IOException {
//        InputStream is=Resources.getResourceAsStream("mybatis-config.xml");
//        SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = ssf.openSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        int i = mapper.deleteUser(21);
        if(i>0){
            System.out.println("删除成功");
        }
    }
    @Test
    public void  updateUser(){
        User user = new User();
        user.setUser_id(4);
        user.setUser_name("MC果");
        user.setUser_pwd("112233");
        SqlSession sqlSession = ssf.openSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        int i = mapper.updateUser(user);
        if(i>0){
            System.out.println("修改成功");
        }
    }
    @Test
    public void findById(){
        SqlSession sqlSession = ssf.openSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        User byId = mapper.findById(4);
        System.out.println(byId);
    }
}

三.MyBatis获取


#{}获取 #{}的本质就是占位符赋值 (自动加单引号)
${}获取${}的本质就是字符串拼接(需要手动添加单引号)
若mapper接口方法的参数为多个字面量类型  

此时mybatis会把参数放到map集合中,以两种方式存储

arg1,arg2...为键,以参数为值。
param1,param2...为键,以参数为值。
因此只需要通过#{}和${}访问map集合的键,就可以获取相对应的值,一定要注意${}的单引号问题。

若mapper接口方法的参数为map集合类型的参数

只需通过#{}和${}访问map集合的键,就可以获得相对应的值,一定要注意${}的单引号问题。

若mapper接口方法的参数为实体类类型的参数

只需要通过#{}和${}访问实体类中的属性名,就可以获得相对应的属性值,一定要注意${}的单引号问题。

可以在mapper接口方法的参数上设置@param注解

此时mybatis会把这些参数放到map中,以两种方式进行存储。

以@param注解的value属性值为键,以参数为值。
以param1,param2...为键,以参数为值。
只需要通过#{}和${}访问map集合的键,就可以获取相应的值,一定要注意${}的单引号问题
1.@param注解

//通过注解@param设置 此时MyBatis会将参数放在map中以两种方式进行存储
//1.以@param注解属性的value值为键,以参数为值
//2.以param1 param2注解的属性值为键 以参数为值

//根据姓名和密码进行查询
User findNameAndPwd(@Param("user_name") String user_name,
                    @Param("user_pwd") String user_pwd);
<!--    findNameAndPwd-->
    <select id="findNameAndPwd" resultType="User">
        select * from user where user_name=#{user_name} and user_pwd=#{user_pwd}
    </select>
@Test
public void findNameAndPwd(){
    SqlSession sqlSession = ssf.openSession(true);
    UserDao mapper = sqlSession.getMapper(UserDao.class);
    User admin = mapper.findNameAndPwd("admin","123456");
    System.out.println(admin);
}

2.查询数据转换成map集合

/*
*查询出的数据有多条时,并且将数据转换成map集合
* 1.mapper接口方法的返回值设置为泛型为map的list集合
* List<Map<String,Object>> findAllTomap();
* 2.将每条数据转换成map集合的数据放在一个大的map集合中
* 但是必须要用@MapKey注解 将查询的某个的字段设置为大的map的键
 */

    List<Map<String,Object>> findAlltoMap();
    @MapKey("user_id")
    Map<String,Object> findToMapByKey();
<!--    List<Map<String,Object>> findAlltoMap();-->
    <select id="findAlltoMap" resultType="map">
        select * from user
    </select>
<!--    Map<String,Object> findToMapByKey();-->
    <select id="findToMapByKey" resultType="map">
        select * from user
    </select>
    @Test
    public void findAlltoMap(){
        SqlSession sqlSession = ssf.openSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<Map<String, Object>> alltoMap = mapper.findAlltoMap();
        System.out.println(alltoMap);
    }
    @Test
    public void findToMapByKey(){
        SqlSession sqlSession = ssf.openSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        Map<String, Object> toMapByKey = mapper.findToMapByKey();
        System.out.println(toMapByKey);
    }

3.模糊查询

    //模糊查询
    List<User> findLike(@Param("user_name") String user_name);
<!--    List<User> findLike(@Param("user_name") String user_name);-->
    <select id="findLike" resultType="User">
        select * from user where user_name like "%"#{user_name}"%"
    </select>
    @Test
    public void findLike(){
        SqlSession sqlSession = ssf.openSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> all = mapper.findLike("a");
        for(User u:all){
            System.out.println(u);
        }
    }

4.获取id自增的主键

<!--    int addUserGetId(User user);
useGeneratedKeys:表示当前添加功能使用自增的主键
keyProperty:将添加的数据的自增主键作为实体类类型的参数的属性赋值
因为增删改返回的都是受影响的行数-->

    //添加功能获取id自增主键
    int addUserGetId(User user);
<!--    void addUserGetId(User user);-->
    <insert id="addUserGetId" useGeneratedKeys="true" keyProperty="user_id">
        insert into user values (null,#{user_name},#{user_pwd})
    </insert>
    @Test
    public void addUserGetId(){
        User user = new User();
        user.setUser_name("qwe");
        user.setUser_pwd("123321");
        SqlSession sqlSession = ssf.openSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        int i = mapper.addUserGetId(user);
        System.out.println(i);
    }

四.占位符

1 #{}

(1)#{}:相当于JDBC中{?}问号占位符 ,为了给sql中的参数进行占位,相当于JDBC中的 preparedstatement。并且能防止sql注入攻击。

(2)在#{}为日期类和字符串类进行占位时,在参数传过来时会进行转义处理(自动在日期类和字符串类两边加上单引号)

在mapper中  select * from emp where name=#{name}

在程序执行时  select * from emp where name=?

参数: 张三传入替换占位符

select * from emp where name=张三  --错误

select * from emp where name=’张三’ --正确

2. ${}

${}: 是为SQL片段进行占位,将传过来的sql片段直接拼接在${}占位符所在的位置,相当于JDBC中statement,并且不可以防止SQL注入攻击
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值