【Java Web开发指南】ORM一些基础问题整理



最强知识图谱!

学习Java或者全栈开发强烈推荐!我说的!

在这里插入图片描述

1.什么是ORM?请说明两种常用的ORM框架的区别是什么。

ORM即对象关系映射框架。使用ORM框架后,应用程序不再直接访问底层数据库,而是以面向对象的方式来操作持久化对象(PO),而ORM框架则会通过映射关系将这些面向对象的操作转换成底层的SQL操作。
常见的ORM框架有Hibernate和MyBatis,区别如下:
Hibernate是一个全表映射的框架。适合场景不太复杂且对性能要求不高的项目中使用。
MyBatis是一个半自动映射的框架。对于一些复杂和需要优化性能的项目来说,显然使用MyBatis更合适。

2.在进行实体关系映射时,如果遇到实体类中的属性名与表中的字段名不一致的情况,该如何解决。请给出至少两种解决方案。

public class User
{
	private Long id;
	private String userName;
	private String passWord;
	/**
	 * ...
	 * get,set方法不再列出
	 * ...
	 * */
}

1.既然是因为名字不一致而导致Mybatis不能完成自动映射,那么就可以将两者的名字想办法保持一致,为查询出的数据库字段起个别名就可以,实例如下:

<select id="selectUserById" resultType="User">
        select 
        id,
        user_name as userName,<!--不用在意大小写,Mybatis会先转换成大写再进行匹配  -->
        user_password as password,
        from user
        where id = #{id}
</select>

2.另一种解决名字不一致的方式是事先指定映射关系,这样Mybatis也能自动完成映射。Mybatis提供了resultMap可以指定映射关系,示例如下:

<resultMap type="User" id="UserResultMap">
		<id column="id" property="id"/>
		<result column="user_name" property="userName"/>
		<result column="user_password" property="userPassword"/>
</resultMap>
	
	
<select id="selectUserById" resultMap="UserResultMap">
        select 
        id,
        user_name,
        user_password,
        from user
        where id = #{id}
</select>

3.从线程安全及生命周期的角度说明SqlSessionFactory 与SqlSession的区别,并且给出至少两种能够获取SqlSessionFactory对象的方式。

SqlSessionFactory一旦被创建,SqlSessionFactory应该在你的项目执行期间都存在。没有理由来处理或重新创建它,最简单的就是使用单例模式。SqlSessionFactory对象是线程安全的。
至于SqlSession,每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能被共享,也是线程不安全的。因此最佳的范围是请求或方法范围。SqlSession是一个单线程对象。

SqlSessionFactory对象的实例可以通过SqlSessionFactoryBuilder对象来构建,而SqlSessionFactoryBuilder则可以通过XML配置文件或一个预先定义好的Configuration实例构建出SqlSessionFactory的实例。

//1.根据给定的Configuration对象创建一个SqlSessionFactory的实例
SqlSessionFactory sqlSessionFactory = 
new SqlSessionFactoryBuilder().build(config);
//2.根据给定的inputStream字节流创建一个SqlSessionFactory的实例
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(inputStream);

InputStream inputStream= Resources.getResourceAsStream("mybatis-config.xml");

4.Mybatis 中一级缓存、二级缓存存放的位置分别是哪里?如果要在程序中实现二级缓存,需要进行的配置都有哪些?

在这里插入图片描述
清空之前,一条语句,一次查询,两个相同结果。
清空之后,两条语句,两次查询,两个相同结果。
二级缓存:
在mybatis-config中:
在这里插入图片描述
在mapper中:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

CREATE TABLE t_account(
	id INT(11) PRIMARY KEY,
	money FLOAT(10),
	userid INT(11) 
	);
alter TABLE t_account ADD CONSTRAINT 
FK_ID FOREIGN KEY(id) REFERENCES t_user(id);

5 设计

PO

Account.java

package com.test.po;

public class Account {
    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public float getMoney() {
        return money;
    }

    public void setMoney(float money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", money=" + money +
                ", userid=" + userid +
                '}';
    }

    public int getUserid() {
        return userid;
    }

    public void setUserid(int userid) {
        this.userid = userid;
    }

    private float money;
    private int userid;
}

Role.java

package com.test.po;

import java.util.List;

public class Role {
    private Integer id;
    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDesc() {
        return desc;
    }

    @Override
    public String toString() {
        return "Role{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                ", userList=" + userList +
                '}';
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    private String desc;

    public List<User> getUserList() {
        return userList;
    }

    public void setUserList(List<User> userList) {
        this.userList = userList;
    }

    private List<User> userList;

}

User.java

package com.test.po;

import java.util.List;

public class User {
    private Integer id;
    private String username;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }


    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                ", roleList=" + roleList +
                '}';
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    private String sex;
    private String address;

//    public List<Account> getAccountList() {
//        return accountList;
//    }
//
//    public void setAccountList(List<Account> accountList) {
//        this.accountList = accountList;
//    }
//
//    private List<Account> accountList;
    private List<Role> roleList;

}

utils

MyBatisUtils.java

package com.test.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 java.io.InputStream;
import java.io.Reader;

