mybatis学习笔记

Mybatis-study

pom文件

<?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>org.example</groupId>
   <artifactId>mybatis-study-02-crud</artifactId>
   <version>1.0-SNAPSHOT</version>

   <dependencies>
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.11</version>
           <scope>test</scope>
       </dependency>

       <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
       <dependency>
           <groupId>org.mybatis</groupId>
           <artifactId>mybatis</artifactId>
           <version>3.4.1</version>
       </dependency>

       <!-- https://mvnrepository.com/artifact/log4j/log4j -->
       <dependency>
           <groupId>log4j</groupId>
           <artifactId>log4j</artifactId>
           <version>1.2.17</version>
       </dependency>

       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>5.1.48</version>
       </dependency>

       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
           <version>1.18.12</version>
           <scope>provided</scope>
       </dependency>

       <dependency>
           <groupId>cglib</groupId>
           <artifactId>cglib</artifactId>
           <version>3.1</version>
       </dependency>
   </dependencies>
</project>

mybatis 的配置文件

<?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>-->
<!--       &lt;!&ndash;-->
<!--           setting:设置某些属性-->
<!--               - name:设置属性的名-->
<!--               - value:设置属性的值-->
<!--       &ndash;&gt;-->
<!--       <setting name="" value=""/>-->
<!--   </settings>-->


   <!--
       在 servlet 的初始化时加载 spring 的容器

   -->

   <!--
       environments:设置连接数据库的环境
           - default :设置默认使用发数据库环境
    -->
   <environments default="mysql">
       <!--
           environment: 某个具有的环境
               - id:数据库环境的唯一标识
       -->
       <environment id="mysql">
           <!--
               transactionManager:
                   - type:设置事务管理方式
                       -:JDBC:使用最JDBC最原始的事务管理进行事务管理方式
                           提交和回滚需要手动处理
                       -:MANAGED:被管理,交个可用管理的框架进行管理
           -->
           <transactionManager type="JDBC"/>
           <!--
               dataSource:
                   - type:
                       - JNDI:调用上下文的数据源
                       - POOLED:使用默认的数据库连接池(每次使用前都会先到连接池中获取)
                       - UNPOOLED:不使用数据库连接池(每次连接都会创建)
           -->
           <dataSource type="POOLED">
               <!--
                   设置连接池
               -->
               <property name="driver" value="com.mysql.jdbc.Driver"/>
               <!--
                   设置连地址
               -->
               <property name="url" value="jdbc:mysql://localhost:3306/mybatis_study"/>
               <!--
                   设置连接名
               -->
               <property name="username" value="root"/>
               <!--
                   设置连接密码
               -->
               <property name="password" value=""/>
           </dataSource>
       </environment>
   </environments>

   <mappers>
       <mapper resource="mapper/EmpMapper.xml"></mapper>
       <mapper resource="mapper/EmpSelectMapper.xml"></mapper>
       <!-- 如果使用 package 需要把包和 xml 文件在同一包下 -->
<!--       <package name="lyy.mapper"/>-->
   </mappers>
</configuration>

映射文件

