Mybits是优秀的持久层框架
持久层框架:
所谓"持久"就是将数据保存到可掉电式存储设备中以便今后使用,简单的说,就是将内存中的数据保存到关系型数据库、文件系统、消息队列等提供持久化支持的设备中。持久层就是系统中专注于实现数据持久化的相对独立的层面。
<!--数据库连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="url" value="jdbc:mysql://localhost:3306/student?useSSL=false&useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT"> </property>
<property name="username" value="root"> </property>
<property name="password" value="root"> </property>
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"> </property>
MyBatis的核心配置文件,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>
<!--环境配置,连接的数据库,这里使用的是MySQL-->
<environments default="mysql">
<environment id="mysql">
<!--指定事务管理的类型,这里简单使用Java的JDBC的提交和回滚设置-->
<transactionManager type="JDBC"></transactionManager>
<!--dataSource 指连接源配置,POOLED是JDBC连接对象的数据源连接池的实现-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybbs"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</dataSource>
</environment>
</environments>
<mappers> <!--这是告诉Mybatis区哪找持久化类的映射文件,对于在src下的文件直接写文件名, 如果在某包下,则要写明路径,如:com/mybatistest/config/User.xml-->
<mapper resource="User.xml"></mapper>
</mappers>
</configuration>
<?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="druid.properties"></properties>
<settings>
<setting name="logImpl" value="LOG4J" ></setting>
</settings>
<!--环境配置,连接的数据库,这里使用的是MySQL-->
<typeAliases >
<!--给一个类起别名-->
<typeAlias type="com.atguigu.entity.User" alias="User"></typeAlias>
</typeAliases>
<environments default="mysql">
<environment id="mysql">
<!--指定事务管理的类型,这里简单使用Java的JDBC的提交和回滚设置-->
<transactionManager type="JDBC"></transactionManager>
<!--dataSource 指连接源配置,POOLED是JDBC连接对象的数据源连接池的实现-->
<dataSource type="POOLED">
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT"></property>
<property name="driver" value="com.mysql.cj.jdbc.Driver"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</dataSource>
</environment>
</environments>
<mappers> <!--这是告诉Mybatis区哪找持久化类的映射文件,对于在src下的文件直接写文件名,如果在某包下,
则要写明路径,如:com/mybatistest/config/User.xml-->
<!--所有的接口实现类都必须经过注册才能使用,你需要把接口实现类和接口绑定到一起-->
<mapper resource="com/atguigu/dao/UseMapper.xml"></mapper>
</mappers>
</configuration>
配置完了去生产一个工厂类,来生产工厂
直接建立一个untils去使用sql类
package com.atguigu.utils;
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 sun.misc.Resource;
import java.io.IOException;
import java.io.InputStream;
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "Mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//将工厂的模板传递进来
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//根据模板去建立流水线
} catch (IOException e) {
e.printStackTrace();
}
}
//sqlsession就是用来执行sql的对象
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();//获取到sqlSession对象就可以直接用了
}
}
1.编写实体类
package com.atguigu.entity;
public class User {
private int id;
private String name;
private String pwd;
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
2.dao层建立接口和实现类
接口实现类的通用配置
接口实现类跟接口放在一个包里面,
自己去看maven的配置吧
<?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用来绑定唯一的接口或者,用来和接口进行绑定-->
<mapper namespace="com.atguigu.dao.UserDao">
<!--就相当于原来的实现了这个接口-->
<select id="getIdUserList" resultType="User" parameterType="int">
select * from user where id = #{id};
</select>
</mapper>
dao层,建立接口,不用实现接口,而是用一个Mapper去映射,这个映射mapper千万记得去配置文件MyBatisConfig中去配置一下,声明自己建立了一个实现类
使用xml文件开发时候,可以这样,将下面,所有的mapper都扫描了
不过要注意,接口和接口实现类名字要相同。
一个叫UserMapper另一个需要叫UserMapper.xml
然后在dao下面直接写一个xml配置文件,作为实现类
这个实现类直接实现方法,要有方法名字和返回值类型
返回的时候记住这两个就行了,一个返回结果集合,另一个返回一个结果,这唯一一个返回结果你记住类型就行了
写清除映射的路径
这里映射路径一定要在MyBatisConfig中去设置相当于声明了我要设置一个实现类了
,相当于告诉
使用方式2,直接定位到dao层中
try{
}catch (){
}
finally {
SqlSession sqlSession = MybatisUtils.getSqlSession();
sqlSession.close();
}
尽量使用trycatch加上finally,finally中去close
这样在Mapper中就要实现这个接口id是接口中要改写的方法
resulType是返回值类型
parameterType是参数
取得参数方式就是#{参数名字}
这就是查的过程。
增的过程
增删改需要提交事务
sqlsession.commit
1.先在接口中写方法
传进去一个User类
2.在Mapper中实现方法
类中的属性可以直接拿出来
记得用Insert的方法
类中属性可以直接拿出来。
3.增删改查没有返回值类型
更新一个东西流程
1.在接口中写下更新方法
2.在mapper中写更新方法
使用万能的Map进行增删改查
Map有一个Key,有一个V,我们可以给V设置一个想要的K,这样传递参数时候很灵活
1.在接口阶段就想清楚了,我要传递的是一个map
2.在接口实现类阶段,就想清楚了我要传递的是什么
3.将想要传递的数据放进map里面,根据KV命名好,然后传递给数据。
配置解析:
核心配置文件:
Mybatis-config.xml
红色的是需要知道配置文件
核心配置文件中,可以有多个环境,但是可以投入使用的环境只有一个
如图所示我配置了两套环境,如何在两套环境中进行切换?
配置好图中黑色默认位置,就可以在两套环境中进行切换。
Mybatis不要管理事务,事务交给spring去管理就可以了。
Mybatis默认事务管理是JDBC,Mybatis默认连接是池连接。
可以设置一个properties文件,作为配置文件存放数据
xml中,文件拜访位置要遵守这个原则。
在properties中配置好属性然后导入到xml中
给自己的类起一个别名:
这样类用起来比较方便和容易
在Mybatis-config中优化配置方式
给类起一个别名
<typeAliases >
<!--给一个类起别名-->
<typeAlias type="com.atguigu.entity.User" alias="User"></typeAlias>
</typeAliases>
Mybiatis生命周期问题
sqlsession相当于一个请求,所以这个请求要经常被关闭,不然会浪费资源。
一个sqlSession代表着连接一个数据库的请求。mapper是一个业务,每一个mapper都是一个业务。
解决属性名和字段名不一致问题
这样在返回时候就会出现password中没办法将pwd按照名字包装进去
解决方案:
1.起别名
sql中可以起别名AS Select pwd AS password
2.ResultMap结果集映射
结果集映射,将sql中的column列,直接映射称为类重的属性
使用结果集合映射时候注意这里,是resultMap不是resultType
相当于我创造了一个容器resultMap,这个容器将sql中列映射为类中对应
然后我在返回值类型中,去设置这个ResultMap,只要映射属性不同的就行。
使用结果集合
日志工厂,当一个`数据库出现异常,我们需要排错,使用日志工厂排错。
在Mybatis-config中去配置日志工厂
<settings>
<setting name="logImpl" value="STDOUT_LOGGING" ></setting>
</settings>
不过似乎我们经常使用的是log4j这个,这个玩意需要导包
导包之后建立一个Log4j的配置文件,log4j.properties
# priority :debug<info<warn<error
#you cannot specify every priority with different file for log4j
log4j.rootLogger=debug,stdout,info,debug,warn,error
#console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern= [%d{yyyy-MM-dd HH:mm:ss a}]:%p %l%m%n
#info log
log4j.logger.info=info
log4j.appender.info=org.apache.log4j.DailyRollingFileAppender
log4j.appender.info.DatePattern='_'yyyy-MM-dd'.log'
log4j.appender.info.File=./src/com/hp/log/info.log
log4j.appender.info.Append=true
log4j.appender.info.Threshold=INFO
log4j.appender.info.layout=org.apache.log4j.PatternLayout
log4j.appender.info.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss a} [Thread: %t][ Class:%c >> Method: %l ]%n%p:%m%n
#debug log
log4j.logger.debug=debug
log4j.appender.debug=org.apache.log4j.DailyRollingFileAppender
log4j.appender.debug.DatePattern='_'yyyy-MM-dd'.log'
log4j.appender.debug.File=./src/com/hp/log/debug.log
log4j.appender.debug.Append=true
log4j.appender.debug.Threshold=DEBUG
log4j.appender.debug.layout=org.apache.log4j.PatternLayout
log4j.appender.debug.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss a} [Thread: %t][ Class:%c >> Method: %l ]%n%p:%m%n
#warn log
log4j.logger.warn=warn
log4j.appender.warn=org.apache.log4j.DailyRollingFileAppender
log4j.appender.warn.DatePattern='_'yyyy-MM-dd'.log'
log4j.appender.warn.File=./src/com/hp/log/warn.log
log4j.appender.warn.Append=true
log4j.appender.warn.Threshold=WARN
log4j.appender.warn.layout=org.apache.log4j.PatternLayout
log4j.appender.warn.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss a} [Thread: %t][ Class:%c >> Method: %l ]%n%p:%m%n
#error
log4j.logger.error=error
log4j.appender.error = org.apache.log4j.DailyRollingFileAppender
log4j.appender.error.DatePattern='_'yyyy-MM-dd'.log'
log4j.appender.error.File = ./src/com/hp/log/error.log
log4j.appender.error.Append = true
log4j.appender.error.Threshold = ERROR
log4j.appender.error.layout = org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss a} [Thread: %t][ Class:%c >> Method: %l ]%n%p:%m%n
然后在Mybatis中去配置好我们需要使用Log4j
<settings>
<setting name="logImpl" value="LOG4J" ></setting>
</settings>
三个日志级别
这三个东西可以写在代码中间,然后会跟着日志走。
使用Mybatis实现分页。
1.写一个接口
2.xml接口实现类
3.测试
使用注解开发
1.只需要写一个接口就可以了
不需要接口实现类
这样开发省事情
另外就是需要Mybatis-config的配置文件
<?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="druid.properties"></properties>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING" ></setting>
</settings>
<!--环境配置,连接的数据库,这里使用的是MySQL-->
<typeAliases >
<!--给一个类起别名-->
<typeAlias type="com.atguigu.entity.User" alias="User"></typeAlias>
</typeAliases>
<environments default="mysql">
<environment id="mysql">
<!--指定事务管理的类型,这里简单使用Java的JDBC的提交和回滚设置-->
<transactionManager type="JDBC"></transactionManager>
<!--dataSource 指连接源配置,POOLED是JDBC连接对象的数据源连接池的实现-->
<dataSource type="POOLED">
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT"></property>
<property name="driver" value="com.mysql.cj.jdbc.Driver"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</dataSource>
</environment>
</environments>
<!--绑定接口表示这个接口是我用注解开发的-->
<mappers>
<mapper class="kuang.dao.UserMapper"></mapper>
</mappers>
</configuration>
Mybatis-config的配置中注意
mapper的位置通过类去找到接口,
这里是class是通过类去找到接口,而不是resource去找到那个接口。
注解开发,在接口上,数据很多时候建议
加上这个注解,当然你创造一个类去作为容器也是完全ok的。
给你的参数加个名字。
增上改查
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.mzpai.product.mapper.MemberMapper" >
<resultMap id="BaseResultMap" type="com.mzpai.product.model.User" >
<result column="uid" property="uid" jdbcType="INTEGER" />
<result column="unionid" property="unionid" jdbcType="VARCHAR" />
<result column="openid" property="openid" jdbcType="VARCHAR" />
<result column="routine_openid" property="routineOpenid" jdbcType="VARCHAR" />
<result column="nickname" property="nickname" jdbcType="VARCHAR" />
<result column="headimgurl" property="headimgurl" jdbcType="VARCHAR" />
<result column="sex" property="sex" jdbcType="VARCHAR" />
<result column="city" property="city" jdbcType="varchar" />
<result column="language" property="language" jdbcType="VARCHAR" />
<result column="province" property="province" jdbcType="VARCHAR" />
<result column="country" property="contry" jdbcType="VARCHAR" />
<result column="remark" property="remark" jdbcType="VARCHAR" />
<result column="groupid" property="groupid" jdbcType="INTEGER" />
<result column="tagid_list" property="tagidList" jdbcType="VARCHAR" />
<result column="subscribe" property="subscribe" jdbcType="INTEGER" />
<result column="subscribe_time" property="subscribeTime" jdbcType="InTEGER" />
<result column="add_time" property="addTime" jdbcType="INTEGER" />
<result column="stair" property="stair" jdbcType="INTEGER" />
<result column="second" property="second" jdbcType="INTEGER" />
<result column="order_stair" property="orderStair" jdbcType="INTEGER" />
<result column="order_second" property="orderSecond" jdbcType="INTEGER" />
<result column="now_money" property="nowMoney" jdbcType="DECIMAL" />
<result column="session_key" property="sessionKey" jdbcType="VARCHAR" />
<result column="user_type" property="userType" jdbcType="VARCHAR" />
<result column="mobile" property="mobile" jdbcType="VARCHAR" />
</resultMap>
<sql id="baseColumnList">
uid, account, pwd,
real_name, birthday, card_id,
mark, partner_id, group_id,
nickname, avatar, phone,
add_time, add_ip, last_time,
last_ip, now_money, brokerage_price,
integral, sign_num, status,
level, spread_uid, spread_time,
user_type, is_promoter, pay_count,
spread_count, clean_time, addres,
adminid, login_type, user_text,
secret_key
</sql>
<insert id="insert" parameterType="com.mzpai.product.model.Member" >
insert into eb_user (uid, account, pwd,
real_name, birthday, card_id,
mark, partner_id, group_id,
nickname, avatar, phone,
add_time, add_ip, last_time,
last_ip, now_money, brokerage_price,
integral, sign_num, status,
level, spread_uid, spread_time,
user_type, is_promoter, pay_count,
spread_count, clean_time, addres,
adminid, login_type, user_text,secret_key)
values (#{uid,jdbcType=INTEGER}, #{account,jdbcType=VARCHAR}, #{pwd,jdbcType=VARCHAR},
#{realName,jdbcType=VARCHAR}, #{birthday,jdbcType=INTEGER}, #{cardId,jdbcType=VARCHAR},
#{mark,jdbcType=VARCHAR}, #{partnerId,jdbcType=INTEGER}, #{groupId,jdbcType=INTEGER},
#{nickname,jdbcType=VARCHAR}, #{avatar,jdbcType=VARCHAR}, #{phone,jdbcType=CHAR},
#{addTime,jdbcType=INTEGER}, #{addIp,jdbcType=VARCHAR}, #{lastTime,jdbcType=INTEGER},
#{lastIp,jdbcType=VARCHAR}, #{nowMoney,jdbcType=DECIMAL}, #{brokeragePrice,jdbcType=DECIMAL},
#{integral,jdbcType=DECIMAL}, #{signNum,jdbcType=INTEGER}, #{status,jdbcType=BIT},
#{level,jdbcType=TINYINT}, #{spreadUid,jdbcType=INTEGER}, #{spreadTime,jdbcType=INTEGER},
#{userType,jdbcType=VARCHAR}, #{isPromoter,jdbcType=BIT}, #{payCount,jdbcType=INTEGER},
#{spreadCount,jdbcType=INTEGER}, #{cleanTime,jdbcType=INTEGER}, #{addres,jdbcType=VARCHAR},
#{adminid,jdbcType=INTEGER}, #{loginType,jdbcType=VARCHAR}, #{userText,jdbcType=VARCHAR},
#{secretKey,jdbcType=VARCHAR})
</insert>
<select id="queryByMemberId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
SELECT
<include refid="baseColumnList"/>
FROM eb_user where uid=#{userId,jdbcType=INTEGER}
</select>
</mapper>