MyBatis02

1.封装MyBatis工具类

泛型:避免类型的转换,性能高
ThreadLocal:线程副本、线程变量 当前线程作为key,每个线程都有自己的对象
内存泄漏(为什么、怎么解决)
参考:MybatisUtil

public class MybatisUtil {
    private static SqlSessionFactory factory;
    private static ThreadLocal<SqlSession> local;//线程副本或线程变量 等价于 Map<Thread,Object>,key当前线程 避免线程安全
    static {
        try {
            //1.加载配置文件
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            //2.获取会话工厂对象 2种设计模式:1.工厂模式 2.建造者模式
            factory= new SqlSessionFactoryBuilder().build(is);
            local=new ThreadLocal<>();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * @description:获取会话,每个线程都有自己的会话对象
     * @return: 会话对象
     */
    public static SqlSession getSqlSession(){
        SqlSession sqlSession=local.get();
        if(sqlSession==null){
            sqlSession=factory.openSession();
            local.set(sqlSession);
        }
        return sqlSession;
    }
    /**
     * @description:  返回持久层接口的实现类
     * @param clz 持久层接口对应的Class对象
     * @return:
     */
    public static <T> T getMapper(Class<T> clz){
        return local.get().getMapper(clz);
    }
    /**
     * @description: 回收对象
     * @return:
     */
    public static void close(){
        local.get().close();
        local.remove();//删除,防止内存泄漏
    }
}

2.数据库连接池

池化技术:有效控制连接,让资源得到充分的使用
常用池化:1.数据库连接池 2.线程池 3.Redis连接池 等等
目的:1.有效控制最大连接,防止服务器宕机 2.充分使用每个连接对象
数据库连接池:有效控制数据库的连接对象,可以让连接更充分的使用
目前市场上数据库连接池:Druid(阿里巴巴)
使用步骤:
1.依赖jar

 <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>
    </dependencies>

编写数据库连接类

继承:PooledDataSourceFactory
		public class MyDruidDataSourceFactory extends PooledDataSourceFactory {
			//替换数据库连接池为Druid的连接池
			public MyDruidDataSourceFactory(){
				this.dataSource=new DruidDataSource();
			}
		}

3.实现配置

需要替换成自定义连接池
		<dataSource type="com.feri.mybatis.config.MyDruidDataSourceFactory">
                <!--使用$ + 占位符-->
                <property name="driverClass" value="${jdbc.driver}"/>
                <property name="jdbcUrl" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
        </dataSource>

3.ResultType和ResultMap

resultType:用在查询标签上,实现查询语句的的结果行的数据类型
要求:类的属性名必须和数据库表的字段名一模一样
适用于简单的映射
resultMap:用来定义数据库的字段和类的标的属性的对应关系,先定义,再使用
好处:
1.解决类的属性名和查询字段不一致的情况
2.实现多表关系映射查询

4.多表关系

关系型数据库:Mysql、Postgresql、Oracle
哪些关系?
一对一:用户表--用户详情表
一对多:老师表--学生表
多对一:学生表--老师表
多对多:商品表--订单表 中间表:订单详细表 2张表如果相互存在一对多,那么就是多对多。必须有中间表
E-R图:实体关系映射图
充分描述或展示表与表之间的关系
Mybatis实现多表关系,就很简单。
只有2种情况:
1.对象
A和B
A-1-1-B 一对一
A-N-1-B 多对一
A中就有B的对象
借助中的
2.集合
A和B
A-1-N-B 一对多
多对多在真实情况下,就是2个一对多
A中就有B的集合
借助中的
实现一对一
association+javaType

	1.编写实体类
	
	2.编写持久层接口
	
	3.编写持久层映射文件
	
	4.运行测试

实现一对多
一对多:用户表----手机表
collection+ofType

	1.编写实体类
	
	2.编写持久层接口
	
	3.编写持久层映射文件
	
	4.运行测试
<mapper namespace="com.qfedu.mapper.UserMapper">
    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        insert into t_user (phone,username,password)values(#{phone},#{username},#{password})
    </insert>
    <resultMap id="userMap" type="com.qfedu.pojo.User">
        <id property="id" column="id"/>
        <result property="phone" column="phone"></result>
        <result property="username" column="username"></result>
        <result property="password" column="password"></result>
        <association property="detail" javaType="com.qfedu.pojo.UserDetail">
            <id property="id" column="udid"/>
            <result property="name" column="uname"/>
            <result property="sex" column="sex"/>
            <result property="address" column="address"/>
            <result property="uid" column="uid"/>
        </association>
    </resultMap>
    <select id="selectById" resultMap="userMap">
        select u.*,ud.id udid,ud.uname,ud.sex,ud.address from t_user u inner join t_userdetail ud on u.id=ud.uid where u.id=#{id}
    </select>
    <resultMap id="userCar" type="com.qfedu.pojo.User">
        <id property="id" column="id"/>
        <result property="phone" column="phone"></result>
        <result property="username" column="username"></result>
        <result property="password" column="password"></result>
        <collection property="cars" ofType="com.qfedu.pojo.Car">
            <id property="id" column="cid"/>
            <result property="brand" column="brand"></result>
            <result property="title" column="title"></result>
            <result property="uid" column="uid"></result>
        </collection>
    </resultMap>
    <select id="selectUserCar" resultMap="userCar">
            select u.*,c.id cid,c.uid,c.brand,c.title from t_user u inner join t_car c on u.id=c.uid
    </select>

</mapper>

5动态sql

就是一些标签,需要死记硬背
动态SQL:可以动态的拼接SQL语句,实现sql复用,简化操作
语法规则:记住以下标签:
sql>:封装可以复用的sql语句,通过 引用
where>:实现where关键字,如果内部为空,则Where关键字不出现,如果内部有内容,则添加Where
trim>:去除
set>:修改 可以去除多余的连接符
if>:分支语句判断 test属性
foreach>:循环,重复操作,可以设置间隔符

Mybatis如何实现批处理?批量新增、批量修改、批量删除
<sql id="s1">
        select * from t_car
    </sql>
    <select id="selectCar" resultType="com.qfedu.pojo.Car">
        <include refid="s1"></include>
        <where>
            <if test="brand !=null">
                and brand = #{brand}
            </if>
            <if test="title != null">
                and title = #{title}
            </if>
        </where>
    </select>
</insert>

    <insert id="batchAdd" parameterType="list">
    insert into t_car (uid,brand,title) values
    <foreach collection="list" item="c" separator=",">
        (#{c.uid},#{c.brand},#{c.title})
    </foreach>

</insert>
    <delete id="deleteCarById" >
        delete from t_car where id in 
        <foreach collection="list" open="(" separator="," close=")" item="id" >
            #{id}
        </foreach>
    </delete>

6Lombok

Lombok:是一个开源的小框架,基于注解实现类的getter、setter、构造、toString等方法
目的简化类中的内容,避免重复搬砖
这个框架还有配套的一个Idea插件
使用步骤:
1.安装插件
lombok---install--重启Idea
2.项目中依赖jar

	    <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
3.实体类使用注解,简化代码
@Data //自动实现属性的getter和setter,并重写toString方法

@NoArgsConstructor //无参构造函数

public class User {
    private Integer id ;
    /** 手机号 */
    private String phone ;
    /** 密码 */
    private String pass ;
    /** 时间 */
    private Date ctime ;
    //对应的详情信息
    private UserDetail detail;

    public User(String phone, String pass) {
        this.phone = phone;
        this.pass = pass;
    }
}
posted @ 2021-09-26 21:54  码丁XIA  阅读(49)  评论(0)    收藏  举报