<?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="lyy.mapper.EmpMapper">

   <select id="getEmpByEid" resultType="lyy.bean.Emp">
      SELECT * FROM `emp` WHERE `eid` = #{eid}
   </select>

   <select id="getAllEmp" resultType="lyy.bean.Emp">
      SELECT * FROM `emp`
   </select>

   <insert id="addEmp">
      INSERT INTO `emp`(`ename`, `age`, `sex`)
      VALUES (#{ename},#{age},#{sex})
   </insert>

   <!--
       parameterType : 执行方法的参数类型
       myBatis 中有类型推断机制,可用不用使用 parameterType
   -->
   <update id="updateEmp" parameterType="lyy.bean.Emp">
      UPDATE `emp` SET `ename`=#{ename},`age`=#{age},`sex`=#{sex}
      WHERE `eid` = #{eid}
   </update>

   <delete id="deleteEmp">
      DELETE FROM `emp` WHERE `eid` = #{eid}
   </delete>
   
   <select id="getEmpMapBy" resultType="lyy.bean.Emp">
      SELECT * FROM `emp`
   </select>

</mapper>

mapper接口类

package lyy.mapper;

import lyy.bean.Emp;

import java.util.List;

/**
* @program: mybatis-2020
* @description:
* @author: LYY
* @create: 2020-08-11 12:07
*/
public interface EmpMapper {

   // 更具 eid 查询信息
   Emp getEmpByEid(String eid);
   // 获取所有的信息
   List<Emp> getAllEmp();
   // 添加信息
   int addEmp(Emp emp);
   // 修改信息
   int updateEmp(Emp emp);

   // 删除信息
   // 返回值(int):受影响的行数
   // 返回值(boolean): 是否操作成功
   Boolean deleteEmp(String eid);
   
   // 更具 map 集合查询所有的员工
   @MapKey("eid")// 设置 map 集合的键,在查询时传出所有的员工信息,可用把员工信息作为值,但是必须设置 map 集合的 key 值
   Map<String,Object> getEmpMapBy();
}

实体类

package lyy.bean;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

/**
* @program: mybatis-2020
* @description:
* @author: LYY
* @create: 2020-08-11 12:05
*/
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class Emp {

   private Integer eid;
   private String ename;
   private Integer age;
   private String sex;

   @Override
   public String toString() {
       return "Emp{" +
               "eid=" + eid +
               ", ename='" + ename + '\'' +
               ", age=" + age +
               ", sex='" + sex + '\'' +
               '}';
  }
}

使用mybatis

    @Test
   public void test() throws IOException {
       // 获取 mybatis 配置文件的输入流对象
       InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
       // 根据字节输入流创建 SqlSessionFactory
       SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
       SqlSessionFactory sqlSessionFactory =
               new SqlSessionFactoryBuilder().build(is);
       // 获取 sqlSession 方法
       SqlSession sqlSession = sqlSessionFactory.openSession();// 需要手动提交事务
       SqlSession sqlSessionOuto = sqlSessionFactory.openSession(true);// 自动提交事务

       // 通过 session 获取 mapper 接口的实现对象
       // .getMapper 通过动态代理,动态生成 UserMapper 的代理的实现类
       // 会先通过 全类名找到对应的映射文件,在通过其方法的方法名找到映射文件中id对应的sql语句
       UserMapper mapper = sqlSession.getMapper(UserMapper.class);
       // 查看 mapper 的实现类
       System.out.println(mapper.getClass().getName());
       List<User> userList = mapper.getAllUser();
       System.out.println(userList);
       sqlSession.commit();// 提交事务
  }

${}和#{}的区别

${}和#{} 生成的 Sql 语句的区别

${} : 在执行时,如果有字符串必须手动拼接

#{} : 不用考虑是否是字符串的问题

<!--
#{}:
运行的 sql 语句是 INSERT INTO `emp`(`ename`, `age`, `sex`) VALUES (?,?,?)
会使用到 PreparedStatement 对象(预编译对象)
然后使用 :
PreparedStatement.set(1,value);替换第1个 ? 的值为 value
PreparedStatement.set(2,value2):替换第2个 ? 的值为 value2
......
最后使用
PreparedStatement.excuteUpdate

特点:
-- 可用防止 sql 注入攻击
-- 可用和传入的参数名不同

-->
<insert id="addEmp">
      INSERT INTO `emp`(`ename`, `age`, `sex`) VALUES (#{ename},#{age},#{sex})
</insert>
<!--
${}:
运行的 sql 语句是 INSERT INTO `emp`(`ename`, `age`, `sex`) VALUES (老王王,12,男)
会使用到 Statement 对象
Steatement statement = Connection(java.sel).createStatement 对象();
String sql = INSERT INTO `emp`(`ename`, `age`, `sex`) VALUES ('+"ename+"'',"+age+",'"+sex+"')
直接执行 sql 语句,需要自己拼接sql语句
statement.execute(String sql);

特点:
-- 不能防止 sql 注入
-- 在模糊查询和批量删除的时候使用 ${}
-- ${}:必须和参数名一致
-->
<insert id="addEmp">
  <!--
如果使用 ${} 需要手动加上 ''
-->
      INSERT INTO `emp`(`ename`, `age`, `sex`) VALUES ('${ename}',${age},'${sex}')
</insert>

${}和#{}取值的方式

如果出现 : BindingException 那么说明通过 #{} 或者 ${} 获取值的方式出现了问题

<!--
Emp getEmpByEid(String eid);

1、传入的值为单个 基本数据类型 和 其包装类 或 String 值
       #{}:可用不用和参数名一致
       ${}:必须和参数名一致
           会把传入的值当成实体类对象,通过 get 方法获取其值
           但是可用使用 value 获取 _parameter 获取出传入的值
2、当传输为 javaBean(实体类) 时
#{} 和 ${} 可用通过属性名获取其属性值,但是要注意 ${} 的单引号问题
3、传入的值为多个值

#{}:可用使用 #{0}(根据索引获取值) 或者 #{parameter1}(第几个参数获取其值) 进行访问
-- 索引
...... eid = #{0} and ename = #{1}
-- 参数
...... eid = #{param1} and ename = #{param2}

${}:不能使用索引 ${数值} 只能使用 #{param2}
--
...... ${param1} and ename = ${param2}

mybatis 会默认将这些参数放在 map 集合中,会以两种方式实现
-- 1、键为 1,2,3 ... n-1 值为参数
-- 2、键为 param1,param2 ... paramN 值为参数
4、传输为的参数为 map 时
#{} 和 ${} 都可以通过键的名字获取值
5、使用 @Param 注解
可以为其自动生成键,自定义键的名字
Emp getEmpByEidAndEname(@Param("eid") String eid,@Param("ename") String ename);
在 xml 直接使用 ${eid} 或者 #{eid}
6、传入的参数为 List 或者 Array
mybatis 会将 List 或者 Array 放在 map 中
List 以 list 为键
Array 以 array 为键
-->
<select id="getEmpByEid" resultType="lyy.bean.Emp">
SELECT * FROM emp WHERE eid = #{eid}
</select>
<!--Emp getEmpByEidAndEname(String eid,String ename);-->
<select id="getEmpByEidAndEname">
  SELECT * FROM emp WHERE eid = #{eid} and ename = #{ename}
</select>

mybatis获取自动生成的主键

在 JDBC 中获取自自动生成主键

Class.forName("")
Connrction(java.sql) conn = DriverManager.getConnection(url,name,pwd)
PreparedStatement ps = conn.prepareStatement(sql语句)
ResultSet rs = ps.getGeneratedKeys();
// 替换 ?
......
re.next();
int ud = rs.getInt();

mapper.xml 中写法

    <!--
       useGeneratedKeys : 开启自动生成的主键
       keyProperty : 设置生成的主键赋值给传递过来的参数的哪一个属性
如: lyy.bean.Emp 的 eid 属性(parameterType可以省略)
   -->
   <insert id="addEmp" parameterType="lyy.bean.Emp" useGeneratedKeys="true" keyProperty="eid">
      INSERT INTO `emp`(`eid`,`ename`, `age`, `sex`) VALUES (null,#{ename},#{age},#{sex})
   </insert>



posted @ 2020-08-11 15:33  lyy2018  阅读(108)  评论(0)    收藏  举报