1. 什么是JDBC,有什么用
JDBC API 允许用户访问任何形式的表格数据,尤其是存储在关系数据库中的数据。
2. jdbc 安装
- 复制mysql-connector-java-5.1.49.jar 到lib 文件夹下
- 右键lib add to library
3. 使用
1. 注册驱动
使用 Class.forName("com.mysql.jdbc.Driver")
- 连接数据库
通过 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
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();
- 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实体类
2. 定义DAO
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>
4. 注册Mapper
<mappers>
<mapper resource="PushTagDAOMapper.xml"/>
</mappers>
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);
}
}
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. 别名
这里只需要写到包,不需要写到类!!
2. 添加日志 log4j2
- maven 增加 log4j2
- 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
3. entity 的实体类需要重写一下toString,不然打印的时候只会打印出内存地址
4. 通过实体类或者@Param 传参,而不是arg0
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>
2. 一对多
<?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. 多对多
一个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;
- 定义中间表实体类
user和rule可能都是多个,所以是list
- 定义DAO类
- 定义reusltMap
- 定义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">
<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>
查询结果
sql 执行结果
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. 缓存
- 缓存分为一级缓存和二级缓存
-
- 一级缓存默认开启,sqlSession级别的
- 二级缓存是SqlSessionFactory 级别