Mybatis如何⾃动⽣成数据库表结构总结
⼀般情况下,⽤Mybatis的时候是先设计表结构再进⾏实体类以及映射⽂件编写的,特别是⽤代码⽣成器的时候。
但有时候不想⽤代码⽣成器,也不想定义表结构,那怎么办?
这个时候就会想到Hibernate,然后想到它的hibernate.hbm2ddl.auto配置项。
所以⼿⼯创表的问题可以很⽅便的迅速⽤Hibernate来解决。那有⼈问啦:就是不想⽤Hibernate才换的Mybatis,你这⼜兜回去了吗?
其实不是的,我们需要的就是单单⼀个hbm2ddl功能。
其实应该这么想:有⼀款⼯具能够⾃动根据注解的实体类来⽣成各种数据库相应的表结构,只需要加⼏个jar包 (经测试后只要7个)并且少量配置(3个配置项)。
这款⼯具就是Hibernate。为什么不能是它呢
原理说来也是超级的简单:加⼊hibernate的包,注解实体类,程序开始时初始化⼀下hibernate的SessionFactory并清除它。
⽰例:
需要的Hibernate相关的JAR包 (本例基于Hibernate5.0.7,仅需要7个):
hibernate-core-5.0.7.Final.jar
hibernate-commons-annotations-5.0.1.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
geronimo-jta_1.1_spec-1.1.1.jar
jboss-logging-3.3.0.Final.jar
dom4j-1.6.1.jar
javassist-3.18.1-GA.jar
l⽂件:(去掉多余的,精简后的内容)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!--不采⽤InnoDB⽅式加快速度 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 注意update⽅式时对于属性的删减并不会删除数据库字段 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 注意注解的话,只能⽤class⼀个⼀个引⽤。除⾮与Spring整合才能扫描⽂件夹路径 -->
<mapping class="batis.bean.User" />
</session-factory>
</hibernate-configuration>
注解的实体类:
@Entity
@Table(name = "t_user")
@Data
@NoArgsConstructor
@ToString
public class User implements Serializable {
private static final long serialVersionUID = -4013951528313410972L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(length = 30)
private String name;
@Column
private Float height;
@Column
private Double salary;
@Column
private Integer vip;
@Column
@Temporal(TemporalType.DATE)
private Date birthday;
@Column
@Temporal(TemporalType.TIMESTAMP)
private Date lastlogin;
@Column
@Enumerated(EnumType.STRING)
// mybatis 默认会将枚举转化为字符串类型存储,此时数据库为varchar型
private State state;
@Column
@Enumerated(EnumType.ORDINAL)
// 可以为mybatis设置枚举类型存储为其索引值存储,此时数据库为int型
private Level level;
@Column(length = 10)
@Enumerated(EnumType.ORDINAL)
// mybatis ⾃定义类型转换器将枚举转化为相应数字类型存储,此时数据库为int型
private Sex sex;
@Column
@Type(type = "string")
// mybatis ⾃定义类型转换器将列表转化为相应字符串类型存储,此时数据库为varchar型
private List<String> tels;
public User(int id) {
super();
this.id = id;
}
public User(int id, String name) {
super();
this.id = id;
this.name = name;
}
public User(String name) {
super();
this.name = name;
}
}
注意:以上实体类⽤了Lombok插件来减少代码量(只要是为了不写setter/getter、toString等。Lombok插件的使⽤请参考其它地⽅。)
@Data
@NoArgsConstructor
@ToString
三个注解属于Lombok插件注解,分别指⽰⽣成SETTER/GETTER、⽣成⽆参构造器、⽣成ToString
其它注解都属于Hibernate(JPA规范)的注解,⽣成DDL就靠它们了。
注解-说明:
@Entity
@Table(name = "t_user")
这⾥指实体类对应了t_user表
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
这⾥指表主健⾃动增长
@Column
这⾥指表字段名称与属性同名,它可以另外指定长度,名称。
@Temporal(TemporalType.DATE)
这⾥指表字段采⽤Date类型存储
@Enumerated(EnumType.STRING)
这⾥指表字段采⽤varchar类型来存储枚举属性
这个简短⽰例仅列出简单的类型的注解,并不涉及表关联之间的注解,幸好的是,注解并不多,更多注解可以参考Hibernate(JPA)注解相关内容。
⾄此,只需要在使⽤SqlSessionFactory(Mybatis)之前就构造SessionFactory(Hibernate)然后销毁它就可以了。⾄于如何初始化Hibernate的SessionFactory,应该都知道。如下:
Mybatis与Spring整合时:简单地配置⼀个hibernate的SessionFactory相关的BEAN了事。这⾥不谈。
Mybatis不与Spring整合时:
Mybatis的⼯具类中添加新⽅法,⽤于⾃动构造DDL:
package batis.util;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import stant.Constants;
public class SessionFactoryUtil {
public static SqlSessionFactory creat(String configFile) {
SqlSessionFactory factory = null;
InputStream inputStream;
try {
inputStream = ResourceAsStream(configFile);
factory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
/
/ TODO Auto-generated catch block
e.printStackTrace();
}
return factory;
}
//这⾥是新⽅法,通过判断标记决定是否要⽤于⾃动⽣成DDL
public static SqlSessionFactory creat(String configFile, boolean hibernateAutoDdl) {
if (hibernateAutoDdl) {
String hibernateConfigFile = Constants.Hibernate_LOCATION;
// 使⽤hibernate⾃动创建DDL
HibernateUtil.buildSessionFactory(hibernateConfigFile);
}
return creat(configFile);
}
}
其中⽤到的Hibernate⼯具类为:jpa mybatis
package batis.util;
import java.util.Properties;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import stant.Constants;
public class HibernateUtil {
public static void buildSessionFactory(String hibernateConfigFile) {
String jdbcPropertiesLocation = Constants.JDBC_LOCATION;
Properties jdbcProperties = PropertiesUtil.loadFromClassPath(jdbcPropertiesLocation);
Properties hibernateJdbcProperties = new Properties();
hibernateJdbcProperties.setProperty("tion.driver_class", Property("driver")); hibernateJdbcProperties.setProperty("tion.url", Property("url"));
hibernateJdbcProperties.setProperty("tion.username", Property("user"));
hibernateJdbcProperties.setProperty("tion.password", Property("password")); final Configuration cfg = new Configuration();
cfg.addProperties(hibernateJdbcProperties);
SessionFactory sessionFactory = cfg.buildSessionFactory();
// 启动后销毁
sessionFactory.close();
sessionFactory = null;
}
}
PropertiesUtil⼯具类:
package batis.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropertiesUtil {
public static Properties loadFromClassPath(String fileName) {
Properties props = new Properties();
while(fileName!=null && fileName.length()>0 && (fileName.startsWith("/") || fileName.startsWith("\\"))) {
fileName = fileName.substring(1);
}
InputStream is = ResourceAsStream("/"+fileName);
try {
props.load(is);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return props;
}
}
常量配置类Constant:
package stant;
public class Constants {
public static String JDBC_LOCATION = "jdbc.properties";
public static String Hibernate_LOCATION = "l";
}
Mybatis配置⽂件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-////DTD Config 3.0//EN"
"/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 别名 -->
<typeAliases>
<!-- 指定包下所有别名为类名的简名 -->
<package name="batis.bean" />
</typeAliases>
<!-- 类型处理器 -->
<typeHandlers>
<!-- 改变默认处理枚举(枚举转换为int) -->
<typeHandler
handler="org.pe.EnumOrdinalTypeHandler"
javaType="ums.Level" />
<!-- ⾃定义处理枚举(枚举转换为枚举键值对的数字值) -->
<typeHandler
handler="pehandle.SexEnumTypeHandler"
javaType="ums.Sex" />
<!-- ⾃定义处理列表(列表转换为字符串连接) -->
<!-- 注意,由于是⾮内置的转换类型,所以仅对select有效,insert/update/delete需要另⾏指定 --> <!-- 另⾏指定⽰例:${tels,typeHandler=pehandle.ListTypeHandler} --> <typeHandler
handler="pehandle.ListTypeHandler"
javaType="java.util.List" />
</typeHandlers>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<!-- ⾃定义MyPoolDataSourceFactory简化配置 -->
<dataSource type="batis.pool.MyPoolDataSourceFactory" />
</environment>
</environments>
<mappers>
<package name="com/sunwii/mybatis/mapper" />
</mappers>
</configuration>
连接池装饰类(⽤于简化Mybatis配置并统⼀jdbc配置⽂件路径常量):package batis.pool;
import java.util.Properties;
import org.apache.ibatis.datasource.pooled.PooledDataSource;
import org.apache.ibatis.datasource.pooled.PooledDataSourceFactory;
import stant.Constants;
import batis.util.PropertiesUtil;
public class MyPoolDataSourceFactory extends PooledDataSourceFactory {
public MyPoolDataSourceFactory() {
PooledDataSource dataSource = new PooledDataSource();
// 更多属性可以通过<property>来设置。
String jdbcPropertiesFile = Constants.JDBC_LOCATION;
Properties prop = PropertiesUtil.loadFromClassPath(jdbcPropertiesFile);
dataSource.Property("driver"));
dataSource.Property("url"));
dataSource.Property("user"));
dataSource.Property("password"));
this.dataSource = dataSource;
}
}
⽤到的⼏个枚举类:
package ums;
public enum Level {
LEVEL_0,
LEVEL_1,
LEVEL_2,
LEVEL_3,
LEVEL_4,
LEVEL_5
}
package ums;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论