JDBC 和 mybatis

1. 什么是JDBC,有什么用

JDBC API 允许用户访问任何形式的表格数据,尤其是存储在关系数据库中的数据。

 

2. jdbc 安装

  1. 复制mysql-connector-java-5.1.49.jar 到lib 文件夹下
  2. 右键lib add to library

JDBC 和 mybatis

 

3. 使用

1. 注册驱动

使用 Class.forName("com.mysql.jdbc.Driver")
  1. 连接数据库

通过 DriverManager.getConnection(url,user,password) 获取数据库连接

URL: jdbc:mysql://localhost:3306/database

username:root

password:1234

 //  1. 驱动
Class.forName("com.mysql.jdbc.Driver");
// 2. 获取连接

String url = "jdbc:mysql://localhost:3306/book";
String user = "root";
String pwd = "root";
Connection con = DriverManager.getConnection(url,user,pwd);

if(con != null){
    System.out.println("db 连接成功");
}else{
    System.out.println("error");

 

 

4.JDBC API

 

JDBC 和 mybatis

 

5.执行sql 并判断结果

 // 3.获取发送sql的对象
        Statement statement = conn.createStatement();

// 4. 执行并返回结果
int result = statement.executeUpdate(sql);

 // 5. 处理结果
if(result == 1){
    System.out.println("成功");
}else{
    System.out.println("失败");
}

 

6.资源释放

// 6. 释放资源
statement.close();
conn.close();

JDBC 和 mybatis

 

 

  1. ResultSet (结果集) 查询

 

// 4. 执行sql
ResultSet res = statement.executeQuery("SELECT * FROM user");
// 5. 判断结果
while (res.next()) {
    String username = res.getString("username");
    String password = res.getString("password");
    String email = res.getString("email");
    System.out.println(username + "  " + password + "  " + email);
}
// 6. 释放资源
// ResultSet 也要释放
res.close();
statement.close();
conn.close();

 

 

7. DAO data access object

 

 

 

8. 什么是Mybatis

优秀的java 开发的持久层的框架。基于jdbc封装。

9. 安装`mybatis`

1. 在pom.xml中添加maven依赖,然后同步

 

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.5.6</version>
</dependency>

 

2.mybatis 配置

创建mybits-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>
  <!-- 环境配置:事务管理器和数据源配置 -->
  <environments default="development">
    <environment id="development">
      <!--   事务控制级别 JDBC   -->
      <transactionManager type="JDBC"/>
      <!--      数据库连接配置     -->
      <dataSource type="POOLED">
        <!--    相当于引入driver 驱动    -->
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <!--   连接串url     -->
        <property name="url" value="jdbc:mysql://localhost:3306/pms_one"/>
        <!--   用户名     -->
        <property name="username" value="lc"/>
        <!--   密码     -->
        <property name="password" value="123456"/>
      </dataSource>
    </environment>
  </environments>

  <!-- 映射器 -->
  <mappers>
    <mapper resource="com/brave/dao/mapper/UpmsUserMapper.xml"/>
  </mappers>
</configuration>

 

 

10. Mybatis开发步骤

1. 定义entity实体类

JDBC 和 mybatis

2. 定义DAO

JDBC 和 mybatis

 

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 指定为 DAO -->
<mapper namespace="com.study.dao.PushTagDao">

<!-- 描述方法 -->
<!-- 里面写sql语句 -->
<!-- id 是DAO方法名称,resultType 是entity 的方法 -->
  <select id="queryPushTag" resultType="com.study.entity.PushTag" >
    SELECT id,tag_id as tagId, _timestamp as timestamp  from
    cbs_push_tag_table
    WHERE id = #{arg0}
  </select>
</mapper>

JDBC 和 mybatis

4. 注册Mapper

 <mappers>
    <mapper resource="PushTagDAOMapper.xml"/>
  </mappers>

JDBC 和 mybatis

 

 

5. 测试结果

import com.study.dao.PushTagDao;
import com.study.entity.PushTag;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class TestPushTag {
  public static void main(String[] args) throws IOException {
    // 1. 加载配置文件
    InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
    // 2. 构建sqlsessionFactory
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    // 3. 通过 sqlSessionFactory 创建 sqlsession
    SqlSession sqlSession = sqlSessionFactory.openSession();
    // 4. 通过 sqlSession 获得DAO实现类的对象
    PushTagDao mapper = sqlSession.getMapper(PushTagDao.class);
    // 5.测试查询方法
    PushTag p1 = mapper.queryPushTag(1);
    PushTag p2 = mapper.queryPushTag(2);
    // 输出结果
    System.out.println(p1);
    System.out.println(p2);
  }
}

JDBC 和 mybatis

 

 

11. 导入jdbc外部配置到mapper

1. 创建 jdbc.properties 文件

jdbc.url=jdbc:mysql://192.168.32.14:3306/pms_one
jdbc.username=lc
[email protected]
jdbc.driver=com.mysql.jdbc.Driver

2. 在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>
  <properties resource="jdbc.properties"></properties>
  <!-- 环境配置:事务管理器和数据源配置 -->
  <environments default="development">
    <environment id="development">
      <!--   事务控制级别 JDBC   -->
      <transactionManager type="JDBC"/>
      <!--      数据库连接配置     -->
      <dataSource type="POOLED">
        <!--    相当于引入driver 驱动    -->
        <property name="driver" value="${jdbc.driver}"/>
        <!--   连接串url     -->
        <property name="url" value="${jdbc.url}"/>
        <!--   用户名     -->
        <property name="username" value="${jdbc.username}"/>
        <!--   密码     -->
        <property name="password" value="${jdbc.pwd}"/>
      </dataSource>
    </environment>
  </environments>

  <!-- 映射器 -->
  <mappers>
    <mapper resource="PushTagDAOMapper.xml"/>
  </mappers>
</configuration>

 

12. mybatis 细节配置

1. 别名

这里只需要写到包,不需要写到类!!

JDBC 和 mybatis

JDBC 和 mybatis

 

2. 添加日志 log4j2

  1. maven 增加 log4j2
  2. resources 增加log4j2.xml
// log4j.properties


// log4j.properties
# 配置根Logger
log4j.rootLogger=debug,stdout

log4j.logger.org.mybatis.example.BlogMapper=TRACE
# 输出信息到控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

JDBC 和 mybatis

3. entity 的实体类需要重写一下toString,不然打印的时候只会打印出内存地址

4. 通过实体类或者@Param 传参,而不是arg0

 

JDBC 和 mybatis

JDBC 和 mybatis

 

5. 模糊查询的字符拼接

<select id="queryUserByLikeName" resultType="User">
  SELECT id,username,password,email
  FROM user WHERE username Like concat('%',#{username},'%');
</select>

 

 

13. CURD

1. 新增(返回自增id)

// 使用自增id的返回自增id
<insert id="insertUser" parameterType="User">
  <!-- 在插入之后 做点什么-->
  <!-- keyProperty 把结果设置到该字段上 -->
  <selectKey order="AFTER" keyProperty="id" resultType="Integer">
    SELECT LAST_INSERT_ID();
  </selectKey>
  INSERT INTO user
  values(NULL,#{username},#{password},#{email})
</insert>

<!-- id 方法名称 parameterType 入参类型 useGeneratedKeys 是否自增主键 keyProperty 主键field -->
<insert id="insertUser2" parameterType="User" useGeneratedKeys="true" keyProperty="id">
  INSERT INTO user
  values(NULL,#{username},#{password},#{email})
</insert>

// 使用before 的事件钩子提前生成一个UUID 的主键
<insert id="insertBook" parameterType="Books">
  <selectKey keyProperty="id" resultType="string" order="BEFORE">
    SELECT REPLACE(UUID(),'-','')
  </selectKey>
  INSERT INTO books
  VALUES (#{id},#{book_name},#{book_desc},#{price})
</insert>

2. update

<!-- 更新并返回受影响的行数 -->
<update id="updateUserById">
  UPDATE user
  SET username = #{username}
  where id = #{id}
</update>

3. delete

<!-- 删除并返回受影响的行数 -->
<delete id="deleteUserById">
  DELETE FROM user
  WHERE id= #{id}
</delete>

14. 事务

sqlSession.submit();
sqlSession.rollback();

 

15. 封装工具类

package com.study.utils;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class MyBatisUtils{

    /**
     * 利用线程来保证 一个线程内多个实例不同时调用初始化
     */
    private  static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();

    private static  SqlSessionFactory sqlSessionFactory = null;

    static {
        try {
            // 1. 获取输入
            InputStream inputStream = null;
            inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            // 2. 获取sqlSecessionFactory
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static void newSqlSession(){
        // 3. 获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        threadLocal.set(sqlSession);
    }

    public static SqlSession getSqlSession(){
        // 从线程中获取sqlSession
        SqlSession sqlSession = threadLocal.get();
        //
        if(sqlSession != null){
            return sqlSession;
        }
        newSqlSession();
        return threadLocal.get();
    }



}

 

16. 映射

<!-- 设置字段映射 可以把小驼峰和大驼峰映射起来 -->
<resultMap id="books_site" type="Books" >
  <id column="id" property="id" ></id>
  <result property="bookName" column="book_name" ></result>
  <result property="bookDesc" column="book_desc"></result>
  <result property="price" column="price"></result>
</resultMap>

17. 表关系

1. 一对一

// 一对一
<mapper namespace="com.study.dao.SitesDAO">
    <resultMap id="sites_result" type="Sites">
        <id column="id" property="id"></id>
        <result column="site_name" property="siteName"></result>
        <result column="url" property="url"></result>
        <result column="book_id" property="bookId"></result>
        <!-- 关联关系:1对1 一本书 对应一个站点 -->
        <association property="book" javaType="Books">
            <id column="bookId" property="id"></id>
            <result column="book_name" property="bookName"></result>
            <result column="book_desc" property="BookDesc"></result>
            <result column="price" property="price"></result>
        </association>
    </resultMap>

    <select id="selectAllSites" resultMap="sites_result">
        SELECT books.id bookId,books.book_name,book_desc,books.price,sites.id as id,sites.url,sites.site_name,sites.book_id as bookId
        FROM books
        INNER JOIN sites
        ON sites.book_id = books.id
    </select>
</mapper>

JDBC 和 mybatisJDBC 和 mybatis

 

2. 一对多

JDBC 和 mybatis

JDBC 和 mybatis

<?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 指定为 DAO -->
<mapper namespace="com.study.dao.UnitDAO">
    <resultMap id="unit_staff_obj" type="Unit">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <!-- collection 集合 property 和as 的一样, ofType 理解为 as的 javaType -->
        <collection  property="staff" ofType="Staff">
            <id column="staff_id" property="id"></id>
            <result column="staff_name" property="name"></result>
            <result column="unit_id" property="unitId"></result>
        </collection >
    </resultMap>

    <select id="selectUnitStaffById" resultMap="unit_staff_obj">
        SELECT unit.id as id,unit.name as name ,staff.id as staff_id,staff.name as staff_name,staff.unit_id as unit_id
        FROM unit
        LEFT JOIN staff
        ON unit.id = staff.unit_id
        WHERE unit.id = #{id}
    </select>
</mapper>

3. 多对多

JDBC 和 mybatis

一个user对应多个rule,一个rule对应多个user。

 

select user.id as userId,user.username as userName,user.email as userEmail,rule.id as ruleId,rule.rule_name as ruleName from user_rule as userRule
INNER join user
ON userRule.user_id = user.id
INNER join rule
ON rule.id = userRule.rule_id;

 

  1. 定义中间表实体类

user和rule可能都是多个,所以是list

JDBC 和 mybatis

  1. 定义DAO类

JDBC 和 mybatis

  1. 定义reusltMap

JDBC 和 mybatis

  1. 定义mapper描述方法

JDBC 和 mybatis

 

<?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.study.dao.UserRuleDAO">
    <resultMap id="one_user_many_rule" type="UserRule">
        <id column="id" property="id"></id>
        <result column="user_id" property="userId"></result>
        <result column="rule_id" property="ruleId"></result>

        <collection property="user" ofType="User">
            <id column="id" property="id"></id>
            <result column="username" property="username"></result>
            <result column="password" property="password"></result>
            <result column="email" property="email"></result>
        </collection>

        <collection property="rule" ofType="Rule">
            <id column="id" property="id"></id>
            <result column="rule_name" property="ruleName"></result>
        </collection>
    </resultMap>


    <select id="queryUserAndRule" resultMap="one_user_many_rule">
        SELECT userRule.id as id,userRule.user_id as user_id, userRule.rule_id as rule_id,
            rule.rule_name as rule_name,user.username,user.email,user.password
        FROM user_rule as userRule
         INNER JOIN user
                    ON user.id = user_id
         INNER JOIN rule
                    ON rule.id = userRule.rule_id
    </select>
</mapper>

查询结果

JDBC 和 mybatis

sql 执行结果

JDBC 和 mybatis

 

 

18. 动态sql

 <!-- 动态sql:if -->
    <select id="queryUserAndRule" resultMap="one_user_many_rule">
        SELECT * from user_rule
        <if test="userId != null">
            WHERE user_id = userId
        </if>
    </select>

    <!-- 动态sql:foreach in id的情况下 -->
    <select id="selectPostIn" resultType="domain.blog.Post">
        SELECT * FROM POST P
        WHERE ID
        in
        <foreach item="item" index="index" collection="list" open="(" separator="," close=")">
            #{item}
        </foreach>
    </select>

19. 缓存

  1. 缓存分为一级缓存和二级缓存
    1. 一级缓存默认开启,sqlSession级别的
  1. 二级缓存是SqlSessionFactory 级别