这里写目录标题
Maven依赖的导入
- 自动化构建项目
- 管理项目依赖(这里的依赖就是jar包),maven可以自动配置添加和管理,自动下载和导入
传统的项目构建,需要先去下载相关的jar包,然后导入到程序中去,后期修改和更新很麻烦。
现在可以使用maven工具来完成。
Maven环境搭建
环境配置:JDK环境
Maven环境搭建(下载Maven)
https://maven.apache.org/
复制路径,配置环境变量
工具操作:IDEA概述
将idea默认的配置改成刚刚下载的maven包
创建一个maven模板
maven依赖的解锁网站
国外的网站不好进
https://mvnrepository.com/
bug解决—无法加载导入的依赖
解决方法:就是idea版本和maven版本不匹配(我使用的是idea2017,要使用的maven版本为3.5.3才行,高版本不兼容)
插件的导入
maven项目如何运行
使用maven命令运行
把当地的web项目加载到Tomcat去运行
发布到tomcat
总结
maven核心就是一个下载工具的作用。
maven基础组件
仓库Repository
- 中央仓库/远程仓库
- 本地仓库(存放下载的依赖)![自己创建一个仓库用来存依赖文件](https://img-blog.csdnimg.cn/952e2672c82f43b5bf271098fab5d3fd.png
- 私有服务器
![国内镜像仓库的配置
](https://img-blog.csdnimg.cn/ed3cc0ff8c5f4de998faf0458ee984a0.png)
Maven核心组件:配置
Mybatis的使用
什么是MyBatis
- 无论是Mybatis、Hibernate都是ORM的一种实现框架,都是对JDBC的一种封装!
Mybatis的工作流程
创建maven项目
方法看上面的讲解。
添加需要的依赖
使用maven的仓库下载mybatis依赖,不需要单独下载jar包。
创建表
用户名和密码是自己用的数据库的。
我这里不知道为什么idea中不能执行sql脚本,所有我去SQLyog里面执行了脚本,将数据库建立。
如何在ideal中执行sql语句
环境变量配置
在resources下创建一个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="dev">
<!--配置环境,不同环境不同的id名字-->
<environment id="dev">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC"></transactionManager>
<!--数据库信息-->
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"></property><!--mysql数据库驱动-->
<property name="url" value="jdbc:mysql://localhost:3306/babytun?useUnicode=true&characterEncoding=UTF-8"></property>
<property name="user" value="root"/>
<property name="password" value="010619"/>
</dataSource>
</environment>
</environments>
</configuration>
修改:结束符没写
用户名没写(username)
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>
<!--设置默认指向数据库-->
<environments default="dev">
<!--配置环境,不同环境不同的id名字-->
<environment id="dev">
<transactionManager type="JDBC"></transactionManager>
<!--数据库信息-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/babytun?useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="010619"/>
</dataSource>
</environment>
</environments>
</configuration>
了解Sqlsession
导入单元测试junit依赖
测试代码:
package com.imooc.mybatis;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import org.apache.ibatis.io.Resources;
import java.io.IOException;
import java.io.Reader;
/*单元测试类*/
public class MyBatisTestor {
@Test
public void testSqlSessionFactory() throws IOException {
//利用Reader加载classpath下的mybatis-config.xml核心配置文件
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
//初始化SqlSessionFactory对象,同时解析mybatis-config.xml文件
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
System.out.println("SessionFactory加载成功");
}
}
测试结果:数据库连接顺利
SqlSession对象—是JDBC的扩展类,用于与数据库的交互
//创建SqlSession对象,SqlSession是JDBC的扩展类,用于与数据库交互
SqlSession sqlSession = null;
sqlSession = sqlSessionFactory.openSession();
//创建数据库连接(测试用)
Connection connection = sqlSession.getConnection();
System.out.println(connection);
如果运行结果正确,说明xml环境配置正确,我们再看一下xml的配置程序
初始化工具类MyBatisUtils
作用:创建全局唯一的SqlSessionFactory对象,所以我们单独创建一个工具类来封装他,方便以后的使用。
使用静态代码块的方法来初始化
package com.imooc.mybatis.utils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.io.Resources;
import java.io.IOException;
import java.io.Reader;
public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory = null;
static {
Reader reader = null;
try {
reader = Resources.getResourceAsReader("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
throw new ExceptionInInitializerError(e);
}
}
public static SqlSession openSession(){
return sqlSessionFactory.openSession();
}
public static void closeSession(SqlSession session){
if(session !=null){
session.close();
}
}
}
测试代码:
@Test
public void testMyBatisUtils() throws Exception {
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.openSession();//使用工具类的方式创建sqlsession
Connection connection = sqlSession.getConnection();
System.out.println(connection);
}catch (Exception e){
throw e;
}finally {
MyBatisUtils.closeSession(sqlSession);
}
}
MyBatis数据查询
查询步骤:
创建实体类Entity,在Java文件夹下,与utils工具类一级
在entity文件下创建一个Goods类,并生成实体类,与数据库表中的字段要匹配
上面两个字段之间要匹配,代码如下:
package com.imooc.mybatis.entity;
public class Goods {
/*生成实体类,与数据库表中的字段匹配*/
private Integer goodsId;//商品编号
private String title;//标题
private String subTitle;//子标题
private Float originalCost;//原始价格
private Float currentPrice;//当前价格
private Float discount;//折扣率
private Integer isFreeDelivery;//是否包邮 ,1-包邮 0-不包邮
private Integer categoryId;//分类编号
public void setGoodsId(Integer goodsId) {
this.goodsId = goodsId;
}
public void setTitle(String title) {
this.title = title;
}
public void setSubTitle(String subTitle) {
this.subTitle = subTitle;
}
public void setOriginalCost(Float originalCost) {
this.originalCost = originalCost;
}
public void setCurrentPrice(Float currentPrice) {
this.currentPrice = currentPrice;
}
public void setDiscount(Float discount) {
this.discount = discount;
}
public void setIsFreeDelivery(Integer isFreeDelivery) {
this.isFreeDelivery = isFreeDelivery;
}
public void setCategoryId(Integer categoryId) {
this.categoryId = categoryId;
}
public Integer getGoodsId() {
return goodsId;
}
public String getTitle() {
return title;
}
public String getSubTitle() {
return subTitle;
}
public Float getOriginalCost() {
return originalCost;
}
public Float getCurrentPrice() {
return currentPrice;
}
public Float getDiscount() {
return discount;
}
public Integer getIsFreeDelivery() {
return isFreeDelivery;
}
public Integer getCategoryId() {
return categoryId;
}
}
创建mappers文件夹,在xml文件里面编写映射关系
查询的sql语句
<!--书写则删改查语句-->
<select id="selectAll" resultType="com.imooc.mybatis.entity.Goods">
SELECT *FROM t_goods ORDER BY goods_id DESC limit 10
</select>
这里的namespace的意思是要查询goods数据表,id = selectAll,表示查询goods数据表的selectAll,因为每个表都有selectAll,所以要使用namespace来区别
编写sql语句
开启驼峰命名映射
如果不这样写的话,下面这种带有特殊符号的字段就不能被mybatis识别
编写测试代码
其他代码不变,只有红框里面的代码是调用sql语句执行数据库的代码
命名空间+运行id,通过创建的sqlsession对象来执行selectList方法,将读取到的数据存放到list集合中去。通过for循环输出表中的title。
List<Goods> list = session.selectList("goods.selectAll");//命名空间+运行的id
for(Goods g : list){
System.out.println(g.getTitle());
}
SQL传参
id:代表了sql的id。
parameterType:指定参数类型的。
例如:传入一个整型对象Interger.
传入一个集合对象Java.util.Map.
传入一个Goods对象com.imooc.mybatis.entity.Goods
resultType:返回对象类型
<?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="goods">
<!--书写则删改查语句-->
<select id="selectAll" resultType="com.imooc.mybatis.entity.Goods">
SELECT *FROM t_goods ORDER BY goods_id DESC limit 10
</select>
<select id="selectById" parameterType="Integer" resultType="com.imooc.mybatis.entity.Goods">
select * from t_goods where goods_id = #{value}
</select>
<!-- 多参数传递时,使用parameterType指定Map接口,SQL中#{key}提取参数 -->
<select id="selectByPriceRange" parameterType="java.util.Map" resultType="com.imooc.mybatis.entity.Goods">
select * from t_goods
where
current_price between #{min} and #{max}
order by current_price
limit 0,#{limt}
</select>
</mapper>
测试代码:
@Test
public void testSelectById() throws Exception {
SqlSession session = null;
try {
session = MyBatisUtils.openSession();
/*执行查询语句*/
Goods goods = session.selectOne("goods.selectById", 1030);
System.out.println(goods.getTitle());
}catch (Exception e){
throw e;
}finally {
MyBatisUtils.closeSession(session);
}
}
@Test
public void testSelectByPriceRange() throws Exception {
SqlSession session = null;
try {
session = MyBatisUtils.openSession();
Map param = new HashMap();
param.put("min",100);
param.put("max",500);
param.put("limt",10);
List<Goods> list = session.selectList("goods.selectByPriceRange", param);
for (Goods g:list){
System.out.println(g.getTitle()+"+"+ g.getCurrentPrice());
}
}catch (Exception e){
throw e;
}finally {
MyBatisUtils.closeSession(session);
}
}
多表联合查询
resultMap多表查询
MyBatis数据写入
数据库事务
数据库的事务是保证数据操作的完整性的基础
从客户端发来的增加,删除,修改操作会先保存在事务日志中。事务日志就是存放所有写操作的sql语句。
当客户端向MySql发起commit命令时,才会将数据1,数据2,数据3,真正的写入对应的数据表中。
如果数据3没有执行成功,客户端就会返回一个rollback回滚命令,当mysql收到这个命令后,该数据库的全部数据都会被清除。不会存入到数据表中,保证了数据的完整。
Mybatis写操作主要有三种:
数据的插入
- parameterType:插入参数的类型是Goods实体对象
- flushCache:flushCache="true"在sql执行后强制清空缓存。
接下来就是写插入的sql语句(括号里面写的是字段名称) - value:(#{属性名称})
- select last_insert_id()是mysql自带的获取当前连接最后产生的ID号。因此该函数不纯在并发性的问题。也不会出现主键的混乱。
- 这里的resultType="Integer"就是接收select last_insert_id()返回的ID号。
<insert id="insert" parameterType="com.imooc.mybatis.entity.Goods" flushCache="true">
INSERT INTO t_goods(title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id)
VALUES (#{title} , #{subTitle} , #{originalCost}, #{currentPrice}, #{discount}, #{isFreeDelivery}, #{categoryId})
<!--<selectKey resultType="Integer" keyProperty="goodsId" order="AFTER">-->
<!--select last_insert_id()-->
<!--</selectKey>-->
</insert>
测试代码
@Test
public void testInsert() throws Exception {
SqlSession session = null;
try{
session = MyBatisUtils.openSession();
Goods goods = new Goods();
goods.setTitle("测试商品");
goods.setSubTitle("测试子标题");
goods.setOriginalCost(200f);
goods.setCurrentPrice(100f);
goods.setDiscount(0.5f);
goods.setIsFreeDelivery(1);
goods.setCategoryId(43);
//insert()方法返回值代表本次成功插入的记录总数
int num = session.insert("goods.insert", goods);
session.commit();//提交事务数据
System.out.println(goods.getGoodsId());
}catch (Exception e){
if(session != null){
session.rollback();//回滚事务
}
throw e;
}finally {
MyBatisUtils.closeSession(session);
}
}
selectKey与useGenerateKeys的区别
selectKey
select last_insert_id()是mysql自带的获取当前连接最后产生的ID号。因此该函数不纯在并发性的问题。也不会出现主键的混乱。
注意事项:
1、什么是selectKey:数据库主键包括自增和非自增,有时候新增一条数据不仅仅知道成功就行,后边的逻辑可能还需要这个新增的主键,这时候再查询数据库就有点儿耗时耗力,我们可以采用selectKey来帮助我们获取新增的主键
useGenerateKeys
- 不需要写select标签,在insert里面添加三条语句即可。同样可以返回主键
- keyProperty:: 这里写goodsId是属性名
- keyCo1umn:这里写的是字段名goods_id。
二者的区别
更新与删除操作
更新商品的标题goods。setTitle();
删除操作
SQL注入攻击
精准查询数据库中的东西
${}:表示不做任何修改