c#有ASP.Net,.NET以及EF Core这几个重要的运行时和框架.分别用于web,应用以及数据库的ORM.
目前跨平台的有Avalonia UI,.Net MAUI以及Uno Platform,至于WPF等本身不是跨平台的,但可以依靠其他库实现跨平台.这里面Avalonia应该是认为bug比较少的.
当然目前最火的跨平台解决方案应该是Flutter,其次是React Native.
至于EF Core,看看代码就知道有多么简洁优雅了.
using var db = new BloggingContext();
// Inserting data into the database
db.Add(new Blog { Url = "http://blogs.msdn.com/adonet" });
db.SaveChanges();
// Querying
var blog = db.Blogs
.OrderBy(b => b.BlogId)
.First();
// Updating
blog.Url = "https://devblogs.microsoft.com/dotnet";
blog.Posts.Add(
new Post
{
Title = "Hello World",
Content = "I wrote an app using EF Core!"
});
db.SaveChanges();
// Deleting
db.Remove(blog);
db.SaveChanges();
而Java的ORM有Mybatis,Mybatis-plus,Hibernate,Spring Data JPA以及更原始的Jdbctemplate和query dsl.
具体来说,当使用Java和MyBatis编写示例代码时,需要配置MyBatis的环境和数据库连接,并编写映射器接口和SQL映射文件
<?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>
<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://localhost:3306/mydatabase"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/example/MyMapper.xml"/>
</mappers>
</configuration>
package com.example;
public class User {
private int id;
private String name;
private int age;
// getters and setters
}
import java.util.List;
public interface UserMapper {
void insertUser(User user);
void updateUser(User user);
void deleteUser(int id);
User getUserById(int id);
List<User> getAllUsers();
}
<?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.example.UserMapper">
<insert id="insertUser" parameterType="com.example.User">
INSERT INTO users (name, age) VALUES (#{name}, #{age})
</insert>
<update id="updateUser" parameterType="com.example.User">
UPDATE users SET name = #{name}, age = #{age} WHERE id = #{id}
</update>
<delete id="deleteUser" parameterType="int">
DELETE FROM users WHERE id = #{id}
</delete>
<select id="getUserById" parameterType="int" resultType="com.example.User">
SELECT * FROM users WHERE id = #{id}
</select>
<select id="getAllUsers" resultType="com.example.User">
SELECT * FROM users
</select>
</mapper>
package com.example;
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.IOException;
import java.io.InputStream;
import java.util.List;
public class Main {
public static void main(String[] args) {
try {
// 加载 MyBatis 配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 创建 SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 获取 UserMapper 接口的实例
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 插入用户
User newUser = new User();
newUser.setName("John");
newUser.setAge(25);
userMapper.insertUser(newUser);
System.out.println("Inserted user: " + newUser);
// 更新用户
User existingUser = userMapper.getUserById(newUser.getId());
existingUser.setName("John Doe");
userMapper.updateUser(existingUser);
System.out.println("Updated user: " + existingUser);
// 获取所有用户
List<User> allUsers = userMapper.getAllUsers();
System.out.println("All users:");
for (User user : allUsers) {
System.out.println(user);
}
// 删除用户
userMapper.deleteUser(existingUser.getId());
System.out.println("Deleted user with ID: " + existingUser.getId());
// 提交事务
sqlSession.commit();
// 关闭 SqlSession
sqlSession.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用MyBatis-Plus编写示例代码时,可以省去编写SQL映射文件,因为MyBatis-Plus提供了便捷的CRUD操作方法和自动生成SQL语句的功能。
package com.example;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@TableName("users")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
// getters and setters
}
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface UserMapper extends BaseMapper<User> {
}
package com.example;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
// 启动 Spring Boot 应用
ConfigurableApplicationContext context = SpringApplication.run(Main.class, args);
// 获取 UserMapper Bean
UserMapper userMapper = context.getBean(UserMapper.class);
// 插入用户
User newUser = new User();
newUser.setName("John");
newUser.setAge(25);
userMapper.insert(newUser);
System.out.println("Inserted user: " + newUser);
// 更新用户
User existingUser = userMapper.selectById(newUser.getId());
existingUser.setName("John Doe");
userMapper.updateById(existingUser);
System.out.println("Updated user: " + existingUser);
// 查询所有用户
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByAsc("id");
IPage<User> userPage = userMapper.selectPage(new Page<>(1, 10), queryWrapper);
System.out.println("All users:");
for (User user : userPage.getRecords()) {
System.out.println(user);
}
// 删除用户
userMapper.deleteById(existingUser.getId());
System.out.println("Deleted user with ID: " + existingUser.getId());
// 关闭应用上下文
context.close();
}
}
使用了MyBatis-Plus的注解 @TableName
来指定实体类与数据库表的映射关系,使用了 @TableId
注解来定义主键字段。UserMapper
接口继承了 BaseMapper<User>
,这样就可以直接使用MyBatis-Plus提供的CRUD操作方法。
使用Hibernate编写示例代码时,需要配置Hibernate的环境和数据库连接,并编写实体类和Hibernate映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mydatabase</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.show_sql">true</property>
<mapping resource="com/example/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
package com.example;
import javax.persistence.*;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "age")
private Integer age;
// getters and setters
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.example.User" table="users">
<id name="id" column="id">
<generator class="identity"/>
</id>
<property name="name" column="name"/>
<property name="age" column="age"/>
</class>
</hibernate-mapping>
package com.example;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import java.util.List;
public class Main {
public static void main(String[] args) {
// 加载 Hibernate 配置
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 创建 Session
Session session = sessionFactory.openSession();
// 开启事务
Transaction transaction = session.beginTransaction();
// 插入用户
User newUser = new User();
newUser.setName("John");
newUser.setAge(25);
session.save(newUser);
System.out.println("Inserted user: " + newUser);
// 更新用户
User existingUser = session.get(User.class, newUser.getId());
existingUser.setName("John Doe");
session.update(existingUser);
System.out.println("Updated user: " + existingUser);
// 查询所有用户
List<User> allUsers = session.createQuery("FROM User", User.class).getResultList();
System.out.println("All users:");
for (User user : allUsers) {
System.out.println(user);
}
// 删除用户
session.delete(existingUser);
System.out.println("Deleted user with ID: " + existingUser.getId());
// 提交事务
transaction.commit();
// 关闭 Session
session.close();
// 关闭 SessionFactory
sessionFactory.close();
}
}
使用Hibernate的注解 @Entity
、@Table
、@Id
和 @Column
来定义实体类与数据库表的映射关系和字段信息。Hibernate映射文件 User.hbm.xml
也定义了实体类与数据库表的映射关系。
当使用Spring Data JPA编写示例代码时,可以利用Spring Data JPA提供的接口和方法来进行数据库操作,而无需编写大量的重复代码。
package com.example;
import javax.persistence.*;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "age")
private Integer age;
// getters and setters
}
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import java.util.List;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
// 启动 Spring Boot 应用
ConfigurableApplicationContext context = SpringApplication.run(Main.class, args);
// 获取 UserRepository Bean
UserRepository userRepository = context.getBean(UserRepository.class);
// 插入用户
User newUser = new User();
newUser.setName("John");
newUser.setAge(25);
userRepository.save(newUser);
System.out.println("Inserted user: " + newUser);
// 更新用户
User existingUser = userRepository.findById(newUser.getId()).orElse(null);
existingUser.setName("John Doe");
userRepository.save(existingUser);
System.out.println("Updated user: " + existingUser);
// 查询所有用户
List<User> allUsers = userRepository.findAll();
System.out.println("All users:");
for (User user : allUsers) {
System.out.println(user);
}
// 删除用户
userRepository.deleteById(existingUser.getId());
System.out.println("Deleted user with ID: " + existingUser.getId());
// 关闭应用上下文
context.close();
}
}
此外使用JPA与querydsl结合的也很多.QueryDSL仅仅是一个通用的查询框架,专注于通过 JavaAPI 构建类型安全的 Sql 查询
package com.example;
import javax.persistence.*;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "age")
private Integer age;
// getters and setters
}
package com.example;
import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.core.types.dsl.StringPath;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long>, QuerydslPredicateExecutor<User> {
// 定义自定义查询方法
default User findByName(String name) {
JPAQueryFactory queryFactory = new JPAQueryFactory(getEntityManager());
QUser user = QUser.user;
return queryFactory.selectFrom(user)
.where(user.name.eq(name))
.fetchOne();
}
// 使用Querydsl的字符串表达式进行模糊查询
default Iterable<User> findByNameLike(String name) {
JPAQueryFactory queryFactory = new JPAQueryFactory(getEntityManager());
QUser user = QUser.user;
StringExpression nameExpression = user.name;
return queryFactory.selectFrom(user)
.where(nameExpression.likeIgnoreCase("%" + name + "%"))
.fetch();
}
}
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import java.util.List;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
// 启动 Spring Boot 应用
ConfigurableApplicationContext context = SpringApplication.run(Main.class, args);
// 获取 UserRepository Bean
UserRepository userRepository = context.getBean(UserRepository.class);
// 插入用户
User newUser = new User();
newUser.setName("John");
newUser.setAge(25);
userRepository.save(newUser);
System.out.println("Inserted user: " + newUser);
// 更新用户
User existingUser = userRepository.findByName("John");
existingUser.setName("John Doe");
userRepository.save(existingUser);
System.out.println("Updated user: " + existingUser);
// 查询所有用户
List<User> allUsers = userRepository.findAll();
System.out.println("All users:");
for (User user : allUsers) {
System.out.println(user);
}
// 根据名称模糊查询用户
List<User> usersWithNameLike = userRepository.findByNameLike("John");
System.out.println("Users with name like 'John':");
for (User user : usersWithNameLike) {
System.out.println(user);
}
// 删除用户
userRepository.delete(existingUser);
System.out.println("Deleted user with ID: " + existingUser.getId());
// 关闭应用上下文
context.close();
}
}