提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、库和框架的区别?
库: 对原有技术的封装,让操作更加简单
框架: 是一整套技术的解决方案
二.mybatis的介绍
mybatis是一个持久层(DAO)的框架。把实体类和sql语句之间建立了半自动的映射关系(半自动的ORM)
Mybatis的优点:
- 减少代码量
- 基于sql语句,简单易学,自己可以改变sql语句,灵活度高,便于调优
- 能了解底层组装过程,是开源的
- sql语句封装在配置文件中,便于统一管理
三.mybatis快速入门
- 1.建立数据库和数据表
- 2.创建项目,并导包
- 3.创建实体类
- 4.配置mybatis的核心配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!--引入dtd格式的约束文件-->
<!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">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!-- 数据源的配置-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 引入映射文件-->
<mapper resource="com/shangma/cn/mapper/AMapper.xml"/>
</mappers>
</configuration>
- 配置sql语句的配置文件
<?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 命名空间 一个命名空间中可以编写n条的sql语句
相当于java中的包,用于区分相同名称的类 这里区分相同的sql
-->
- xmlsql语句标签:
查询 select <select>
插入 insert <insert>
修改 update <update>
删除 delete <delete>
查询
<!--
添加用户
keyProperty:表示主键的属性
order: 表示返回的主键是在添加前(BEFORE)还是在添加后(AFTER)
last_insert_id() 是mysql中的函数 返回的是最后一次添加的id
-->
<select id="findAll" resultType="com.shangma.cn.entity.User">
select * from user
</select>
根据id查询
<select id="findUserById" parameterType="int" resultType="com.shangma.cn.entity.User">
select * from user where id = #{id}
</select>
添加
<insert id="addUser" parameterType="com.shangma.cn.entity.User">
//设置selectKey会返回增加的ID
<!--
添加用户
keyProperty:表示主键的属性
order: 表示返回的主键是在添加前(BEFORE)还是在添加后(AFTER)
last_insert_id() 是mysql中的函数 返回的是最后一次添加的id
-->
<selectKey keyProperty="id" order="AFTER" resultType="int">
select last_insert_id()
</selectKey>
insert into user (username,sex,birthday,address) values(#{username},#{sex},#{birthday},#{address})
</insert>
修改用户
<update id="updateUser" parameterType="com.shangma.cn.entity.User">
update user set username = #{username},sex = #{sex},birthday = #{birthday},address=#{address} where id = #{id}
</update>
根据id删除用户
<!-- 根据id删除用户-->
<delete id="deleteUserById" parameterType="int">
delete from user where id = #{id}
</delete>
模糊查询
<!--
模糊查询
mybatis3.4之前,下面必须写value
-->
<select id="searchUser" parameterType="string" resultType="com.shangma.cn.entity.User">
select * from user where username like '%${value}%'
</select>
</mapper>
该处使用的url网络请求的数据。
- test测试类 编写代码(核心对象SqlSession)
private InputStream inputStream;
private SqlSession sqlSession;
@Before // 表示在每一次测试方法执行之前都会执行
public void init() throws IOException {
// mybatis核心配置文件的名称
String resource = "mybatis.xml";
// 从路径下面加载核心配置文件
inputStream = Resources.getResourceAsStream(resource);
// 获取sqlSession工厂类
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获取sqlSession
sqlSession = sqlSessionFactory.openSession();
}
@After //表示在每一次测试方法执行之后都会执行
public void release(){
// 关闭资源
sqlSession.close();
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
关于增删改查的测试
@Test
public void findAll() throws IOException {
// 使用sqlsession进行增删改查
List<User> users = sqlSession.selectList("gufengshuo.findAll");
users.forEach(user-> System.out.println(user));
}
@Test
public void findUserById() throws IOException {
// 使用sqlsession进行增删改查
User user = sqlSession.selectOne("gufengshuo.findUserById", 24);
System.out.println(user);
}
@Test
public void addUser() throws IOException {
// 使用sqlsession进行增删改查
User user = new User();
user.setUsername("张无忌");
user.setSex("男");
user.setAddress("冰火岛");
user.setBirthday(new Date());
sqlSession.insert("gufengshuo.addUser",user);
// 增删改时,需要手动提交事务,否则不能持久化到数据库中
sqlSession.commit();
System.out.println(user);
}
@Test
public void updateUser() throws IOException {
// 使用sqlsession进行增删改查
User user = new User();
user.setId(22);
user.setUsername("谢逊");
user.setSex("男");
user.setAddress("冰火岛");
user.setBirthday(new Date());
// 修改数据
sqlSession.update("gufengshuo.updateUser",user);
// 增删改时,需要手动提交事务,否则不能持久化到数据库中
sqlSession.commit();
}
@Test
public void deleteUser() throws IOException {
// 使用sqlsession进行增删改查
// 删除数据
sqlSession.delete("gufengshuo.deleteUserById",36);
// 增删改时,需要手动提交事务,否则不能持久化到数据库中
sqlSession.commit();
}
@Test
public void searchUser() throws IOException {
// 使用sqlsession进行增删改查
List<User> users = sqlSession.selectList("gufengshuo.searchUser", "张");
System.out.println(users);
}
五 mybatismapper开发
使用这种方式,可以不用写dao的实现类.程序员只需要编写mapper接口就可以。
注意:这种使用方式需要符合规范
5.1 Mapper代理书写规范
- Mapper接口的完整路径,要和Mapper配置文件(xml)中的namespace一致
- Mapper接口中的方法名,必须和mapper配置文件中的sql语句的id值相同
- Mapper接口中的方法的参数只能有一个,并且类型要和mapper配置文件中的sql语句的parameterType类型一致
- mapper接口中的返回值要和mapper配置文件中sql语句的resultType(或者resultMap)的类型一致
-
六 #{}和${}的区别
- #{}在引用时,如果发现目标是一个字符串,则会将其值作为一个字符串拼接在sql上
- ${}在引用时,即使发现目标是一个字符串,也不会作为字符串而是直接使用将其拼接在sql上
大部分场景都使用#{}
insert into user values(null,#{username},55);
insert into user values(null,'关谷神奇',55);
insert into user values(null,${username},55);
insert into user values(null,关谷神奇,55);
如果需要引用的是一个列名,使用${}
select * from user order by #{cage};
select * from user order by 'age';
select * from user order by ${cage};
select * from user order by age;
# 七.全局配置文件讲解 ## 7.1 文件名称 mybatis的核心配置文件的名称,其实可以随便写。但是在公司中一般都会有两种命名 - sqlMapperConfig.xml - mybatis-config.xml ## 7.2 数据库环境配置
<!-- default 要使用哪一个数据库环境-->
<environments default="development">
<!-- 开发环境下的数据库-->
//此外还有test(测试环境)www(上线环境)
<environment id="development">
<!-- JDBC的事务管理 交给mybatis统一管理 -->
<transactionManager type="JDBC"/>
<!--
dataSource 数据源(连接池)
type: POOLED 要使用POOLED的数据源 不是druid 也不是C3p0 对应的类是PooledDataSource
UNPOOLED 对应的是UnPooledDataSource
-->
<dataSource type="POOLED">
<!-- 数据源的配置-->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
7.3 导入外部配置文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql:///mybatis?characterEncoding=utf-8
username=root
password=123456
在核心配置文件中加载
<!-- 加载配置文件-->
<properties resource="db.properties"></properties>
使用
<dataSource type="POOLED">
<!-- 数据源的配置-->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
7.4别名标签
1.参数类型和返回值类型如果是引用数据类型,默认需要使用的是全路径名
2.设置别名 别名不区分大小写 但是一般都使用全小写
<typeAliases>
<!-- <typeAlias type="com.shangma.cn.entity.User" alias="user"/>-->
** 整个entity包下的类全部别名是类名的小写(不区分大小写)**
<package name="com.shangma.cn.entity"/>
</typeAliases>
7.5 映射文件
<mappers>
实际开发中的用法
直接写包名,表示自动去对应的包下找到mapper接口和包下对应的同名的xml
注意点:**如果要使用package,接口名称要和mapper文件名一致 并且在同一个目录下**
<package name="com.shangma.cn.mapper"/>
</mappers>
八.parameterType
可以取四种值:
- 基本数据类型
- 本质上就是官方系统的常用的引用数据类型的别名 如:java.lang.Integer -->int
- 自定义类型
- 如果起了别名,可以使用别名.
- 如果没有起别名,那么必须是全路径名
- 嵌套类型(对象套对象)
- #{对象的属性名.属性名…}
- map使用
- #{key}
parameterType可以省略
- #{key}
九.resultType
注意点:
返回单个实体类和实体类集合时,mapper映射文件中的resultType的类型是一样的.
这种单独resultType的方式的前提条件是属性名和表中的列名一致,所以数据会封装到实体中
如果数据库表和实体类中遵守驼峰命名规范,可以在核心xml文件中使用mybaits开启驼峰命名
<settings>
<!-- 开启驼峰命名-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
十.resultMap
如果表中的字段和实体类中的属性名不一致(表中字段,这里不可改实体类属性名),并且不符合驼峰命名规范,我们可以使用resultMap手动结果映射
resultMap手动结果映射
id:对应的resultMap的唯一标识
type:表示给哪一个类型进行手动结果映射
property:实体类中需要映射的属性名
column:数据库表中的列名
注意点:如果对应的属性和列名是主键,那么可以使用result标签,也可以使用id标签
官方推荐使用id标签,这样效率更高
<resultMap id="resultId" type="user">
<id property="userId" column="uid"></id>
<result property="userAddress" column="abc"></result>
</resultMap>
<select id="findUserById" resultMap="resultId">
<include refid="selectAll"></include> where uid = #{id}
</select>
十一 动态标签
<where>:动态的判断是否使用 and
<if>:可以有判断的条件
<set>:动态的判断是否用 ,
<trim>:可以添加前缀和后缀,可以动态判断是否覆盖某个符号
<foreach>:遍历集合
11.1 (查)select的使用(where )
<select id="findUsers" resultType="user">
select * from user
<where>
<if test="username != null and username != ''">
username = #{username}
</if>
<if test="sex != null and sex != ''">
and sex = #{sex}
</if>
<if test="address != null and address != ''">
and address = #{address}
</if>
<if test="birthday != null">
and birthday = #{birthday}
</if>
</where>
</select>
11.2(改)update的使用(必然使用 set )
<update id="updateUser" parameterType="user">
update user
<set>
<if test="username != null and username != ''">
username = #{username},
</if>
<if test="sex != null and sex != ''">
sex = #{sex},
</if>
<if test="birthday != null">
birthday = #{birthday},
</if>
<if test="address != null and address != ''">
address = #{address},
</if>
</set>
where id = #{id}
</update>
11.3(增) insert的使用(必然使用 trim )
<insert id="addUser">
insert into user
prefix:前缀 suffix:后缀 suffixOverrides:覆盖
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="username != null and username != ''">
username,
</if>
<if test="sex != null and sex != ''">
sex,
</if>
<if test="birthday != null">
birthday,
</if>
<if test="address != null and address != ''">
address
</if>
</trim>
values
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="username != null and username != ''">
#{username},
</if>
<if test="sex != null and sex != ''">
#{sex},
</if>
<if test="birthday != null">
#{birthday},
</if>
<if test="address != null and address != ''">
#{address},
</if>
</trim>
</insert>
11.4(删) delete的使用(必然使用where)
<delete id="deleteUser">
delete from user
<where>
<if test="username != null and username != ''">
username = #{username}
</if>
<if test="sex != null and sex != ''">
and sex = #{sex}
</if>
<if test="birthday != null">
and birthday = #{birthday}
</if>
<if test="address != null and address != ''">
and address = #{address}
</if>
</where>
</delete>
11.5 批量删除
批量删除多个id的用户信息
delete from user where id in(3,8,9)
foreach:对集合进行遍历
collection:需要遍历的类型
open:左边的符号
close:右边的符号
separator:遍历之后的元素的分隔符
item:每一条数据的条目
<delete id="deleteUsers">
delete from user where id in
<foreach collection="list" open="(" close=")" separator="," item="id">
#{id}
</foreach>
</delete>
十二 使用mybatis进行多表查询
一个用户有一个购物车 一对一
一个购物车对应多个购物车项 一对多
一个购物车项对应一个商品 一对一
一个用户可以选择多个商品,一个商品可以被多个用户选择 多对多
12.1 一对一查询
需求:查询用户以及他的购物车的信息
12.1.1生成cart实体类
public class Cart {
private String cartId;
private long userId;
private long totalnum;
private double totalmoney;
public String getCartId() {
return cartId;
}
public void setCartId(String cartId) {
this.cartId = cartId;
}
public long getUserId() {
return userId;
}
public void setUserId(long userId) {
this.userId = userId;
}
public long getTotalnum() {
return totalnum;
}
public void setTotalnum(long totalnum) {
this.totalnum = totalnum;
}
public double getTotalmoney() {
return totalmoney;
}
public void setTotalmoney(double totalmoney) {
this.totalmoney = totalmoney;
}
@Override
public String toString() {
return "Cart{" +
"cartId='" + cartId + '\'' +
", userId=" + userId +
", totalnum=" + totalnum +
", totalmoney=" + totalmoney +
'}';
}
}
12.1.2 在User类中添加cart属性,提供set和get和toString方法
12.1.3 在UserMapper接口中添加抽象方法
/**
* 查询用户和购物车信息
*/
List<User> selectUserAndCart();
12.1.4 在UserMapper.xml中添加代码
<!--
多表查询之一对一
sql语句 select * from user u,cart c where u.id = c.userId
在user中需要描述一个cart
association:描述的是一对一的关系
javaType:要对哪一个类型进行描述
-->
<resultMap id="userandcart" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<result property="address" column="address"></result>
手动映射 cart
<association property="cart" javaType="cart">
<id property="cartId" column="cartId"></id>
<result property="userId" column="userId"></result>
<result property="totalnum" column="totalnum"></result>
<result property="totalmoney" column="totalmoney"></result>
</association>
</resultMap>
<select id="selectUserAndCart" resultMap="userandcart">
select * from user u,cart c where u.id = c.userId
</select>
测试
@Test
public void test08(){
List<User> users = userMapper.selectUserAndCart();
users.forEach(user -> System.out.println(user));
}
12.2 一对多查询
需求:查询购物车和对应的购物车条目项
12.2.1 创建CartMapper接口
public interface CartMapper {
/**
* 查询购物车和购物车项
*/
List<Cart> selectCartAndCartItem();
}
12.2.2 创建CartMapper.xml
<mapper namespace="com.shangma.cn.mapper.CartMapper">
<!--
select * from cart c,cartitem ci where c.cartId = ci.cartId
collection:描述的是一对多关系时,多的一方
property: 属性名
ofType:表示集合中的泛型类型
-->
<resultMap id="cartandcartitem" type="cart">
<id property="cartId" column="cartId"></id>
<result property="userId" column="userId"></result>
<result property="totalnum" column="totalnum"></result>
<result property="totalmoney" column="totalmoney"></result>
<collection property="cartitems" ofType="cartitem">
<id property="cartItemId" column="cartItemId"></id>
<result property="cartId" column="cartId"></result>
<result property="pid" column="pid"></result>
<result property="pnum" column="pnum"></result>
<result property="pmoney" column="pmoney"></result>
</collection>
</resultMap>
<select id="selectCartAndCartItem" resultMap="cartandcartitem">
select * from cart c,cartitem ci where c.cartId = ci.cartId
</select>
</mapper>
12.3 多对多(四表联查)
需求:查询用户和用户购买的商品
12.3.1 在UserMapper接口中添加抽象方法
/**
* 查询用户及用户的商品
*/
List<User> selectUserAndGoods();
12.3.2 在UserMapper.xml中添加sql语句
<resultMap id="userandgood" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<result property="address" column="address"></result>
<association property="cart" javaType="cart">
<id property="cartId" column="cartId"></id>
<result property="userId" column="userId"></result>
<result property="totalnum" column="totalnum"></result>
<result property="totalmoney" column="totalmoney"></result>
<collection property="cartitems" ofType="cartitem">
<id property="cartItemId" column="cartItemId"></id>
<result property="cartId" column="cartId"></result>
<result property="pid" column="pid"></result>
<result property="pnum" column="pnum"></result>
<result property="pmoney" column="pmoney"></result>
<association property="good" javaType="good">
<id property="pid" column="pid"></id>
<result property="pname" column="pname"></result>
<result property="price" column="price"></result>
<result property="pimg" column="pimg"></result>
<result property="pdesc" column="pdesc"></result>
</association>
</collection>
</association>
</resultMap>
<select id="selectUserAndGoods" resultMap="userandgood">
select * from user u,cart c,cartitem ci,good g where u.id = c.userId
and c.cartId = ci.cartId and ci.pid =g.pid
</select>
14 mybatis的延迟加载
延迟加载又叫做懒加载(lazy load)表示关联查询时,当使用关联的数据时,才真正去数据库查询,可以减轻数据库的压力,提高查询的性能和效率
需求:查询用户和购物车信息
14.1默认延迟加载是关闭的需要在核心xml中打开权限
<!-- 延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
14.2在UserMapper中添加抽象方法
使用懒加载的方式查询用户和购物车信息
List<User> selectUserAndCartByLazyLoad();
14.3在UserMapper.xml中添加配置
select:需要执行的方法 一定要写全路径名
column:id 表示将select * from user的结果的id列的值传给select标签指定方法的参数
<resultMap id="lazyMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<result property="address" column="address"></result>
<association property="cart" javaType="cart" select="com.shangma.cn.mapper.CartMapper.selectCartById" column="id"></association>
</resultMap>
<select id="selectUserAndCartByLazyLoad" resultMap="lazyMap">
select * from user
</select>
14.4在CartMapper中添加抽象方法
/**
* 通过id查询购物车
*/
Cart selectCartById(int userId);
14.5在CartMapper.xml中添加配置
<select id="selectCartById" resultType="cart">
select * from cart where userId = #{id}
</select>
14.6测试
结果
测试时发现,如果只是获取用户的基本信息,不会执行select * from cart where userId = #{id}语句,如果明确的指定要获取购物车信息,那么会执行select * from cart where userId = #{id}语句