public class MyBatisUtils {
    private static SqlSessionFactory sqlSessionFactory=null;
    static {
        try{
            Reader reader= Resources.getResourceAsReader("mybatis-config.xml");
            sqlSessionFactory= new SqlSessionFactoryBuilder().build(reader);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public static SqlSession getSession(){
        return sqlSessionFactory.openSession();
    }
}

mapper

UserMapper.java

package com.test.mapper;

import com.test.po.User;

import java.util.List;

public interface UserMapper {
    public List<User> findUserByName(String name);
    public List<User> findUserByDynamicQuery(User user);
    public User findAccountWithUser(Integer id);
    public List<User> findRoleWithUser(Integer id);
}

UserMapper.xml

<?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.test.mapper.UserMapper">
    <!--根据客户编号获取客户信息 -->
    <select id="findUserByName" parameterType="String"
            resultType="user">
		select * from t_user where username like concat('%',#{value},'%')
	</select>
    <select id="findUserByDynamicQuery" parameterType="user" resultType="user">
    select * from t_user where 1=1
        <choose>
        <when test="username!=null and username!=''">
            and username=#{username}
        </when>
        <when test="sex!=null and sex!=''">
            and sex=#{sex}
        </when>
        <otherwise>
            and username=#{username} and sex=#{sex}
        </otherwise>
        </choose>
    </select>
    <select id="findAccountWithUser" parameterType="Integer" resultMap="resultMap1">
        select u.*,a.id as account_id,a.money
            from t_user u,t_account a
            where u.id=a.userid
            and u.id=#{id}
    </select>
    <resultMap id="resultMap1" type="user">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="sex" column="sex"/>
        <result property="address" column="address"/>
        <collection property="accountList" ofType="account">
            <id property="id" column="account_id"/>
            <result property="money" column="money"/>
        </collection>
    </resultMap>
    <select id="findRoleWithUser" parameterType="Integer" resultMap="resultMap2">
        select * from t_user where id=#{id}
    </select>
    <resultMap id="resultMap2" type="user">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="sex" column="sex"/>
        <result property="address" column="address"/>
        <collection property="roleList" column="id" ofType="role"
                    select="com.test.mapper.RoleMapper.findRoleById">
        </collection>
    </resultMap>
</mapper>

RoleMapper.xml

<?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.test.mapper.RoleMapper">
    <select id="findRoleById" parameterType="Integer" resultType="role">
        select * from t_role where id in(
            select role_id from user_role where user_id=#{id}
        )
    </select>
</mapper>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-4.3.xsd
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
    <!--读取db.properties -->
    <context:property-placeholder location="classpath:db.properties"/>
    <!-- 配置数据源 -->
	<bean id="dataSource" 
            class="org.apache.commons.dbcp2.BasicDataSource">
        <!--数据库驱动 -->
        <property name="driverClassName" value="${jdbc.driver}" />
        <!--连接数据库的url -->
        <property name="url" value="${jdbc.url}" />
        <!--连接数据库的用户名 -->
        <property name="username" value="${jdbc.username}" />
        <!--连接数据库的密码 -->
        <property name="password" value="${jdbc.password}" />
        <!--最大连接数 -->
        <property name="maxTotal" value="${jdbc.maxTotal}" />
        <!--最大空闲连接  -->
        <property name="maxIdle" value="${jdbc.maxIdle}" />
        <!--初始化连接数  -->
        <property name="initialSize" value="${jdbc.initialSize}" />
	</bean>

    <!--配置MyBatis工厂 -->
    <bean id="sqlSessionFactory" 
            class="org.mybatis.spring.SqlSessionFactoryBean">
         <!--注入数据源 -->
         <property name="dataSource" ref="dataSource" />
         <!--指定核心配置文件位置 -->
   		 <property name="configLocation" value="classpath:mybatis-config.xml"/>
   </bean>

	<!-- Mapper代理开发(基于MapperScannerConfigurer) -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
	     <property name="basePackage" value="com.test.mapper" />
	</bean>

</beans>

db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=lixiang666
jdbc.maxTotal=30
jdbc.maxIdle=10
jdbc.initialSize=5

log4j.properties

# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com.test=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

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="db.properties" />
	<!-- 定义别名 -->
	<typeAliases>
		<package name="com.test.po" />
	</typeAliases>

	<!--2.配置Mapper的位置 -->
	<mappers>
		<mapper resource="com/test/mapper/UserMapper.xml" />
		<mapper resource="com/test/mapper/RoleMapper.xml" />
	</mappers>
</configuration>

test.java

import com.test.mapper.UserMapper;
import com.test.po.Role;
import com.test.po.User;
import com.test.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

public class test {
    @Test
    public void findUserByLikeNameTest(){
        ApplicationContext act=new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper userMapper=act.getBean(UserMapper.class);
        List<User> userList=userMapper.findUserByName("zhang");
        for(User user:userList){
            System.out.println(user.toString());
        }
    }
    @Test
    public void findUserByDynamicQueryTest(){
        ApplicationContext act=new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper userMapper=act.getBean(UserMapper.class);
        User user=new User();
        user.setSex("female");
        List<User> userList=userMapper.findUserByDynamicQuery(user);
        for(User u:userList){
            System.out.println(u.toString());
        }
    }
    @Test
    public void findAccountWithUserTest(){
        ApplicationContext act=new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper userMapper=act.getBean(UserMapper.class);
        User user=userMapper.findAccountWithUser(1);
        System.out.println(user.toString());
    }
    @Test
    public void findRoleWithUserTest(){
        ApplicationContext act=new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper userMapper=act.getBean(UserMapper.class);
        List<User> userList=userMapper.findRoleWithUser(1);
        for(User u:userList) {
            System.out.println(u.toString());
        }
    }
}

李响Superb CSDN认证博客专家 机器学习 TensorFlow 图像处理
成为一名优秀的算法工程师⬆️ ,
目前还在读软件工程,
AI攻防、算法和深度学习方向,
微博同名❤️ :李响Superb,
(记得关注,有问题微博私信!)
我们一起努力呀!
相关推荐
©️2020 CSDN 皮肤主题: 猿与汪的秘密 设计师:白松林 返回首页
实付 9.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值